コード例 #1
0
        /// <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);
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        /// <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);
        }
コード例 #4
0
        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);
                    }
                }
            }
        }