Ejemplo n.º 1
0
        /* Separa la pelota según la información en mtv. */
        private void Separate(MinimumTranslationVector mtv)
        {
            /* Calculo el vector de la separación. */
            Vector displacement = mtv.axis.NewWithLength(mtv.overlap);

            /* Le sumo este vector a la posición de la pelota. */
            this.lastPosition = this.position.Copy();
            this.position.Sum(displacement);
        }
Ejemplo n.º 2
0
        /* Función estática que recibe dos polígonos y aplica el teorema SAT. Devuelve un
         * vector de traslación mínimo con la información de la colisión. Si ese vector es null,
         * no ha habido colisión; si tiene valor, la ha habido. */
        private static MinimumTranslationVector SATCollision(Polygon polygon1, Polygon polygon2)
        {
            /* Declaro el resultado del algoritmo, un vector de traslación mínimo. */
            MinimumTranslationVector result = new MinimumTranslationVector();

            List <Vector> axes = new List <Vector>();
            Vector        axisWithMinOverlap = null;
            double        minOverlap         = double.MaxValue;

            /* Añado los ejes del primer polígono. */
            for (int i = 0; i < polygon1.Yaxes.Count; i++)
            {
                axes.Add(polygon1.Yaxes[i]);
            }

            /* Añado los ejes del segundo polígono. */
            for (int j = 0; j < polygon2.Yaxes.Count; j++)
            {
                axes.Add(polygon2.Yaxes[j]);
            }

            /* Recorro cada eje. */
            Projection polygon1Projection;
            Projection polygon2Projection;
            double     overlap;

            for (int k = 0; k < axes.Count; k++)
            {
                /* Obtengo las proyecciones de cada figura. */
                polygon1Projection = new Projection(axes[k], polygon1);
                polygon2Projection = new Projection(axes[k], polygon2);

                /* Compruebo si se solapan. */
                overlap = Projection.Overlap(polygon1Projection, polygon2Projection);
                if (overlap == 0)
                {
                    /* No hay solapamiento entre estas dos proyecciones, por
                     * tanto no hay solapamiento. */
                    result.axis    = null;
                    result.overlap = 0;
                    return(result);
                }
                else if (overlap < minOverlap)
                {
                    /* Me quedo con este. */
                    minOverlap         = overlap;
                    axisWithMinOverlap = axes[k];
                }
            }

            /* No ha habido separación en ningún eje, así que hay colisión
             * y devolvemos el mtv relleno con los mejores valores. */
            result.axis    = axisWithMinOverlap.Copy();
            result.overlap = minOverlap;
            return(result);
        }
Ejemplo n.º 3
0
        /* Comprueba que el eje que marca mtv apunta desde el polígono hacia la pelota,
         * para sacarla hacia afuera. */
        private void CheckSATAxisDirection(MinimumTranslationVector mtv, Polygon polygon)
        {
            /* Calculo un vector desde el centroide de la pelota hasta el centroide
             * del polígono. */
            Vector ballDirection = Vector.Subtract(polygon.Centroid, this.position);

            ballDirection.Normalize();

            if (Vector.DotProduct(mtv.axis, ballDirection) > 0)
            {
                /* Ambos vectores van en la misma dirección, así que
                 * hay que cambiar el eje de mtv de sentido. */
                mtv.axis.X *= -1;
                mtv.axis.Y *= -1;
            }
        }
Ejemplo n.º 4
0
        /* Recibe un vector de traslación mínimo procedente del SAT y un polígono,
         * y tiene que rebotar del polígono según el valor del vector. */
        public void Bounce(MinimumTranslationVector mtv, Polygon polygon)
        {
            /* Compruebo que el eje del mtv es el que lleva
             * la bola hacia afuera del polígono. */
            this.CheckSATAxisDirection(mtv, polygon);

            /* Primero separo la pelota del polígono la cantidad
             * requerida por mtv. */
            this.Separate(mtv);

            /* Reflejo la velocidad sobre el eje mtv. */
            this.Deflect(mtv.axis);

            /* Compruebo que la velocidad no se ha salido de los límites. */
            this.CheckVelocityLimit();
        }
Ejemplo n.º 5
0
        /* Gestiona la colisión de este polígono con una pelota, aplicando
         * el teorema SAT. */
        public bool HandleCollisionSAT(Ball ball)
        {
            /* Actualizamos el polígono de colisión de la pelota. */
            ball.UpdateCollisionPolygon();

            /* Aplico el teorema de separación de ejes y guardo el resultado en mtv. */
            MinimumTranslationVector mtv = SATCollision(this, ball.Polygon);

            if (mtv.MeansCollision())
            {
                /* El resultado de SAT es una colisión, así que tenemos que rebotar la
                 * pelota de este polígono. */
                Console.WriteLine(DateTime.UtcNow + " voy a aplicar bounce");
                ball.Bounce(mtv, this);
                return(true);
            }

            return(false);
        }