예제 #1
0
        public frmPrincipal()
        {
            InitializeComponent();

            Paint   += new PaintEventHandler(Form1_Paint);
            KeyDown += new KeyEventHandler(Form1_KeyDown);

            KeyPreview     = true;
            DoubleBuffered = true;

            Random rnd = new Random(Environment.TickCount);

            Poligono p = new Poligono();

            p.Pontos.Add(new Vetor(0, 0));
            p.Pontos.Add(new Vetor(50, -25));
            p.Pontos.Add(new Vetor(75, 0));
            p.Pontos.Add(new Vetor(75, 75));
            p.Pontos.Add(new Vetor(50, 100));
            p.Pontos.Add(new Vetor(0, 75));
            p.cor = Color.FromArgb(255, rnd.Next(0, 255), rnd.Next(0, 255), rnd.Next(0, 255));
            poligonos.Add(p);

            p = new Poligono();
            p.Pontos.Add(new Vetor(150, 150));
            p.Pontos.Add(new Vetor(50, 0));
            p.Pontos.Add(new Vetor(150, 0));
            p.Posicao(80, 80);
            p.cor = Color.FromArgb(255, rnd.Next(0, 255), rnd.Next(0, 255), rnd.Next(0, 255));
            poligonos.Add(p);

            p = new Poligono();
            p.Pontos.Add(new Vetor(0, 50));
            p.Pontos.Add(new Vetor(50, 0));
            p.Pontos.Add(new Vetor(150, 80));
            p.Pontos.Add(new Vetor(160, 200));
            p.Pontos.Add(new Vetor(-10, 190));
            p.Posicao(300, 300);
            p.cor = Color.FromArgb(255, rnd.Next(0, 255), rnd.Next(0, 255), rnd.Next(0, 255));
            poligonos.Add(p);

            foreach (Poligono polygon in poligonos)
            {
                polygon.CriarArestas();
            }

            jogador = poligonos[0];
        }
예제 #2
0
        // Calcule a projeção de um polígono em um eixo e retorne-o como um intervalo [min, max]
        public void ProjecaoPoligono(Vetor eixo, Poligono poligono, ref float min, ref float max)
        {
            // Para projetar um ponto em um eixo, use o produto escalar
            float d = eixo.ProdutoPontual(poligono.Pontos[0]);

            min = d;
            max = d;
            for (int i = 0; i < poligono.Pontos.Count; i++)
            {
                d = poligono.Pontos[i].ProdutoPontual(eixo);
                if (d < min)
                {
                    min = d;
                }
                else
                {
                    if (d > max)
                    {
                        max = d;
                    }
                }
            }
        }
예제 #3
0
        // Verifique se o polígono A vai colidir com o polígono B na velocidade dada
        public ColisaoPoligonoResultado ColisaoPoligono(Poligono poligonoA, Poligono poligonoB, Vetor velocidade)
        {
            ColisaoPoligonoResultado resultado = new ColisaoPoligonoResultado();

            resultado.Intersecao  = true;
            resultado.Interceptar = true;

            int   arestaCountA        = poligonoA.Arestas.Count;
            int   arestaCountB        = poligonoB.Arestas.Count;
            float minIntervalDistance = float.PositiveInfinity;
            Vetor EixoTranslacao      = new Vetor();
            Vetor aresta;

            // Loop através de todas as bordas de ambos os polígonos
            for (int indiceAresta = 0; indiceAresta < arestaCountA + arestaCountB; indiceAresta++)
            {
                if (indiceAresta < arestaCountA)
                {
                    aresta = poligonoA.Arestas[indiceAresta];
                }
                else
                {
                    aresta = poligonoB.Arestas[indiceAresta - arestaCountA];
                }

                // ===== 1. Descobrir se os polígonos estão se cruzando atualmente =====

                // Encontre o eixo perpendicular à borda atual
                Vetor eixo = new Vetor(-aresta.Y, aresta.X);
                eixo.Normalizar();

                // Encontre a projeção do polígono no eixo atual
                float minA = 0; float minB = 0; float maxA = 0; float maxB = 0;
                ProjecaoPoligono(eixo, poligonoA, ref minA, ref maxA);
                ProjecaoPoligono(eixo, poligonoB, ref minB, ref maxB);

                // Verifique se as projeções de polígono estão se cruzando atualmente
                if (DistanciaDoIntervalo(minA, maxA, minB, maxB) > 0)
                {
                    resultado.Intersecao = false;
                }

                // ===== 2. Agora, encontre os polígonos que irão se *cruzar* =====

                // Projetar a velocidade no eixo atual
                float velocidadeProjecao = eixo.ProdutoPontual(velocidade);

                // Obter a projeção do polígono A durante o movimento
                if (velocidadeProjecao < 0)
                {
                    minA += velocidadeProjecao;
                }
                else
                {
                    maxA += velocidadeProjecao;
                }

                // Faça o mesmo teste acima para a nova projeção
                float distanciaDoIntervalo = DistanciaDoIntervalo(minA, maxA, minB, maxB);
                if (distanciaDoIntervalo > 0)
                {
                    resultado.Interceptar = false;
                }

                // Se os polígonos não estiverem se cruzando e não se cruzarem, saia do loop
                if (!resultado.Intersecao && !resultado.Interceptar)
                {
                    break;
                }

                // Verifique se a distância atual do intervalo é a mínima.
                // Em caso afirmativo, armazene a distância do intervalo e a distância atual.
                // Isso será usado para calcular o vetor de transladação mínima
                distanciaDoIntervalo = Math.Abs(distanciaDoIntervalo);
                if (distanciaDoIntervalo < minIntervalDistance)
                {
                    minIntervalDistance = distanciaDoIntervalo;
                    EixoTranslacao      = eixo;

                    Vetor d = poligonoA.Centro - poligonoB.Centro;
                    if (d.ProdutoPontual(EixoTranslacao) < 0)
                    {
                        EixoTranslacao = -EixoTranslacao;
                    }
                }
            }

            // O vetor de transladação mínimo pode ser usado para pressionar os polígonos.
            // Primeiro move os polígonos pela sua velocidade e, em seguida, move PoligonoA por TransladacaoMinimaVetor.
            if (resultado.Interceptar)
            {
                resultado.TranslacaoMinimaVetor = EixoTranslacao * minIntervalDistance;
            }

            return(resultado);
        }