¿Cómo puedo detectar mediante programación si dos triángulos se tocan entre sí o no, dados sus vértices en un plano de coordenadas 2D? Esto incluye tocar puntos o bordes, así como si un triángulo está completamente dentro del otro.Detección de colisiones triangulares en espacio 2D
Respuesta
intersección Uso Línea Línea
Ten en cuenta también la posibilidad de que algún vértice podría estar tocando uno de los lados del otro triángulo.
http://www.blackpawn.com/texts/pointinpoly/default.html
function SameSide(p1,p2, a,b)
cp1 = CrossProduct(b-a, p1-a)
cp2 = CrossProduct(b-a, p2-a)
if DotProduct(cp1, cp2) >= 0 then return true
else return false
function PointInTriangle(p, a,b,c)
if SameSide(p,a, b,c) and SameSide(p,b, a,c)
and SameSide(p,c, a,b) then return true
else return false
O mirar en este enlace y desplazarse hacia abajo
Esto no comprueba si un triángulo está completamente dentro de otro, sin embargo, sí lo hace. – qJake
@SpikeX: Iba a decir lo mismo, pero creo que debe hacer clic en el enlace de la parte inferior para buscar el artículo de PointInPolygon (http://www.topcoder.com/tc?module=Static&d1=tutorials&d2 = geometría3) – Dave
Para eso necesitas asegurarte de que los 3 vértices estén en los bordes o dentro del triángulo. Déjame encontrar un enlace. Mientras tanto, siéntete libre de votar. –
Puede probar que los dos triángulos no colisionan mediante la búsqueda de un borde (de un total de 6 aristas que forman los dos triángulos) que actúa como una línea de separación donde todos los vértices de un triángulo se encuentran en un lado y los vértices del otro triángulo se encuentran en el otro lado. Si puede encontrar tal borde, significa que los triángulos no se cruzan, de lo contrario, los triángulos están colisionando.
Aquí hay una implementación de Matlab de la función de colisión triangular. Usted puede encontrar que la teoría de la función sameside
aquí: http://www.blackpawn.com/texts/pointinpoly/default.html
function flag = triangle_intersection(P1, P2)
% triangle_test : returns true if the triangles overlap and false otherwise
% P1, P2: a 3 by 2 array (each), describing the vertices of a triangle,
% the first column corresponds to the x coordinates while the second column
% corresponds to the y coordinates
function flag = sameside(p1,p2,a,b)
% sameside : returns true if the p1,p1 lie on same sides of the
% edge ab and false otherwise
p1(3) = 0; p2(3) = 0; a(3) = 0; b(3) = 0;
cp1 = cross(b-a, p1-a);
cp2 = cross(b-a, p2-a);
if(dot(cp1, cp2) >= 0)
flag = true;
else
flag = false;
end
end
% Repeat the vertices for the loop
P1(4:5,:) = P1(1:2,:);
P2(4:5,:) = P2(1:2,:);
flag = true;
% Testing all the edges of P1
for i=1:3
if(~sameside(P1(i,:), P2(1,:), P1(i+1,:), P1(i+2,:)) ...
&& sameside(P2(1,:), P2(2,:), P1(i+1,:), P1(i+2,:)) ...
&& sameside(P2(2,:), P2(3,:), P1(i+1,:), P1(i+2,:)))
flag = false; return;
end
end
% Testing all the edges of P2
for i=1:3
if(~sameside(P2(i,:), P1(1,:), P2(i+1,:), P2(i+2,:)) ...
&& sameside(P1(1,:), P1(2,:), P2(i+1,:), P2(i+2,:)) ...
&& sameside(P1(2,:), P1(3,:), P2(i+1,:), P2(i+2,:)))
flag = false; return;
end
end
end
Puede hacer esto más rápido si tiene en cuenta que todos los triángulos son convexos. Debido a que son convexos, a medida que avanzas por los puntos, todos giran en la misma dirección, por lo que siempre sabes de qué lado está el punto del triángulo. – Eyal
En resumen, la respuesta de Hassan es más rápido.
https://jsfiddle.net/eyal/gxw3632c/
Este es el código más rápido en javascript:
// check that all points of the other triangle are on the same side of the triangle after mapping to barycentric coordinates.
// returns true if all points are outside on the same side
var cross2 = function(points, triangle) {
var pa = points.a;
var pb = points.b;
var pc = points.c;
var p0 = triangle.a;
var p1 = triangle.b;
var p2 = triangle.c;
var dXa = pa.x - p2.x;
var dYa = pa.y - p2.y;
var dXb = pb.x - p2.x;
var dYb = pb.y - p2.y;
var dXc = pc.x - p2.x;
var dYc = pc.y - p2.y;
var dX21 = p2.x - p1.x;
var dY12 = p1.y - p2.y;
var D = dY12 * (p0.x - p2.x) + dX21 * (p0.y - p2.y);
var sa = dY12 * dXa + dX21 * dYa;
var sb = dY12 * dXb + dX21 * dYb;
var sc = dY12 * dXc + dX21 * dYc;
var ta = (p2.y - p0.y) * dXa + (p0.x - p2.x) * dYa;
var tb = (p2.y - p0.y) * dXb + (p0.x - p2.x) * dYb;
var tc = (p2.y - p0.y) * dXc + (p0.x - p2.x) * dYc;
if (D < 0) return ((sa >= 0 && sb >= 0 && sc >= 0) ||
(ta >= 0 && tb >= 0 && tc >= 0) ||
(sa+ta <= D && sb+tb <= D && sc+tc <= D));
return ((sa <= 0 && sb <= 0 && sc <= 0) ||
(ta <= 0 && tb <= 0 && tc <= 0) ||
(sa+ta >= D && sb+tb >= D && sc+tc >= D));
}
var trianglesIntersect4 = function(t0, t1) {
return !(cross2(t0,t1) ||
cross2(t1,t0));
}
que escribió el violín de arriba para probar algunas técnicas diferentes y comparar la velocidad. Todas las técnicas se basan en una combinación de tres herramientas diferentes:
- Baricéntrico prueba de punto en el triángulo: convertir un punto de x, y espacio para u, v espacio donde u, v son dos caras de el triangulo. Luego prueba si el punto está dentro del triángulo (0,0) (0,1) (1,0), lo cual es fácil.
- lado misma prueba de punto en el triángulo: Esta prueba le indica si un ángulo es más o menos de 180 grados. Si el triángulo es a, b, c y su punto es p, compruebe si el ángulo pab y bac son ambos más o ambos menos de 180. Debe hacer esto para ab, bc y ca. Si alguno es cierto, el punto está afuera. Esta prueba es más lenta que baricéntrica por un punto.
- Line segmento intersección: Comprobar si el segmento de línea a, b interseca la línea segmento c, d. Para hacer eso, encontrará el punto donde se cruzan las dos líneas y luego verifique que esas líneas estén en el cuadro delimitador de a, by b, c. Esto es casi tan rápido como Barycentric.
Esas son las herramientas.Ahora, para averiguar si los triángulos se cruzan, hay 3 formas en que he probado:
- 8 intersección de líneas y 2 de punto en el triángulo: sólo necesita 8 intersección de líneas y no todos 9 porque no puede ser solo 1 intersección. Después de eso, necesitas 2 puntos en triángulo en caso de que 1 triángulo esté completamente dentro del otro.
- intersección de 6 líneas y 4 puntos en triángulo: Si la dibuja, puede ver que puede ignorar por completo un lado de uno de los triángulos para la intersección de línea y luego hacer todos los puntos de otros triángulos para punto en triángulo. Debido a que la intersección de línea y la baricéntrica son aproximadamente la misma velocidad, esto no es mucho mejor que el # 1. Pero si utilizó el mismo lado, será más rápido porque el mismo punto en triángulo es más lento.
- 9 pruebas de punto en triángulo en el mismo lado: Puede usar cualquier baricentro o el mismo lado. Para cualquiera, modifique el punto en triángulo para probar 3 puntos al mismo tiempo y no quiere simplemente probar que son los tres fuera del triángulo, debe probar que están todos 3 fuera de en el el mismo lado. Debido a que estamos reutilizando mucha información, podemos ahorrar tiempo en los cálculos. Una vez más, baricéntrico parece un poco más rápido que el mismo lado aquí también.
- 1. Detección de colisiones poligonales 2D
- 2. Quadtree para detección de colisiones 2D
- 3. Javascript Detección de colisiones
- 4. modelo de actor y detección de colisiones
- 5. Recursos de uso de técnicas para la detección de colisiones en 2D?
- 6. ¿Qué es un buen algoritmo de detección de colisiones en 2D rectángulos solo?
- 7. ¿Solamente está integrando la detección de colisiones Box2D en mi motor 2d?
- 8. Java Tile Game - Detección de colisiones
- 9. QuadTree para detección de colisión 2D
- 10. 2D Detección de colisión continua
- 11. Desarrollo de juegos para Android: detección de colisiones fallidas
- 12. detección de colisiones de formas irregulares en IOS
- 13. detección de colisiones entre dos imágenes en Java
- 14. Detección de colisiones deslizando contra un plano en XNA
- 15. Mejor algoritmo para detección de colisiones eficiente entre objetos
- 16. ¿Alguien puede explicar la detección de colisiones por píxel?
- 17. Pathfinding básico con evitación de obstáculos en un espacio 2D continuo
- 18. Javascript phsyics en un espacio 2d
- 19. Simulación en 2D de choques 2D (Detección rápida de colisión para gran cantidad de bolas)
- 20. Problema de detección de colisiones basado en píxeles con OpenGLES 2.0 en Android
- 21. XNA C# 2D juego de plataformas
- 22. 2d física de plataformas
- 23. Uso del polimorfismo para la detección de colisiones de una manera elegante
- 24. Generando coordenadas triangulares/hexagonales (xyz)
- 25. Good Object Oriented Class Design para la detección de colisiones en el desarrollo de juegos
- 26. ¿Cuál es la mejor manera de implementar la detección de colisiones unidimensionales?
- 27. C# Algoritmo de detección de espacio en blanco GDI Edge
- 28. Número esperado de colisiones hash
- 29. ¿Alguien sabe si hay alguna API de detección de colisiones para HTML5 Canvas ...?
- 30. Recomendamos un plugin JQuery que maneje la detección de colisiones para elementos que se pueden arrastrar
parece estar cerca de un duplicado de esta pregunta: http://stackoverflow.com/questions/1903258/triangle-triangle-intersection-test Eso es 3D, 2D no, pero tal vez algunas de las respuestas que habrá ayudar de todos modos. – bcat
Ya examiné esa pregunta, parece que tengo mucha más información de la que necesito, ya que está en 3D específicamente, y no quiero complicar demasiado los cálculos aquí (estos se realizarán en un ciclo, y deberían ser lo más rentable posible). – qJake
Posible duplicado de [¿Cuál es la forma más eficiente de detectar intersecciones triángulo-triángulo?] (Http://stackoverflow.com/questions/1585459/whats-the-most-efficient-way-to-detect-triangle-triangle-intersections) – TimSC