2013-05-04 32 views
0

在Box2D项目中,我需要在用户双击的确切点上在两个PolygonShaped物体之间创建一个RevoluteJoint。在形状上找到触摸点

我有触摸点和两个形状中的每一个的顶点列表(显然设置为不会相互碰撞)。如果我理解正确,触摸点是根据世界位置,并且顶点描述的形状,可能存在于任何世界。但是我如何从一个“翻译”到另一个?

例如,用户双击(3.63,5.07)。 (0.37485206,-0.17777264),(-0.2880008,-0.033603553),(-0.1609711,-0.2395713),(-0.04113376,-0.31708732),(0.26274818,-0.38661742),(0.26274818,-0.38661742), (0.35696936,-0.29765773)]

为形状2的顶点:[(-0.015462875,0.24353802),(-0.13529873,0.31698608),(-0.36852637,0.4127499),(-0.4136281,0.17009032),(-0.2880008, -0.033603553)]

的revoluteJoint:

RevoluteJointDef jd = new RevoluteJointDef(); 
jd.bodyA = touchedBodies.get(0); 
jd.bodyB = touchedBodies.get(1); 
jd.collideConnected = false; 
jd.localAnchorA.set(?????); 
jd.localAnchorB.set(?????); 
world.createJoint(jd); 

任何帮助,将不胜感激。

编辑:

我做了一些进步,但仍然没有。我现在在做的是根据形状的顶点找到一个“平均”位置。我正在拍摄第一个条目,并且知道顶点逆时针计算哪一个是中间顶点,并且假定它距离第一个顶点最远。所以我做了这两个的平均,并在那里设置关节。

下面的代码:

Shape shape1 = touchedFixtures.get(0).getShape(); 
Vec2 oneAverage = null; 
if(shape1.getClass() == PolygonShape.class) { 
    PolygonShape s = (PolygonShape)shape1; 
    Vec2[] vs = s.m_vertices; 
    List<Vec2> vsNonZero = new LinkedList<Vec2>(); 
    for(int i=0; i<vs.length; i++) { 
     if(vs[i].x != 0 || vs[i].y != 0) { 
      vsNonZero.add(vs[i]); 
     } 
    } 
    Vec2 oneOne = vsNonZero.get(0); 
    Vec2 oneMiddle = vsNonZero.get(Math.round(vsNonZero.size()/2)); 
    oneAverage = new Vec2((oneOne.x + oneMiddle.x)/2, (oneOne.y + oneMiddle.y)/2); 
} 

而且关节的局部主播:

jointDef.localAnchorA.set(oneAverage); 

我做的是同为联合的第二主体。这发现一个相当不错的接近度,但它并不完美,特别是如果形状较大。

任何想法如何接近实际接触点?我需要的东西就像shape.getTouchedPoint(),但API似乎没有提供它。

回答

0

本地锚点是指关节在本地身体坐标系中“连接”的位置。每个物体都有它自己的坐标系,它是当你将形状定位在身体中时使用的系统。例如,当身体在世界中旋转时,形状与人体局部坐标中的位置相同。

所以localAnchorA是人体A的局部坐标系与身体B.身体A的连接,同样对于B

基本上,在坐标纸上绘出形状与它们的形状坐标,你给了创建时,然后使用该坐标系为关节的锚点选择一个点。

编辑:对于动态的东西,在身体对象上使用getLocalPoint方法,或者更酷,并使用getLocalPointToOut方法。喜欢的东西:

jd.bodyA.getLocalPointToOut(worldLocation, jd.localAnchorA); 
+0

感谢Daniel的答复,但我需要动态设置关节,因此我无法从图表中选择它。我需要的东西就像shape.getTouchedPoint(),但API似乎没有提供它。 – Eddy 2013-05-05 13:35:12

+0

我用我现在使用的一些代码编辑了这个问题。有进展,但我仍然不在那里。 – Eddy 2013-05-05 13:50:06

+0

啊,我看到了,是的,你想使用getLocalPoint,因为你发现。为了更有效率,你应该使用getLocalPointToOut(locationWorld,jd.localAnchorA); – 2013-05-07 20:34:16

1

这是你如何做到这一点:上述

jd.localAnchorA = touchedBodies.get(0).getLocalPoint(locationWorld); 
jd.localAnchorB = touchedBodies.get(1).getLocalPoint(locationWorld); 

touchedBodies是简单地被感动,这两个机构的列表,所以上面的可以用这个来代替:

jd.localAnchorA = bodyA.getLocalPoint(locationWorld); 
jd.localAnchorB = bodyB.getLocalPoint(locationWorld); 

谢谢iforce2d在这里提供这个答案(http://www.cocos2d-iphone.org/forum/topic/343137#post-507904)以及一些解释和C++代码。