fisic javascript box2d physics curve chipmunk

fisic - Motor de física Javascript y curva infinita simulada.



fisic js (3)

La mejor solución son las formas de borde con vértices fantasma, pero si eso no está disponible en la versión / puerto que está utilizando, la siguiente mejor opción es como el diagrama en su pregunta llamada "borde", pero extienda los polígonos más a fondo bajo tierra. pendiente baja, como en este hilo: http://www.box2d.org/forum/viewtopic.php?f=8&t=7917

Estoy tratando de hacer un Tiny Wings como en javascript.

La primera vez que vi una técnica usando Box2D , estoy usando la versión web de cierre (debido a la corrección de fugas de memoria).
En resumen, exploto la curva en polígonos para que se vea así:

También probé con Chipmunk-js y uso la forma de segmento para simular mi terreno de esa manera:

En ambos casos, estoy experimentando algunos "choques" o "baches" en los puntos comunes entre polígonos o segmentos cuando un círculo está rodando.

Pregunté por Chipmunk y el autor dijo que implementó una propiedad de radio para que el segmento redujera este comportamiento. Lo intenté y de hecho hizo el truco pero no es perfecto. Todavía tengo algunos baches (tuve que configurarlo a 30px de radio para obtener un efecto positivo).

Los "baches" se añaden en los puntos compartidos entre dos polígonos:

Usando, como illandril sugirió illandril , la técnica de bordes (solo probó con polígono-polígono de contacto) para evitar que el círculo se estrellara en un borde:

También intenté agregar la opción de viñeta como sugirió Luc y nada parece cambiar.

Aquí la demo del tema.
Puedes intentar cambiar el valor para verificar:

  • opción de bala
  • tamaño del borde
  • las iteraciones cuentan
  • los físicos

(solo probado en el último dev Chrome)
Sé paciente (o cambia la gravedad horizontal) y verás lo que quiero decir.
Aquí el repo para los interesados.


Primero pensé que el problema podría venir del cambio de pendiente entre dos segmentos adyacentes, pero como en una superficie plana de polígonos todavía tiene baches, creo que el problema es más bien golpear la esquina de un polígono.

¿No sé si puedes establecer dos conjuntos de polígonos, superponiéndose entre sí? Simplemente use los mismos cálculos de interpolación y genere un segundo conjunto de polígonos como en el diagrama a continuación: tiene el conjunto rojo de polígonos y agrega el conjunto verde al establecer los vértices izquierdos de un polígono verde en el centro de un polígono rojo, y sus vértices derechos en el medio del siguiente polígono rojo.

! [diagrama] [1]

Esto debería funcionar en curvas cóncavas y ... bueno, deberías estar volando sobre las convexas de todos modos.

Si esto no funciona, intente establecer un gran número de polígonos para construir la pendiente. Usa una décima parte del radio del círculo para el ancho del polígono, tal vez incluso menos. Eso debería reducir sus discontinuidades de pendiente.

- editar

En la línea 5082 de Box2D.js (al menos en este repositorio ) tiene la función PreSolve (contacto, colector) que puede anular para verificar si los colectores (direcciones en las que se impulsa la bola de nieve al chocar con los polígonos) son correctos.

Para hacerlo, necesitaría recuperar el vector múltiple y compararlo con la normal de la curva. Debería verse así (quizás no exactamente):

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


Yo diría que el problema se ha abordado en Box2D 2.2.0, consulte su manual, sección 4.5 "Formas de borde"

La cosa es que es una característica de la versión 2.2.0 , junto con la cadena, y box2dweb en realidad está portado desde 2.2.1a, no sé acerca de box2dweb-closing.

Todo lo que he intentado modificando Box2D.Collision.b2Collision.CollidePolygonAndCircle ha dado como resultado un comportamiento errático. Al menos una parte del tiempo (p. Ej., Bola que golpea en direcciones aleatorias, pero solo cuando rueda lentamente).