2013-05-04 2 views
0

В проекте Box2D Мне нужно создать RevoluteJoint между двумя объектами PolygonShaped в точную точку, где пользователь дважды постучал.Поиск точки касания формы

У меня есть точка касания и список вершин для каждой из двух фигур (очевидно, чтобы они не сталкивались друг с другом). Если я правильно понимаю, точка касания находится в терминах местоположения в мире и вершины описывают форму, которая может находиться в любом мире. Но как мне «переводить» из одного в другой?

Например, пользователь дважды постучал по (3.63.5.07).

Вершины для формы 1 являются: [(0,37485206, -0,17777264), (-0,2880008, -0,033603553), (-0,1609711, -0,2395713), (-0,04113376, -0,31708732), (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); 

Любая помощь будет принята с благодарностью.

EDIT:

Я сделал немного прогресса, но до сих пор не существует. Теперь я нахожу «среднее» местоположение, основанное на вершинах формы. Я беру первую запись и зная, что вершины идут против часовой мудрый, подсчитывают, какая из них - средняя вершина, и полагает, что она наиболее далека от первой. Поэтому я делаю в среднем по два и устанавливаю там сустав.

Вот код:

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 является соединение тела А в локальной системе координат тела А, в то же самое для B с телом В.

В принципе, рисовать фигуры на миллиметровой бумаге с их формой координаты, которые вы дали при ее создании , затем используйте эту систему координат, чтобы выбрать точку для якоря сустава.

Редактировать: для динамических материалов используйте метод getLocalPoint на объекте кузова или кулер и используйте метод getLocalPointToOut.Что-то вроде:

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

Спасибо за ответ, Дэниэл, но мне нужно установить динамическое соединение, чтобы я не мог выбрать его из графика. Мне нужно что-то вроде shape.getTouchedPoint(), но API, похоже, не предоставляет его. – Eddy

+0

Я отредактировал вопрос с помощью некоторого кода, который я использую сейчас. Там прогресс, но я все еще не там. – Eddy

+0

А я вижу, да, вы хотите использовать getLocalPoint, как вы нашли. Чтобы быть еще более эффективным, вы должны использовать getLocalPointToOut (locationWorld, jd.localAnchorA); –

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); 

Благодарим вас за этот ответ здесь (http://www.cocos2d-iphone.org/forum/topic/343137#post-507904), а также код на C++.

Смежные вопросы