예제 #1
0
        /// <summary>
        /// Gets an array of colision data including both polygon lines and the actual intersect point
        /// </summary>
        /// <param name="p"></param>
        /// <returns>[TgtLineStart, TgtLineEnd, MyLineStart, MyLineEnd, IntersectionPoint]</returns>
        public Vector2[] CheckColisions_Accurate_GetLine(Polygon p)
        {
            Vector2[] myCorners    = GetCorners();
            Vector2[] otherCorners = p.GetCorners();
            for (int i = 0; i < myCorners.Length; i++)
            {
                for (int i2 = 0; i2 < otherCorners.Length; i2++)
                {
                    if (LocationManager.linesIntersect(myCorners[i], myCorners[(i + 1) % myCorners.Length], otherCorners[i2], otherCorners[(i2 + 1) % otherCorners.Length]))
                    {
                        return new Vector2[] { otherCorners[i2], otherCorners[(i2 + 1) % otherCorners.Length], myCorners[i], myCorners[(i + 1) % myCorners.Length], LocationManager.getIntersectionPoint(myCorners[i], myCorners[(i + 1) % myCorners.Length], otherCorners[i2], otherCorners[(i2 + 1) % otherCorners.Length]).Value }
                    }
                    ;
                }
            }

            return(null);
        }
예제 #2
0
파일: Camera.cs 프로젝트: Jeffersah/FP1
        /// <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);
            }
        }
예제 #3
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);
        }
예제 #4
0
        /// <summary>
        /// Checks if a line intersects a circle and returns all intersection positions
        /// </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 List <Vector2> CircleIntersects_V(Vector2[] line, Vector2 CirclePosition, float CircleRadius)
        {
            List <Vector2> outp = new List <Vector2>();
            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)
                {
                    outp.Add(LocationManager.moveByRotation(line[0], t1 * LocationManager.getDistance(line[0], line[1]), LocationManager.getRotation(line[0], line[1])));
                    if (t2 >= 0 && t2 <= 1)
                    {
                        outp.Add(LocationManager.moveByRotation(line[0], t2 * LocationManager.getDistance(line[0], line[1]), LocationManager.getRotation(line[0], line[1])));
                    }
                }

                if (t2 >= 0 && t2 <= 1)
                {
                    outp.Add(LocationManager.moveByRotation(line[0], t2 * LocationManager.getDistance(line[0], line[1]), LocationManager.getRotation(line[0], line[1])));
                }
            }
            return(outp);
        }
예제 #5
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);
        }
예제 #6
0
 public Vector2[] RelativeLine(Vector2[] GlobalLine, Vector2 Position, float CurrentRotation)
 {
     return(new Vector2[] { LocationManager.TransformAround(Position, GlobalLine[0], CurrentRotation) - Position,
                            LocationManager.TransformAround(Position, GlobalLine[1], CurrentRotation) - Position });
 }
예제 #7
0
파일: Physics.cs 프로젝트: Jeffersah/FP1
 public static Vector2 ConvertToMA(Vector2 v)
 {
     return(new Vector2(LocationManager.getDistance(Vector2.Zero, v), (float)Math.Atan2(v.Y, v.X)));
 }
예제 #8
0
파일: Camera.cs 프로젝트: Jeffersah/FP1
        /// <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);
        }
예제 #9
0
        public bool VelocityColision(Polygon moving, Polygon stationary, Vector2 velocity)
        {
            Rectangle roughBounds = moving.Bounds;

            roughBounds.Width  += (int)Math.Ceiling(Math.Abs(velocity.X));
            roughBounds.Height += (int)Math.Ceiling(Math.Abs(velocity.Y));
            if (velocity.X < 0)
            {
                roughBounds.X += (int)Math.Ceiling(velocity.X);
            }
            if (velocity.Y < 0)
            {
                roughBounds.Y += (int)Math.Ceiling(velocity.Y);
            }
            debug_bounds = roughBounds;
            if (!roughBounds.Intersects(stationary.Bounds))
            {
                return(false);
            }

            float MV  = Physics.ConvertToMA(velocity).X;
            float MV2 = MV * MV;

            List <Vector2[]> movingLines     = new List <Vector2[]>();
            List <Vector2[]> stationaryLines = new List <Vector2[]>();

            for (int i = 0; i < moving.NumberOfSides(); i++)
            {
                movingLines.Add(new Vector2[] { moving.GetCorner(i), Vector2.Add(moving.GetCorner(i), velocity) });
            }

            for (int i = 0; i < stationary.NumberOfSides(); i++)
            {
                stationaryLines.Add(new Vector2[] { Vector2.Subtract(stationary.GetCorner(i), velocity), stationary.GetCorner(i) });
            }
            float maxMove = (velocity.X * velocity.X) + (velocity.Y * velocity.Y);
            bool  colid   = false;

            for (int i = 0; i < movingLines.Count; i++)
            {
                foreach (Vector2 [] edge in stationary.GetEdges())
                {
                    Vector2?Colision = LocationManager.getIntersectionPoint(movingLines[i], edge);
                    switch (LocationManager.LinesIntersect_Precise(movingLines[i], edge))
                    {
                    case 1:
                        if (Colision.HasValue)
                        {
                            float newdist = LocationManager.getDistanceSquared(movingLines[i][0], Colision.Value);
                            if (newdist < maxMove)
                            {
                                maxMove = newdist;
                            }
                            colid   = true;
                            HITEDGE = edge;
                        }
                        else
                        {
                            Console.Out.WriteLine("? ? ? ?");
                        }
                        break;

                    case 2:
                        Cot = new Vector2[2][] { movingLines[i], edge };
                        Vector2[] edgecheck = new Vector2[] { movingLines[i][0], Vector2.Add(movingLines[i][0], Vector2.Multiply(velocity, 100000)) };
                        int       hitcount  = 0;
                        foreach (Vector2[] ec2 in stationary.GetEdges())
                        {
                            if (LocationManager.LinesIntersect_Precise(ec2, edgecheck) == 1)
                            {
                                hitcount++;
                            }
                        }
                        if (hitcount % 2 == 0)
                        {
                        }
                        else
                        {
                            if (Colision.HasValue)
                            {
                                float newdist = LocationManager.getDistanceSquared(movingLines[i][0], Colision.Value);
                                if (newdist < maxMove)
                                {
                                    maxMove = newdist;
                                }
                                colid   = true;
                                HITEDGE = edge;
                            }
                            else
                            {
                                Console.Out.WriteLine("? ? ? ?");
                            }
                        }
                        break;

                    default:
                    case 0:
                        break;
                    }
                }
            }

            for (int i = 0; i < stationaryLines.Count; i++)
            {
                foreach (Vector2[] edge in moving.GetEdges())
                {
                    Vector2?Colision = LocationManager.getIntersectionPoint(stationaryLines[i], edge);
                    switch (LocationManager.LinesIntersect_Precise(stationaryLines[i], edge))
                    {
                    case 1:
                        if (Colision.HasValue)
                        {
                            float newdist = MV2 - LocationManager.getDistanceSquared(stationaryLines[i][0], Colision.Value);
                            if (newdist < maxMove)
                            {
                                maxMove = newdist;
                            }
                            colid   = true;
                            HITEDGE = edge;
                        }
                        else
                        {
                            Console.Out.WriteLine("? ? ? ?");
                        }
                        break;

                    case 2:
                        Cot = new Vector2[2][] { stationaryLines[i], edge };
                        Vector2[] edgecheck = new Vector2[] { stationaryLines[i][0], Vector2.Add(stationaryLines[i][0], Vector2.Multiply(velocity, 100000)) };
                        int       hitcount  = 0;
                        foreach (Vector2[] ec2 in moving.GetEdges())
                        {
                            if (LocationManager.LinesIntersect_Precise(ec2, edgecheck) == 1)
                            {
                                hitcount++;
                            }
                        }
                        if (hitcount % 2 == 0)
                        {
                        }
                        else
                        {
                            if (Colision.HasValue)
                            {
                                float newdist = MV2 - LocationManager.getDistanceSquared(stationaryLines[i][0], Colision.Value);
                                if (newdist < maxMove)
                                {
                                    maxMove = newdist;
                                }
                                colid   = true;
                                HITEDGE = edge;
                            }
                            else
                            {
                                Console.Out.WriteLine("? ? ? ?");
                            }
                        }
                        break;

                    default:
                    case 0:
                        break;
                    }
                }
            }

            if (colid)
            {
                maxV = (float)Math.Sqrt(maxMove) / MV;
                return(true);
            }

            debug_AllLines = new List <Vector2[]>();
            debug_AllLines.AddRange(movingLines);
            debug_AllLines.AddRange(stationaryLines);

            return(false);
        }
예제 #10
0
 /// <summary>
 /// Centers the camera on a given vector
 /// </summary>
 /// <param name="p"></param>
 public void Center(Vector2 p)
 {
     Center(LocationManager.getPointFromVector(p));
 }
예제 #11
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)));
            }
        }
예제 #12
0
        protected static bool[,] ScanOctant(Point Source, bool[,] World, bool[,] Ret, int pDepth, int pOctant, double pStartSlope, double pEndSlope, int range)
        {
            int visrange2 = range * range;
            int x         = 0;
            int y         = 0;

            switch (pOctant)
            {
            case 1:     //nnw // 0, -1
                // -1, 0
                y = Source.Y - pDepth;
                if (y < 0)
                {
                    return(Ret);
                }

                x = Source.X - Convert.ToInt32((pStartSlope * Convert.ToDouble(pDepth)));
                if (x < 0)
                {
                    x = 0;
                }

                while (GetSlope(x, y, Source.X, Source.Y, false) >= pEndSlope)
                {
                    if (LocationManager.distanceCheck(LocationManager.getVectorFromPoint(Source), new Vector2(x, y), range))
                    {
                        Ret[x, y] = true;
                        if (World[x, y])                        //current cell blocked
                        {
                            if (x - 1 >= 0 && !World[x - 1, y]) //prior cell within range AND open...
                            //...incremenet the depth, adjust the endslope and recurse
                            {
                                ScanOctant(Source, World, Ret, pDepth + 1, pOctant, pStartSlope, GetSlope(x - 0.5, y + 0.5, Source.X, Source.Y, false), range);
                            }
                        }
                        else
                        {
                            if (x - 1 >= 0 && World[x - 1, y])     //prior cell within range AND open...
                            //..adjust the startslope
                            {
                                pStartSlope = GetSlope(x - 0.5, y - 0.5, Source.X, Source.Y, false);
                            }
                        }
                    }
                    x++;
                }
                x--;
                break;

            case 2:     //nne

                y = Source.Y - pDepth;
                if (y < 0)
                {
                    return(Ret);
                }

                x = Source.X + Convert.ToInt32((pStartSlope * Convert.ToDouble(pDepth)));
                if (x >= World.GetLength(0))
                {
                    x = World.GetLength(0) - 1;
                }

                while (GetSlope(x, y, Source.X, Source.Y, false) <= pEndSlope)
                {
                    if (GetVisDistance(x, y, Source.X, Source.Y) <= visrange2)
                    {
                        Ret[x, y] = true;
                        if (World[x, y])
                        {
                            if (x + 1 < World.GetLength(0) && !World[x + 1, y])
                            {
                                ScanOctant(Source, World, Ret, pDepth + 1, pOctant, pStartSlope, GetSlope(x + 0.5, y + 0.5, Source.X, Source.Y, false), range);
                            }
                        }
                        else
                        {
                            if (x + 1 < World.GetLength(0) && World[x + 1, y])
                            {
                                pStartSlope = -GetSlope(x + 0.5, y - 0.5, Source.X, Source.Y, false);
                            }
                        }
                    }
                    x--;
                }
                x++;
                break;

            case 3:

                x = Source.X + pDepth;
                if (x >= World.GetLength(0))
                {
                    return(Ret);
                }

                y = Source.Y - Convert.ToInt32((pStartSlope * Convert.ToDouble(pDepth)));
                if (y < 0)
                {
                    y = 0;
                }

                while (GetSlope(x, y, Source.X, Source.Y, true) <= pEndSlope)
                {
                    if (GetVisDistance(x, y, Source.X, Source.Y) <= visrange2)
                    {
                        Ret[x, y] = true;
                        if (World[x, y])
                        {
                            if (y - 1 >= 0 && !World[x, y - 1])
                            {
                                ScanOctant(Source, World, Ret, pDepth + 1, pOctant, pStartSlope, GetSlope(x - 0.5, y - 0.5, Source.X, Source.Y, true), range);
                            }
                        }
                        else
                        {
                            if (y - 1 >= 0 && World[x, y - 1])
                            {
                                pStartSlope = -GetSlope(x + 0.5, y - 0.5, Source.X, Source.Y, true);
                            }
                        }
                    }
                    y++;
                }
                y--;
                break;

            case 4:

                x = Source.X + pDepth;
                if (x >= World.GetLength(0))
                {
                    return(Ret);
                }

                y = Source.Y + Convert.ToInt32((pStartSlope * Convert.ToDouble(pDepth)));
                if (y >= World.GetLength(1))
                {
                    y = World.GetLength(1) - 1;
                }

                while (GetSlope(x, y, Source.X, Source.Y, true) >= pEndSlope)
                {
                    if (GetVisDistance(x, y, Source.X, Source.Y) <= visrange2)
                    {
                        Ret[x, y] = true;
                        if (World[x, y])
                        {
                            if (y + 1 < World.GetLength(1) && !World[x, y + 1])
                            {
                                ScanOctant(Source, World, Ret, pDepth + 1, pOctant, pStartSlope, GetSlope(x - 0.5, y + 0.5, Source.X, Source.Y, true), range);
                            }
                        }
                        else
                        {
                            if (y + 1 < World.GetLength(1) && World[x, y + 1])
                            {
                                pStartSlope = GetSlope(x + 0.5, y + 0.5, Source.X, Source.Y, true);
                            }
                        }
                    }
                    y--;
                }
                y++;
                break;

            case 5:

                y = Source.Y + pDepth;
                if (y >= World.GetLength(1))
                {
                    return(Ret);
                }

                x = Source.X + Convert.ToInt32((pStartSlope * Convert.ToDouble(pDepth)));
                if (x >= World.GetLength(0))
                {
                    x = World.GetLength(0) - 1;
                }

                while (GetSlope(x, y, Source.X, Source.Y, false) >= pEndSlope)
                {
                    if (GetVisDistance(x, y, Source.X, Source.Y) <= visrange2)
                    {
                        Ret[x, y] = true;
                        if (World[x, y])
                        {
                            if (x + 1 < World.GetLength(1) && !World[x + 1, y])
                            {
                                ScanOctant(Source, World, Ret, pDepth + 1, pOctant, pStartSlope, GetSlope(x + 0.5, y - 0.5, Source.X, Source.Y, false), range);
                            }
                        }
                        else
                        {
                            if (x + 1 < World.GetLength(1) &&
                                World[x + 1, y])
                            {
                                pStartSlope = GetSlope(x + 0.5, y + 0.5, Source.X, Source.Y, false);
                            }
                        }
                    }
                    x--;
                }
                x++;
                break;

            case 6:

                y = Source.Y + pDepth;
                if (y >= World.GetLength(1))
                {
                    return(Ret);
                }

                x = Source.X - Convert.ToInt32((pStartSlope * Convert.ToDouble(pDepth)));
                if (x < 0)
                {
                    x = 0;
                }

                while (GetSlope(x, y, Source.X, Source.Y, false) <= pEndSlope)
                {
                    if (GetVisDistance(x, y, Source.X, Source.Y) <= visrange2)
                    {
                        Ret[x, y] = true;
                        if (World[x, y])
                        {
                            if (x - 1 >= 0 && !World[x - 1, y])
                            {
                                ScanOctant(Source, World, Ret, pDepth + 1, pOctant, pStartSlope, GetSlope(x - 0.5, y - 0.5, Source.X, Source.Y, false), range);
                            }
                        }
                        else
                        {
                            if (x - 1 >= 0 &&
                                World[x - 1, y])
                            {
                                pStartSlope = -GetSlope(x - 0.5, y + 0.5, Source.X, Source.Y, false);
                            }
                        }
                    }
                    x++;
                }
                x--;
                break;

            case 7:

                x = Source.X - pDepth;
                if (x < 0)
                {
                    return(Ret);
                }

                y = Source.Y + Convert.ToInt32((pStartSlope * Convert.ToDouble(pDepth)));
                if (y >= World.GetLength(1))
                {
                    y = World.GetLength(1) - 1;
                }

                while (GetSlope(x, y, Source.X, Source.Y, true) <= pEndSlope)
                {
                    if (GetVisDistance(x, y, Source.X, Source.Y) <= visrange2)
                    {
                        Ret[x, y] = true;
                        if (World[x, y])
                        {
                            if (y + 1 < World.GetLength(1) && !World[x, y + 1])
                            {
                                ScanOctant(Source, World, Ret, pDepth + 1, pOctant, pStartSlope, GetSlope(x + 0.5, y + 0.5, Source.X, Source.Y, true), range);
                            }
                        }
                        else
                        {
                            if (y + 1 < World.GetLength(1) && World[x, y + 1])
                            {
                                pStartSlope = -GetSlope(x - 0.5, y + 0.5, Source.X, Source.Y, true);
                            }
                        }
                    }
                    y--;
                }
                y++;
                break;

            case 8:     //wnw

                x = Source.X - pDepth;
                if (x < 0)
                {
                    return(Ret);
                }

                y = Source.Y - Convert.ToInt32((pStartSlope * Convert.ToDouble(pDepth)));
                if (y < 0)
                {
                    y = 0;
                }

                while (GetSlope(x, y, Source.X, Source.Y, true) >= pEndSlope)
                {
                    if (GetVisDistance(x, y, Source.X, Source.Y) <= visrange2)
                    {
                        Ret[x, y] = true;
                        if (World[x, y])
                        {
                            if (y - 1 >= 0 && !World[x, y - 1])
                            {
                                ScanOctant(Source, World, Ret, pDepth + 1, pOctant, pStartSlope, GetSlope(x + 0.5, y - 0.5, Source.X, Source.Y, true), range);
                            }
                        }
                        else
                        {
                            if (y - 1 >= 0 && World[x, y - 1])
                            {
                                pStartSlope = GetSlope(x - 0.5, y - 0.5, Source.X, Source.Y, true);
                            }
                        }
                    }
                    y++;
                }
                y--;
                break;
            }

            if (x < 0)
            {
                x = 0;
            }
            else if (x >= World.GetLength(0))
            {
                x = World.GetLength(0) - 1;
            }

            if (y < 0)
            {
                y = 0;
            }
            else if (y >= World.GetLength(1))
            {
                y = World.GetLength(1) - 1;
            }

            if (pDepth < range & !World[x, y])
            {
                ScanOctant(Source, World, Ret, pDepth + 1, pOctant, pStartSlope, pEndSlope, range);
            }
            return(Ret);
        }
예제 #13
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);
        }
예제 #14
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);
            }
        }
예제 #15
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);
        }
예제 #16
0
 /// <summary>
 /// Converts a rectangle into an equivalent polygon
 /// </summary>
 /// <param name="r"></param>
 /// <returns></returns>
 public static Polygon GetFromRectangle(Rectangle r)
 {
     Polygon tmp = new Polygon(UNIT_SQUARE(), LocationManager.getVectorFromPoint(r.Center), 0);
     tmp.Scale(r.Width, r.Height);
     return tmp;
 }