Javascript物理引擎与模拟无限曲线
我正在尝试用javascript做一个小翅膀 我第一次看到,我正在使用(因为内存泄漏修复)。Javascript物理引擎与模拟无限曲线,javascript,box2d,physics,curve,chipmunk,Javascript,Box2d,Physics,Curve,Chipmunk,我正在尝试用javascript做一个小翅膀 我第一次看到,我正在使用(因为内存泄漏修复)。 简而言之,我将曲线分解为多边形,使其看起来像: 我还尝试了花栗鼠js,我使用片段形状模拟我的地面,如下所示: 在这两种情况下,当一个圆滚动时,我都会在多边形或线段之间的公共点上遇到一些“碰撞”或“碰撞” 我问过花栗鼠,作者说他为片段实现了radius属性以减少这种行为。我试过了,它确实成功了,但并不完美。我仍然有一些颠簸(我必须将半径设置为30px才能获得积极的效果) “凹凸”附加在两个多边形之间的
简而言之,我将曲线分解为多边形,使其看起来像: 我还尝试了花栗鼠js,我使用片段形状模拟我的地面,如下所示: 在这两种情况下,当一个圆滚动时,我都会在多边形或线段之间的公共点上遇到一些“碰撞”或“碰撞” 我问过花栗鼠,作者说他为片段实现了radius属性以减少这种行为。我试过了,它确实成功了,但并不完美。我仍然有一些颠簸(我必须将半径设置为30px才能获得积极的效果) “凹凸”附加在两个多边形之间的共享点上: 按照我的建议,使用边缘处理技术(他只测试了多边形接触),以避免圆在边缘上碰撞: 还尝试按照Luc的建议添加项目符号选项,但似乎没有任何变化 这是问题的答案。
您可以尝试更改要检查的值:
- 子弹选项
- 边缘尺寸
- 迭代次数
- 物理学
耐心点(或者改变水平重力),你就会明白我的意思。
这是给感兴趣的人看的。我最初认为问题可能来自两个相邻线段之间的坡度变化,但由于在多边形的平面上仍然有凸起,我认为问题相当于碰到了多边形的角 我不知道你是否可以设置两组多边形,彼此重叠?只需使用相同的插值计算,并生成第二组多边形,就像下面的图表:你已经建立了红色的多边形集,并通过在红色多边形的中间设置绿色多边形的左顶点,以及在下一个红色多边形中间的右顶点添加绿色集。 !![附图][1] 这应该适用于凹曲线和。。。不管怎样,你都应该飞过凸面 如果这不起作用,请尝试设置大量多边形以构建坡度。使用圆半径的十分之一作为多边形的宽度,甚至可能更小。这样可以减少坡度的不连续性 --编辑 在Box2D.js第5082行(至少)中,您具有PreSolve(接触,歧管)功能,您可以覆盖该功能,以检查歧管(碰撞多边形时推动雪球的方向)是否正确 为此,需要恢复流形向量并将其与曲线的法线进行比较。它应该是这样的(也许不完全是这样):
我想说这个问题已经在Box2D 2.2.0中解决了,请参阅 问题是,除了chainshape之外,box2dweb实际上是从2.2.1a移植的——我不知道box2dweb的闭包
我通过修改Box2D.Collision.b2Collision.collizedPolygonandCircle尝试的任何操作都会导致不稳定的行为。至少有一部分时间(例如,球在随机方向上碰撞,但仅当它缓慢滚动时)。最好的解决方案是带有重影顶点的边形状,但如果在您使用的版本/端口中不可用,则下一个最好的解决方案类似于您问题中称为“边缘”的图表,但是用一个非常浅的坡度将多边形进一步延伸到地下,就像这条线:你需要的是一个立方样条线,它保证顶点和坡度的连续性。我实际上使用的是和立方法来弯曲我的地面。这不是问题所在,因为您可以尝试使用具有多个相邻多边形(或线段)的线性坡度,但当圆在边上滚动时,仍然会得到“凹凸”。
Smooth.js
将立方体分别应用于每个维度,并且不会精确处理坡度。看看getTangent
方法,它执行有限差分(next\u value-prev\u value)/stride
,而不是正确的数学处理。我不知道js
,但在FORTRAN
和C#
中,我使用了数值公式()第3.3节,三次样条。让我补充一点,三次样条不仅在值和斜率上建立了连续性,而且在曲率上也建立了连续性。我恐怕这超出了我的能力:/你能用一个方案解释一下吗?我正在使用Smooth.js来弯曲我分组的坡度,它看起来在视觉上和物理上都很有效。我猜问题是两个相邻的多边形共享一些点,请参见更新的问题。我正在设置一个演示,以便能够更加明确。感谢您的想法,但我无法实现它。它还在颠簸。我仍然认为你箱子的角落是问题所在。看-很明显,你会希望你的雪球以垂直于其表面的脉冲反弹。当遇到拐角时,情况并非如此。尝试将雪球设置为子弹体(请参见)。@SuperSkunk,你能看看碰撞时得到的流形,看看它们是否远离曲线曲面的法线吗?我已经更新了我的答案,使我的观点更具可读性。我正在慢慢地达到目的。仍然需要解决如何从预解算曲线的点(请参见TODO注释块)我现在无法处理它,但我明白你的意思,我将在周末尝试一下!你已经得到了一些积极的结果吗?有趣的技术在后,我会尝试,并寻找幽灵顶点。
Box2D.Dynamics.b2ContactListener.prototype.PreSolve = function (contact, oldManifold) {
// contact instanceof Box2D.Dynamics.Contacts.b2Contact == true
var localManifold, worldManifold, xA, xB, man_vect, curve_vect, normal_vect, angle;
localManifold = contact.GetManifold();
if(localManifold.m_pointCount == 0)
return; // or raise an exception
worldManifold = new Box2D.Collision.b2WorldManifold();
contact.GetWorldManifold( worldManifold );
// deduce the impulse direction from the manifold points
man_vect = worldManifold.m_normal.Copy();
// we need two points close to & surrounding the collision to compute the normal vector
// not sure this is the right order of magnitude
xA = worldManifold.m_points[0].x - 0.1;
xB = worldManifold.m_points[0].x + 0.1;
man_vect.Normalize();
// now we have the abscissas let's get the ordinate of these points on the curve
// the subtraction of these two points will give us a vector parallel to the curve
var SmoothConfig;
SmoothConfig = {
params: {
method: 'cubic',
clip: 'mirror',
cubicTension: 0,
deepValidation: false
},
options: {
averageLineLength: .5
}
}
// get the points, smooth and smooth config stuff here
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]));
// now turn it to have a normal vector, turned upwards
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();
// and finally compute the angle between the two vectors
angle = Box2D.Common.Math.b2Math.Dot(man_vect, normal_vect);
$('#angle').text("" + Math.round(Math.acos(angle)*36000/Math.PI)/100 + "°");
// here try to raise an exception if the angle is too big (maybe after a few ms)
// with different thresholds on the angle value to see if the bumps correspond
// to a manifold that's not normal enough to your curve
};