Example #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="p1">Source Point</param>
        /// <param name="p2">Rotating Point</param>
        /// <param name="theta">Angle</param>
        /// <returns></returns>
        public static Vector2 TransformAround(Vector2 p1, Vector2 p2, float theta)
        {
            float rot  = LocationManager.getRotation(p1, p2) + theta;
            float dist = LocationManager.getDistance(p1, p2);

            return(new Vector2(p1.X + (dist * (float)Math.Cos(rot)), p1.Y + (dist * (float)Math.Sin(rot))));
        }
Example #2
0
        /// <summary>
        /// Checks if a line intersects a circle and returns the first intersection point
        /// </summary>
        /// <param name="line">The line to check</param>
        /// <param name="CirclePosition">The position of the circle</param>
        /// <param name="CircleRadius">The radius of the circle</param>
        /// <returns>A list of intersection points</returns>
        public static Vector2?CircleIntersects_CV(Vector2[] line, Vector2 CirclePosition, float CircleRadius)
        {
            Vector2 d = Vector2.Subtract(line[1], line[0]);
            Vector2 f = Vector2.Subtract(line[0], CirclePosition);
            float   a = Vector2.Dot(d, d);
            float   b = 2 * Vector2.Dot(f, d);
            float   c = Vector2.Dot(f, f) - CircleRadius * CircleRadius;

            float discriminant = b * b - 4 * a * c;

            if (discriminant < 0)
            {
            }
            else
            {
                discriminant = (float)Math.Sqrt(discriminant);

                float t1 = (-b - discriminant) / (2 * a);
                float t2 = (-b + discriminant) / (2 * a);

                if (t1 >= 0 && t1 <= 1)
                {
                    return(LocationManager.moveByRotation(line[0], t1 * LocationManager.getDistance(line[0], line[1]), LocationManager.getRotation(line[0], line[1])));
                }

                if (t2 >= 0 && t2 <= 1)
                {
                    return(LocationManager.moveByRotation(line[0], t2 * LocationManager.getDistance(line[0], line[1]), LocationManager.getRotation(line[0], line[1])));
                }
            }
            return(null);
        }
Example #3
0
        /// <summary>
        /// Draws a generic texture (solid color) line between two points
        /// </summary>
        /// <param name="v1">Start point of the line</param>
        /// <param name="v2">End point of the line</param>
        /// <param name="sb">SpriteBatch to use</param>
        /// <param name="c">Color of the line</param>
        public static void drawLineGeneric(Vector2 v1, Vector2 v2, SpriteBatch sb, Color c)
        {
            float betweenAngle = LocationManager.getRotation(v1, v2);
            float distance     = LocationManager.getDistance(v1, v2);

            drawGenericNoCheck(sb, new Rectangle((int)Math.Round(LocationManager.moveByRotation(v1, distance / 2f, betweenAngle).X), (int)Math.Round(LocationManager.moveByRotation(v1, distance / 2f, betweenAngle).Y), (int)Math.Round(distance), 1), c, null, betweenAngle, new Vector2(0.5f, 0.5f), SpriteEffects.None, 0);
        }
Example #4
0
 /// <summary>
 /// Converts a line into a polygonal approximation, defined as an infinitely thin rectangle
 /// </summary>
 /// <param name="A"></param>
 /// <param name="B"></param>
 /// <returns></returns>
 public static Polygon GetFromLine(Vector2 A, Vector2 B)
 {
     float ang = LocationManager.getRotation(A, B);
     float dist = LocationManager.getDistance(A, B);
     Polygon tmp = new Polygon(UNIT_SQUARE(), LocationManager.moveByRotation(A, dist / 2, ang),ang );
     tmp.Scale(dist, 0);
     return tmp;
 }
Example #5
0
        private void CalculateArea()
        {
            AreaGood = true;
            area     = 0;
            for (int i = 0; i < corners.Length; i++)
            {
                Vector2 corner1 = corners[i];
                Vector2 corner2 = corners[(i + 1) % corners.Length];
                Vector2 center  = Vector2.Zero;

                area += (1 / 2f) * LocationManager.getDistance(center, corner1) * LocationManager.getDistance(center, corner2) * (float)Math.Sin(LocationManager.NormalRelitiveAngle_NormalInput(LocationManager.getRotation(center, corner1), LocationManager.getRotation(center, corner2)));
            }
        }
Example #6
0
        /// <summary>
        /// Draws an image stretched along it's X axis to form a line between two points
        /// </summary>
        /// <param name="sb">Spritebatch to use</param>
        /// <param name="i">The image to use</param>
        /// <param name="p1">Start point</param>
        /// <param name="p2">End point</param>
        /// <param name="forcedWidth">Width of the line</param>
        /// <param name="c">Tint color</param>
        public static void drawAsLine(SpriteBatch sb, Image i, Vector2 p1, Vector2 p2, int forcedWidth, Color c)
        {
            float distance = LocationManager.getDistance(p1, p2);
            float rotation = LocationManager.getRotation(p1, p2);

            Vector2 placementPoint = LocationManager.moveByRotation(p1, distance / 2, rotation);

            Rectangle colisCheck = new Rectangle((int)Math.Ceiling(Math.Min(p1.X, p2.X)), (int)Math.Ceiling(Math.Min(p1.Y, p2.Y)), (int)Math.Ceiling(Math.Abs(p1.X - p2.X)), (int)Math.Ceiling(Math.Abs(p1.Y - p2.Y)));

            Rectangle drawLocation = new Rectangle((int)placementPoint.X, (int)placementPoint.Y, (int)Math.Ceiling(distance), forcedWidth);

            drawLocation = new Rectangle(
                (int)((Math.Round((drawLocation.X - cameraLocation.X) * zoom)) + Camera.origin.X),
                (int)((Math.Round((drawLocation.Y - cameraLocation.Y) * zoom)) + Camera.origin.Y),
                (int)Math.Round(drawLocation.Width * zoom),
                (int)Math.Round(drawLocation.Height * zoom));

            if (colisCheck.Intersects(getFullScreen()))
            {
                sb.Draw(i.getTexture(), drawLocation, null, c, rotation, new Vector2(((float)i.getTexture().Width) / 2f, ((float)i.getTexture().Height) / 2f), SpriteEffects.None, 0);
            }
        }
Example #7
0
        public static Vector2[] getReflectionLine(Vector2[] src, Vector2[] tgt)
        {
            if (LinesIntersect_Precise(src, tgt) == 0)
            {
                return(null);
            }
            Vector2 si1 = convertLineToSI(src);
            Vector2 si2 = convertLineToSI(tgt);

            Vector2 pointOfIntersection = new Vector2();

            if (!float.IsInfinity(si1.X) && !float.IsInfinity(si2.X))
            {
                pointOfIntersection.X = (si2.Y - si1.Y) / (si1.X - si2.X);
                pointOfIntersection.Y = (si1.X * pointOfIntersection.X) + si1.Y;
            }
            else if (!float.IsInfinity(si2.X))
            {
                pointOfIntersection.X = src[0].X;
                pointOfIntersection.Y = (si2.X * pointOfIntersection.X) + si2.Y;
            }
            else if (!float.IsInfinity(si1.X))
            {
                pointOfIntersection.X = tgt[0].X;
                pointOfIntersection.Y = (si1.X * pointOfIntersection.X) + si1.Y;
            }

            float Angle1 = (float)Math.Atan2(src[1].Y - src[0].Y, src[1].X - src[0].X);
            float Angle2 = (float)Math.Atan2(tgt[1].Y - tgt[0].Y, tgt[1].X - tgt[0].X);

            float newAngle = Angle2 + (Angle2 - Angle1);

            float distanceRemaining = LocationManager.getDistance(src[0], src[1]) - LocationManager.getDistance(src[0], pointOfIntersection);

            Vector2[] returnLine = new Vector2[] { pointOfIntersection, moveByRotation(pointOfIntersection, distanceRemaining, newAngle) };

            return(returnLine);
        }
Example #8
0
        public static List <float> CircleIntersects_A(Vector2[] line, Vector2 CirclePosition, float CircleRadius)
        {
            List <float> outp = new List <float>();
            Vector2      d    = Vector2.Subtract(line[1], line[0]);
            Vector2      f    = Vector2.Subtract(line[0], CirclePosition);
            float        a    = Vector2.Dot(d, d);
            float        b    = 2 * Vector2.Dot(f, d);
            float        c    = Vector2.Dot(f, f) - CircleRadius * CircleRadius;

            float discriminant = b * b - 4 * a * c;

            if (discriminant < 0)
            {
                // no intersection
            }
            else
            {
                // ray didn't totally miss sphere,
                // so there is a solution to
                // the equation.

                discriminant = (float)Math.Sqrt(discriminant);

                // either solution may be on or off the ray so need to test both
                // t1 is always the smaller value, because BOTH discriminant and
                // a are nonnegative.
                float t1 = (-b - discriminant) / (2 * a);
                float t2 = (-b + discriminant) / (2 * a);

                // 3x HIT cases:
                //          -o->             --|-->  |            |  --|->
                // Impale(t1 hit,t2 hit), Poke(t1 hit,t2>1), ExitWound(t1<0, t2 hit),

                // 3x MISS cases:
                //       ->  o                     o ->              | -> |
                // FallShort (t1>1,t2>1), Past (t1<0,t2<0), CompletelyInside(t1<0, t2>1)

                if (t1 >= 0 && t1 <= 1)
                {
                    // t1 is the intersection, and it's closer than t2
                    // (since t1 uses -b - discriminant)
                    // Impale, Poke
                    outp.Add(getRotation(CirclePosition, LocationManager.moveByRotation(line[0], t1 * LocationManager.getDistance(line[0], line[1]), LocationManager.getRotation(line[0], line[1]))));
                    if (t2 >= 0 && t2 <= 1)
                    {
                        outp.Add(getRotation(CirclePosition, LocationManager.moveByRotation(line[0], t2 * LocationManager.getDistance(line[0], line[1]), LocationManager.getRotation(line[0], line[1]))));
                    }
                    //return true;
                }

                // here t1 didn't intersect so we are either started
                // inside the sphere or completely past it
                if (t2 >= 0 && t2 <= 1)
                {
                    outp.Add(getRotation(CirclePosition, LocationManager.moveByRotation(line[0], t2 * LocationManager.getDistance(line[0], line[1]), LocationManager.getRotation(line[0], line[1]))));
                }

                // no intn: FallShort, Past, CompletelyInside
            }
            return(outp);
        }
Example #9
0
 public static Vector2 ConvertToMA(Vector2 v)
 {
     return(new Vector2(LocationManager.getDistance(Vector2.Zero, v), (float)Math.Atan2(v.Y, v.X)));
 }
Example #10
0
        public static bool DoSingleColision_Debug(Polygon MovingPoly, Polygon StationaryPoly, Velocity velocity, List <Vector2[]> lines, List <Color> linecolors)
        {
            Vector2[][] MovingLines     = new Vector2[MovingPoly.NumberOfSides()][];
            Vector2[][] StationaryLines = new Vector2[StationaryPoly.NumberOfSides()][];
            bool        doWork          = false;

            for (int i = 0; i < MovingLines.Length; i++)
            {
                MovingLines[i] = new Vector2[] { velocity.Move(MovingPoly.GetCorner(i), -1f), velocity.Move(MovingPoly.GetCorner(i), 1f) };
                lines.Add(MovingLines[i]);
                linecolors.Add(Color.Blue);
                if (!doWork && LocationManager.getBounds(MovingLines[i]).Intersects(StationaryPoly.Bounds))
                {
                    doWork = true;
                }
            }
            for (int i = 0; i < StationaryLines.Length; i++)
            {
                StationaryLines[i] = new Vector2[] { velocity.Move(StationaryPoly.GetCorner(i), -1f), velocity.Move(StationaryPoly.GetCorner(i), 1f) };
                lines.Add(StationaryLines[i]);
                linecolors.Add(Color.Green);
                if (!doWork && LocationManager.getBounds(StationaryLines[i]).Intersects(MovingPoly.Bounds))
                {
                    doWork = true;
                }
            }
            if (!doWork)
            {
                foreach (Vector2[] v in LocationManager.RectangleEdges(MovingPoly.Bounds))
                {
                    lines.Add(v);
                    linecolors.Add(Color.Yellow);
                }
                foreach (Vector2[] v in LocationManager.RectangleEdges(StationaryPoly.Bounds))
                {
                    lines.Add(v);
                    linecolors.Add(Color.Yellow);
                }
                return(false);
            }

            int     lowindex     = -1;
            int     otherindex   = -1;
            float   lowdistance  = 0;
            bool    movingcloser = false;
            Vector2 intersect    = new Vector2();

            for (int i = 0; i < MovingLines.Length; i++)
            {
                for (int i2 = 0; i2 < StationaryLines.Length; i2++)
                {
                    Vector2?V2 = LocationManager.getIntersectionPoint(StationaryPoly.GetEdge(i2), MovingLines[i]);
                    if (V2.HasValue)
                    {
                        if (lowindex == -1 || LocationManager.distanceCheck(V2.Value, MovingLines[i][0], lowdistance))
                        {
                            lowdistance  = LocationManager.getDistance(V2.Value, MovingLines[i][0]);
                            lowindex     = i;
                            otherindex   = i2;
                            movingcloser = true;
                            intersect    = V2.Value;
                        }
                    }
                }
            }
            for (int i = 0; i < StationaryLines.Length; i++)
            {
                for (int i2 = 0; i2 < MovingLines.Length; i2++)
                {
                    Vector2?V2 = LocationManager.getIntersectionPoint(MovingPoly.GetEdge(i2), StationaryLines[i]);
                    if (V2.HasValue)
                    {
                        //Console.Out.WriteLine("Intersection at {0}::{1} => Point at {2}", MovingPoly.GetEdge(i2)[0] + "," + MovingPoly.GetEdge(i2)[1], StationaryLines[i][0] + "," + StationaryLines[i][1], V2.Value);
                        if (lowindex == -1 || LocationManager.distanceCheck(V2.Value, StationaryLines[i][1], lowdistance))
                        {
                            lowdistance  = velocity.M - LocationManager.getDistance(V2.Value, StationaryLines[i][0]);
                            lowindex     = i;
                            otherindex   = i2;
                            movingcloser = false;
                            intersect    = V2.Value;
                        }
                    }
                }
            }

            if (lowindex != -1)
            {
                Velocity AddToVelocity = new Velocity();
                if (movingcloser)
                {
                    float angle = LocationManager.getRotation(intersect, LocationManager.getReflectionLine(MovingLines[lowindex], StationaryPoly.GetEdge(otherindex))[1]);
                    AddToVelocity.A = angle;
                    AddToVelocity.M = velocity.M;
                    lines.Add(new Vector2[] { MovingLines[lowindex][0], MovingLines[lowindex][1] });
                    linecolors.Add(Color.Red);
                }
                else
                {
                    float angle = LocationManager.getRotation(intersect, LocationManager.getReflectionLine(StationaryLines[lowindex], MovingPoly.GetEdge(otherindex))[1]);
                    AddToVelocity.A = angle;
                    AddToVelocity.M = velocity.M;
                    lines.Add(new Vector2[] { StationaryLines[lowindex][0], StationaryLines[lowindex][1] });
                    linecolors.Add(Color.Red);
                }

                velocity.X = AddToVelocity.X;
                velocity.Y = AddToVelocity.Y;

                MovingPoly.Position = LocationManager.moveByRotation(MovingPoly.Position, lowdistance, velocity.A);
                return(true);
            }
            return(false);
        }
Example #11
0
        public static bool TryTurn_Debug(Polygon myPoly, Polygon StationaryPoly, ref float amt, List <Vector2[]> lines, List <Color> linecolors)
        {
            Vector2 CircleCenter = myPoly.Position;

            Pair <float, bool, float>[] distances;
            float greatestMine = 0;
            float lowestOther  = -1;
            ArrayBuilder <Pair <float, bool, float> > build = new ArrayBuilder <Pair <float, bool, float> >(myPoly.NumberOfSides() + StationaryPoly.NumberOfSides());

            for (int x = 0; x < myPoly.NumberOfSides(); x++)
            {
                float next = LocationManager.getDistance(CircleCenter, myPoly.GetCorner(x));
                build.Add(new Pair <float, bool, float>(next, true, LocationManager.getRotation(CircleCenter, myPoly.GetCorner(x))));
                if (next > greatestMine)
                {
                    greatestMine = next;
                }
            }
            for (int x = 0; x < StationaryPoly.NumberOfSides(); x++)
            {
                float next = LocationManager.getDistance(CircleCenter, StationaryPoly.GetCorner(x));
                build.Add(new Pair <float, bool, float>(next, false, LocationManager.getRotation(CircleCenter, StationaryPoly.GetCorner(x))));
                if (lowestOther == -1 || next < lowestOther)
                {
                    lowestOther = next;
                }
            }
            distances = build.Finish();
            float currentMin = amt;

            for (int i = 0; i < distances.Length; i++)
            {
                for (int i2 = 0; i2 < (distances[i].second ? StationaryPoly.NumberOfSides() : myPoly.NumberOfSides()); i2++)
                {
                    Vector2[] line     = (distances[i].second ? StationaryPoly.GetEdge(i2) : myPoly.GetEdge(i2));
                    float     minAngle = distances[i].third;
                    foreach (float f in LocationManager.CircleIntersects_A(line, CircleCenter, distances[i].first))
                    {
                        lines.Add(new Vector2[] { Vector2.Add(new Vector2(-2, 0), LocationManager.moveByRotation(CircleCenter, distances[i].first, f)), Vector2.Add(new Vector2(2, 0), LocationManager.moveByRotation(CircleCenter, distances[i].first, f)) });
                        linecolors.Add(Color.Red);
                        lines.Add(new Vector2[] { Vector2.Add(new Vector2(0, -2), LocationManager.moveByRotation(CircleCenter, distances[i].first, f)), Vector2.Add(new Vector2(0, 2), LocationManager.moveByRotation(CircleCenter, distances[i].first, f)) });
                        linecolors.Add(Color.Red);
                        if (amt > 0)
                        {
                            if (f > minAngle && LocationManager.NormalRelitiveAngle(minAngle, f) < amt)
                            {
                                lines.Add(new Vector2[] { Vector2.Add(new Vector2(-8, 0), LocationManager.moveByRotation(CircleCenter, distances[i].first, f)), Vector2.Add(new Vector2(8, 0), LocationManager.moveByRotation(CircleCenter, distances[i].first, f)) });
                                linecolors.Add(Color.Blue);
                                lines.Add(new Vector2[] { Vector2.Add(new Vector2(0, -8), LocationManager.moveByRotation(CircleCenter, distances[i].first, f)), Vector2.Add(new Vector2(0, 8), LocationManager.moveByRotation(CircleCenter, distances[i].first, f)) });
                                linecolors.Add(Color.Blue);
                            }
                            if (f > (minAngle) && LocationManager.NormalRelitiveAngle(minAngle, f) < currentMin)
                            {
                                currentMin = LocationManager.NormalRelitiveAngle(minAngle, f);
                            }
                        }
                        else if (amt < 0)
                        {
                            if (f < minAngle && LocationManager.NormalRelitiveAngle(f, minAngle) < -amt)
                            {
                                lines.Add(new Vector2[] { Vector2.Add(new Vector2(-8, 0), LocationManager.moveByRotation(CircleCenter, distances[i].first, f)), Vector2.Add(new Vector2(8, 0), LocationManager.moveByRotation(CircleCenter, distances[i].first, f)) });
                                linecolors.Add(Color.Blue);
                                lines.Add(new Vector2[] { Vector2.Add(new Vector2(0, -8), LocationManager.moveByRotation(CircleCenter, distances[i].first, f)), Vector2.Add(new Vector2(0, 8), LocationManager.moveByRotation(CircleCenter, distances[i].first, f)) });
                                linecolors.Add(Color.Blue);
                            }
                            if (f < minAngle && LocationManager.NormalRelitiveAngle(f, minAngle) < -currentMin)
                            {
                                currentMin = LocationManager.NormalRelitiveAngle(f, minAngle);
                            }
                        }
                    }
                }
            }
            if (currentMin == amt)
            {
                myPoly.Rotation += amt;
                return(false);
            }
            else
            {
                myPoly.Rotation += currentMin * .9f;
                amt             *= -.9f;
                return(true);
            }
        }
Example #12
0
        public static bool DoSingleColision(Polygon MovingPoly, Polygon StationaryPoly, ref Vector2 velocity, bool isMA)
        {
            if (!isMA)
            {
                velocity = Physics.ConvertToMA(velocity);
            }
            Vector2[][] MovingLines     = new Vector2[MovingPoly.NumberOfSides()][];
            Vector2[][] StationaryLines = new Vector2[StationaryPoly.NumberOfSides()][];

            for (int i = 0; i < MovingLines.Length; i++)
            {
                MovingLines[i] = new Vector2[] { LocationManager.moveByRotation(MovingPoly.GetCorner(i), -velocity.X, velocity.Y), LocationManager.moveByRotation(MovingPoly.GetCorner(i), velocity.X, velocity.Y) };
            }
            for (int i = 0; i < StationaryLines.Length; i++)
            {
                StationaryLines[i] = new Vector2[] { /*StationaryPoly.GetCorner(i)*/ LocationManager.moveByRotation(StationaryPoly.GetCorner(i), velocity.X, velocity.Y), LocationManager.moveByRotation(StationaryPoly.GetCorner(i), -velocity.X, velocity.Y) };
            }

            int     lowindex     = -1;
            int     otherindex   = -1;
            float   lowdistance  = 0;
            bool    movingcloser = false;
            Vector2 intersect    = new Vector2();

            for (int i = 0; i < MovingLines.Length; i++)
            {
                for (int i2 = 0; i2 < StationaryLines.Length; i2++)
                {
                    Vector2?V2 = LocationManager.getIntersectionPoint(StationaryPoly.GetEdge(i2), MovingLines[i]);
                    if (V2.HasValue)
                    {
                        if (lowindex == -1 || LocationManager.distanceCheck(V2.Value, MovingLines[i][0], lowdistance))
                        {
                            lowdistance  = LocationManager.getDistance(V2.Value, MovingLines[i][0]);
                            lowindex     = i;
                            otherindex   = i2;
                            movingcloser = true;
                            intersect    = V2.Value;
                        }
                    }
                }
            }
            for (int i = 0; i < StationaryLines.Length; i++)
            {
                for (int i2 = 0; i2 < MovingLines.Length; i2++)
                {
                    Vector2?V2 = LocationManager.getIntersectionPoint(MovingPoly.GetEdge(i2), StationaryLines[i]);
                    if (V2.HasValue)
                    {
                        //Console.Out.WriteLine("Intersection at {0}::{1} => Point at {2}", MovingPoly.GetEdge(i2)[0] + "," + MovingPoly.GetEdge(i2)[1], StationaryLines[i][0] + "," + StationaryLines[i][1], V2.Value);
                        if (lowindex == -1 || LocationManager.distanceCheck(V2.Value, StationaryLines[i][1], lowdistance))
                        {
                            lowdistance  = velocity.X - LocationManager.getDistance(V2.Value, StationaryLines[i][0]);
                            lowindex     = i;
                            otherindex   = i2;
                            movingcloser = false;
                            intersect    = V2.Value;
                        }
                    }
                }
            }

            if (lowindex != -1)
            {
                //Console.Out.WriteLine("Colis=> Lowindex: {0}, distance: {1}, whose:{2}", lowindex, lowdistance, movingcloser);
                Vector2 AddToVelocity = new Vector2();
                if (movingcloser)
                {
                    float angle = LocationManager.getRotation(intersect, LocationManager.getReflectionLine(MovingLines[lowindex], StationaryPoly.GetEdge(otherindex))[1]);
                    AddToVelocity.Y = angle;
                    AddToVelocity.X = velocity.X;
                }
                else
                {
                    float angle = LocationManager.getRotation(intersect, LocationManager.getReflectionLine(StationaryLines[lowindex], MovingPoly.GetEdge(otherindex))[1]);
                    AddToVelocity.Y = angle;
                    AddToVelocity.X = -velocity.X;
                }
                velocity            = AddToVelocity;
                MovingPoly.Position = LocationManager.moveByRotation(MovingPoly.Position, lowdistance - .4f, velocity.Y);
                if (!isMA)
                {
                    velocity = Physics.ConvertToXY(velocity);
                }
                return(true);
            }
            if (!isMA)
            {
                velocity = Physics.ConvertToXY(velocity);
            }
            return(false);
        }