2017-05-09 38 views
1

我有以下由随机点生成的网格,并使用Delaunay三角网创建三角形。然后,我在每个顶点上应用每个三角形的弹簧力。但由于某种原因,平衡总是向左移动。弹簧物理平衡总是向左移动

这里是行为的视频: https://youtu.be/gb5aj05zkIc

为什么发生这种情况?

下面是物理代码:

for (let i=0; i < mesh.geometry.faces.length; i++) { 

    let face = mesh.geometry.faces[i]; 

    let a = mesh.geometry.vertices[face.a]; 
    let b = mesh.geometry.vertices[face.b]; 
    let c = mesh.geometry.vertices[face.c]; 

    let p1 = Vertcies[face.a]; 
    let p2 = Vertcies[face.b]; 
    let p3 = Vertcies[face.c]; 

    update_force_points(p1, p2, a, b); 
    update_force_points(p1, p3, a, c); 
    update_force_points(p2, p3, b, c); 
    } 

function update_force_points(p1, p2, p1p, p2p) { 

    // get all the verticies 
    var dx = (p1.x - p2.x); 
    var dy = (p1.y - p2.y); 

    var len = Math.sqrt(dx*dx + dy*dy); 
    let fx = (ks * (len - r) * (dx/len)) + ((kd * p2.vx - p1.vx)); 
    let fy = (ks * (len - r) * (dy/len)) + ((kd * p2.vy - p1.vy)); 

    if (! p1.fixed) { 
    p1.fx = (ks * (len - r) * (dx/len)) + ((kd * p2.vx - p1.vx)); 
    p1.fy = (ks * (len - r) * (dy/len)) + ((kd * p2.vy - p1.vy)); 
    } 
    if (! p2.fixed) { 
    p2.fx = -1 * p1.fx; 
    p2.fy = -1 * p1.fy; 
    } 

    p1.vx += p1.fx/mass; 
    p1.vy += p1.fy/mass; 

    p2.vx += p2.fx/mass; 
    p2.vy += p2.fy/mass; 

    p1.x += p1.vx; 
    p1.y += p1.vy; 
    p2.x += p2.vx; 
    p2.y += p2.vy; 

    p1p.x = p1.x; 
    p1p.y = p1.y; 
    p2p.x = p2.x; 
    p2p.y = p2.y; 

    p2p.z = 0.0; 
    p1p.z = 0.0; 
} 
+0

可以定义KS和KD? 它在哪里定义哪些点是固定的? 所有顶点的质量是固定的吗? 如果你随机化顶点位置,你会得到相同的结果吗? (如果不是所有的都漂向左边的底部?),那么这并不奇怪。由于你减去了一个固定的数量(r),所以这里有更多的力量。应该有不对称 – OtterFamily

回答

2

在你正在做的速度计算和分配,同时新位置的时刻,这样的平衡将根据订单变化,通过你循环我猜想左下角的点不是在顶点列表的开始,就是在最后。

尝试做所有p#.vx计算直线,然后做第二遍,你只是做p#.X + = P#.vx

这样你计算基础上的快照所有必要的速度其中点是前一帧,那么在所有点具有新速度之后,您更新它们的位置。

所以做:

for(var i = 0; i < #; i++){ 
    updateforces(bla,bla,bla) //don't assign position in here, just add forces to the velocity 
} 

for(var i =0; i < #; i++){ 
    updateposition(bla,bla,bla) 
} 
+0

你的评论给我一个想法,我尝试过,它的工作。对'update_force_points'的调用不会以相同的方式更新力量。我更新为p1,p2然后是p2,p3,最后是p3,p1,因此彼此作用的力是三角形的。 – ArmenB

+0

哦,我也意识到,你所做的只是解决更大的问题 - '''p1p.x = p1.x; p1p.y = p1.y; p2p.x = p2.x; p2p.y = p2.y; ''' 这行覆盖顶点数据,它不会修改它。这意味着最后一个调用的函数会设置顶点数据 - 因此包含该顶点数据点的所有以前的函数都会被最后一个调用的函数覆盖。即在你的原始代码中:'''update_force_points(p2,p3,b,c);'''覆盖以前在除'''a'''之外的顶点上所做的工作,所以现在至少你要覆盖特定的但它只是解决更大的问题 – OtterFamily

+0

只有在您的模型(p1,p2等)已修复时,您才应该执行顶点赋值(a =#,b =#等),并且需要修复您的模型分开的部队分配和职位分配。 所以你需要: '''calculateforces(); calculatemodelPositions(); assignVertexpositions();'''作为单独的步骤 – OtterFamily