我正试图在javascript中做一个小小的翅膀。
我第一次看到a technique using Box2D,我正在使用closure-web version(由于内存泄漏修复)。
简而言之,我将曲线分解为多边形,因此看起来像:
我也尝试使用Chipmunk-js,我使用分段形状模拟我的地面:
在这两种情况下,当圆形滚动时,我在多边形或线段之间的公共点处遇到一些“崩溃”或“颠簸”。
我向Chipmunk询问过这个问题,作者说他为该段实现了一个radius属性来减少这种行为。我试过,它确实做了诀窍,但它并不完美。我仍然有一些颠簸(我必须设置为半径30px以获得正面效果)。
“凸起”附加在两个多边形之间的共享点上:
使用illandril向我建议边缘技术(他只测试多边形 - 多边形接触)以避免圆圈在边缘崩溃:
还尝试添加子弹选项,如Luc建议的那样,似乎没有任何改变。
此问题the demo 您可以尝试更改要检查的值:
(仅在最新的开发者Chrome上测试过)
保持耐心(或改变水平重力),你会明白我的意思
这里感兴趣的the repo。
答案 0 :(得分:2)
最好的解决方案是带有鬼顶点的边缘形状,但是如果你在使用的版本/端口中没有它,那么下一个最好的东西就像你的问题中的图表'edging',但是将多边形进一步扩展到地下斜率非常浅,如此线程:http://www.box2d.org/forum/viewtopic.php?f=8&t=7917
答案 1 :(得分:1)
我首先想到的问题可能来自两个相邻段之间斜率的变化,但是因为在多边形的平面上你仍然有凹凸,我认为问题是撞到多边形的角落。
我不知道你是否可以设置两组多边形,相互重叠?只需使用相同的插值计算并生成第二组多边形,就像下图所示:您已经构建了红色多边形集,并通过在红色多边形的中间设置绿色多边形的左顶点来添加绿色集,并且它的右顶点位于下一个红色多边形的中间。
![图] [1]
这应该适用于凹曲线......无论如何你应该飞过凸曲线。
如果这不起作用,请尝试设置大量多边形来构建斜率。使用圆的半径的十分之一作为多边形的宽度,甚至可以更小。这应该会减少你的斜坡不连续性。
在Box2D.js第5082行(至少在this repo中)你有PreSolve(接触,流形)功能,你可以覆盖它来检查歧管(碰撞多边形时雪球被冲击的方向) )是对的。
为此,您需要恢复流形矢量并将其与曲线的法线进行比较。它应该看起来像(可能不完全):
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
};
答案 2 :(得分:0)
我说这个问题已在Box2D 2.2.0中得到解决,请参阅its manual, section 4.5 "Edge Shapes"
事物是it's a feature of the 2.2.0 version,连着chainhape的东西,而box2dweb实际上是从2.2.1a移植的 - 不知道box2dweb-closure。
我通过修改Box2D.Collision.b2Collision.CollidePolygonAndCircle尝试的任何事都导致了不稳定的行为。至少有一部分时间(例如,球在随机方向上撞击,但只有在它缓慢滚动时)。