/// <summary> /// Detecta interseção entre dois segmentos de retas /// </summary> /// <param name="pontoA1">Ponto A do segmento 1</param> /// <param name="pontoB1">Ponto B do segmento 1</param> /// <param name="pontoA2">Ponto A do segmento 2</param> /// <param name="pontoB2">Ponto B do segmento 2</param> /// <param name="intersecao">Ponto de interseção entre as retas</param> /// <param name="linhas_intersecao">Linha de interseção?</param> /// <param name="aa">Ponto A da linha de interseç+ão</param> /// <param name="bb">Ponto B da linha de interseção</param> /// <returns></returns> public static bool IntersecaoEntreDuasRetas(Vertice2 pontoA1, Vertice2 pontoB1, Vertice2 pontoA2, Vertice2 pontoB2, out Vertice2 intersecao, out bool linhas_intersecao, out Vertice2 aa, out Vertice2 bb) { // Obtém os parâmetros dos segmentos float dxAB = pontoB1.X - pontoA1.X; float dyAB = pontoB1.Y - pontoA1.Y; float dxCD = pontoB2.X - pontoA2.X; float dyCD = pontoB2.Y - pontoA2.Y; // Resolve para t1 e t2 float denominador = (dyAB * dxCD - dxAB * dyCD); float t1 = ((pontoA1.X - pontoA2.X) * dyCD + (pontoA2.Y - pontoA1.Y) * dxCD) / denominador; if (float.IsInfinity(t1)) { // As linhas são paralelas (ou próximas o suficiente) linhas_intersecao = false; intersecao = null; aa = null; bb = null; return(false); } linhas_intersecao = true; float t2 = ((pontoA2.X - pontoA1.X) * dyAB + (pontoA1.Y - pontoA2.Y) * dxAB) / -denominador; // Ponto de interseção intersecao = new Vertice2(pontoA1.X + dxAB * t1, pontoA1.Y + dyAB * t1); // Os segmentos se cruzam se t1 e t2 estiverem entre 0 e 1 bool colisao = ((t1 >= 0) && (t1 <= 1) && (t2 >= 0) && (t2 <= 1)); // Encontre os pontos mais próximos nos segmentos if (t1 < 0) { t1 = 0; } else if (t1 > 1) { t1 = 1; } if (t2 < 0) { t2 = 0; } else if (t2 > 1) { t2 = 1; } // Linha de interseção aa = new Vertice2(pontoA1.X + dxAB * t1, pontoA1.Y + dyAB * t1); bb = new Vertice2(pontoA2.X + dxCD * t2, pontoA2.Y + dyCD * t2); return(colisao); }
public static Eixos2 operator +(Eixos2 a, Vertice2 b) { Vertice2 ret = new Vertice2(b.Obj); ret.X = a.X + b.X; ret.Y = a.Y + a.Y; return(ret); }
/// <summary> /// Checa se ocorre a interseção entre dois polígonos /// </summary> /// <param name="a">Vértices de posições X e Y globais</param> /// <param name="b">Vértices de posições X e Y globais</param> /// <returns></returns> public static bool IntersecaoEntrePoligonos(Vertice2[] a, params Vertice2[] b) { foreach (Vertice2[] vPoligono in new[] { a, b }) { for (int i1 = 0; i1 < vPoligono.Count(); i1++) { int i2 = (i1 + 1) % vPoligono.Count(); Vertice2 p1 = vPoligono[i1]; Vertice2 p2 = vPoligono[i2]; Vetor2 normal = new Vetor2(p2.Y - p1.Y, p1.X - p2.X); float?minA = null, maxA = null; foreach (var p in a) { var projetado = normal.X * p.X + normal.Y * p.Y; if (minA == null || projetado < minA) { minA = projetado; } if (maxA == null || projetado > maxA) { maxA = projetado; } } float?minB = null, maxB = null; foreach (var p in b) { float projetado = normal.X * p.X + normal.Y * p.Y; if (minB == null || projetado < minB) { minB = projetado; } if (maxB == null || projetado > maxB) { maxB = projetado; } } if (maxA < minB || maxB < minA) { return(false); } } } return(true); }
public static IEnumerable <Vertice2> ObterVerticesObjeto2DPelaTela(this Camera2D cam, List <Objeto2D> objs, params Vertice2[] verticesTela) { for (int i = 0; i < verticesTela.Length; i++) { // Converte X e Y da tela para as coordenadas X e Y no mundo 2D Eixos2 xy = ObterPosEspaco2DMouseXY(cam, verticesTela[i]); verticesTela[i].X = xy.X; verticesTela[i].Y = xy.Y; } for (int o = 0; o < objs.Count; o++) { Objeto2D obj = objs[o]; for (int i = 0; i < obj.Vertices.Count(); i++) { Vertice2 vertice = obj.Vertices[i]; if (IntersecaoEntrePoligonos(verticesTela, new Vertice2(vertice.Global.X, vertice.Global.Y))) { yield return(vertice); } } } }