我最初认为问题可能来自于相邻两个线段之间的斜率变化,但由于在多边形的平坦表面上仍然有凸起,我认为问题更可能是撞到了多边形的角落。
我不知道是否可以设置两组重叠的多边形?只需使用相同的插值计算,并生成第二组多边形,就像下图所示:您已经构建了红色的多边形集,并通过将绿色多边形的左顶点设置在红色多边形的中心,并将其右顶点设置在下一个红色多边形的中心来添加绿色多边形集。
![diagram][1]
这应该适用于凹曲线...好吧,你应该已经飞过凸曲线了。
如果这行不通,请尝试设置大量多边形以构建斜坡。将圆的半径的十分之一用作多边形的宽度,甚至可以更小。这应该可以减少您的斜率不连续性。
--编辑
在Box2D.js的第5082行(至少在
this repo中),您可以重写PreSolve(contact, manifold)函数以检查雪球与多边形碰撞时的冲量方向是否正确。
为此,您需要恢复manifold向量并将其与曲线的法向量进行比较。它应该看起来像这样(可能不完全相同):
Box2D.Dynamics.b2ContactListener.prototype.PreSolve = function (contact, oldManifold) {
var localManifold, worldManifold, xA, xB, man_vect, curve_vect, normal_vect, angle;
localManifold = contact.GetManifold();
if(localManifold.m_pointCount == 0)
return;
worldManifold = new Box2D.Collision.b2WorldManifold();
contact.GetWorldManifold( worldManifold );
man_vect = worldManifold.m_normal.Copy();
xA = worldManifold.m_points[0].x - 0.1;
xB = worldManifold.m_points[0].x + 0.1;
man_vect.Normalize();
var SmoothConfig;
SmoothConfig = {
params: {
method: 'cubic',
clip: 'mirror',
cubicTension: 0,
deepValidation: false
},
options: {
averageLineLength: .5
}
}
smooth = Smooth(global_points,SmoothConfig);
curve_vect = new Box2D.Common.Math.b2Vec2(xB, smooth(xB)[1]);
curve_vect.Subtract(new Box2D.Common.Math.b2Vec2(xA, smooth(xA)[1]));
normal_vect = new Box2D.Common.Math.b2Vec2(-curve_vect.y, curve_vect.x);
if(normal_vect.y > 0)
normal_vect.NegativeSelf();
normal_vect.Normalize();
worldManifold.m_normal = normal_vect.Copy();
angle = Box2D.Common.Math.b2Math.Dot(man_vect, normal_vect);
$('#angle').text("" + Math.round(Math.acos(angle)*36000/Math.PI)/100 + "°");
};
Smooth.js
对每个维度分别应用三次函数,但不精确处理斜率。请查看getTangent
方法,它使用有限差分(next_value-prev_value)/stride
而非正确的数学处理方法。我不懂js
,但在FORTRAN
和C#
中,我使用了数值计算方法 (http://apps.nrbook.com/c/index.html) 第 3.3 节,即三次样条插值。 - John Alexiou