gpt4 book ai didi

javascript - Verlet 3D 破球

转载 作者:行者123 更新时间:2023-11-29 23:39:26 26 4
gpt4 key购买 nike

我正在尝试使用 verlet integration用于制作软体球体。

我主要是创建一个网格并通过 Spring 连接每个顶点。我正在使用 three.js 来渲染球体。我相信一切正常,但我不确定如何获得预期的结果。如果连接太弱,我的球就会塌陷;如果太僵硬,我的球就会爆炸。似乎有些不对劲。问题发生在物体掉落并撞到地面的那一刻。我将发布我的代码的主要部分,但是我不确定我的方法是否有效以及是否可用于产生我想要的结果。

function verletStick3D(p1, p2, distance, rigid){


this.type = "stick";
this.p1 = p1;
this.p2 = p2;
this.distance = distance;
this.rigid = rigid;
this.update = function(){

var dx = this.p1.x - this.p2.x;
var dy = this.p1.y - this.p2.y;
var dz = this.p1.z - this.p2.z;
var distance = Math.sqrt(dx * dx + dy * dy + dz * dz);
var difference = this.distance - distance;
var percent = difference / distance / 2;
var offsetX = dx * percent * this.rigid;
var offsetY = dy * percent * this.rigid;
var offsetZ = dz * percent * this.rigid;
this.p1.x += offsetX;
this.p1.y += offsetY;
this.p1.z += offsetZ;
this.p2.x -= offsetX;
this.p2.y -= offsetY;
this.p2.z -= offsetZ;

}
}

function verletPoint3D(x, y,z, maxX, maxZ, bounce = 0.9, friction =

1.0, gravity = {x:0, y:-0.03, z:0}){
y = y + 10;
this.type = "point";
this.x=x;
this.y=y;
this.z=z;
this.xOld=x;
this.yOld=y;
this.zOld=z;
this.bounce = bounce;
this.friction = friction;
this.gravity = gravity;
this.update = function(){
var vx = (this.x - this.xOld) * this.friction;
var vy = (this.y - this.yOld) * this.friction;
var vz = (this.z - this.zOld) * this.friction;
this.xOld = this.x;
this.yOld = this.y;
this.zOld = this.z;
this.x += vx;
this.y += vy;
this.z += vz;
this.y += this.gravity.y;
this.x += this.gravity.x;
this.z += this.gravity.z;



}
this.setGravity = function(gravity){
this.gravity = gravity;
}
this.constrain = function(){
var vx = (this.x - this.xOld) ;
var vy = (this.y - this.yOld) ;

if(this.x > this.maxX){
this.x = width;
this.xOld = this.x + vx * this.bounce;
}
if(this.x < this.minX){
this.x ;
this.xOld = this.x + vx * this.bounce;
}
if(this.z > this.maxZ ){
this.z = height ;
this.zOld = this.z + vz * this.bounce;

}
if(this.z < this.minZ){
this.z = 0;
this.zOld = this.z + vz * this.bounce;
}
if(this.y < 0){
this.y = 0;
this.yOld = this.y + vy * this.bounce;
}

}
}

function verletFromMesh(vertices, faces, maxX, maxY){
var points = [];
for(var i = 0; i < vertices.length; i++){

var p = new verletPoint3D(vertices[i].x, vertices[i].y, vertices[i].z, maxX, maxY, 0.9, 0.9);
points.push(p);

}

var springs = []
/*
for(var i = 0; i < faces.length; i++){
var face = faces[i];
var p1 = face.a;
var p2 = face.b;
var p3 = face.c;
springs.push(new verletStick( p1,p2, distance3D(p1, p2), 1.0) )
springs.push(new verletStick( p2,p3, distance3D(p2, p3), 1.0) )
springs.push(new verletStick( p3,p1, distance3D(p3, p1), 1.0) )
}*/
for(var i = 0; i < points.length; i++){
var p1 = points[i];
for(var j= i+1; j < points.length; j++){
var p2 = points[j];
if(p1.x == p2.x && p1.y == p2.y && p1.z == p2.z)
continue;
var dist = distance3D(p1, p2)

springs.push(new verletStick3D( p1,p2, dist, 1.0) )


}


}


return new verletObj(points, springs);
}

最佳答案

嗯,很难确切地看出你错在哪里,但对我来说,你的 Spring 似乎无法扭转运动。这将导致爆炸/坍塌,具体取决于它们的强度。我强烈建议尝试明确限制它们对球体的影响,希望这能帮助您进一步调试此问题。

您的数学运算方式,尤其是在设置偏移量 dx * percent * this.rigid; 时,看起来这些动态力的行为是静态的,因此发挥作用太过分了。

Ps:你检查过这个post吗? ? 这是关于摩擦的,但我认为这里的答案很值得引用:

Just introduce a small, constant acceleration on moving objects that points in the direction opposite to the motion. And make sure it can't actually reverse the motion; if you detect that in an integration step, just set the velocity to zero.

希望这能让您以某种方式朝着正确的方向前进。

关于javascript - Verlet 3D 破球,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45601658/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com