예제 #1
0
 public Polygon(Polygon p)
 {
     foreach (Vector2 point in p.Points)
     {
         m_Points.Add(point);
     }
     BuildEdges();
     CalculateMaxMin();
 }
예제 #2
0
파일: Camera.cs 프로젝트: opcon/Substructio
        /// <summary>
        /// The default Constructor.
        /// </summary>
        public Camera(float prefWidth, float prefHeight, float windowWidth, float windowHeight, MouseDevice m)
        {
            OriginalBounds = CameraBounds = new Polygon();
            TargetScale = Scale = new Vector2(1f, 1f);
            MinimumScale = new Vector2(0.5f, 0.5f);
            MaximumScale = new Vector2(20, 20);
            CameraBox = new Polygon();
            Mouse = m;
            PreferredWidth = prefWidth;
            PreferredHeight = prefHeight;
            UpdateResize(windowWidth, windowHeight);


            UpdateProjectionMatrix();
        }
예제 #3
0
 // Calculate the projection of a polygon on an axis and returns it as a [min, max] interval
 public static void ProjectPolygon(Vector2 axis, Polygon polygon, ref float min, ref float max)
 {
     // To project a point on an axis use the dot product
     float d = Vector2.Dot(axis, polygon.Points[0]);
     min = d;
     max = d;
     foreach (Vector2 t in polygon.Points)
     {
         d = Vector2.Dot(t, axis);
         if (d < min)
         {
             min = d;
         }
         else
         {
             if (d > max)
             {
                 max = d;
             }
         }
     }
 }
예제 #4
0
        // Structure that stores the results of the PolygonCollision function

        // Check if polygon A is going to collide with polygon B for the given velocity
        public static PolygonCollisionResult PolygonCollision(Polygon polygonA, Polygon polygonB, Vector2 velocity)
        {
            var result = new PolygonCollisionResult {Intersect = true, WillIntersect = true};

            int edgeCountA = polygonA.Edges.Count;
            int edgeCountB = polygonB.Edges.Count;
            float minIntervalDistance = float.PositiveInfinity;
            var translationAxis = new Vector2();
            Vector2 edge;

            // Loop through all the edges of both polygons
            for (int edgeIndex = 0; edgeIndex < edgeCountA + edgeCountB; edgeIndex++)
            {
                edge = edgeIndex < edgeCountA ? polygonA.Edges[edgeIndex] : polygonB.Edges[edgeIndex - edgeCountA];

                // ===== 1. Find if the polygons are currently intersecting =====

                // Find the axis perpendicular to the current edge
                var axis = new Vector2(-edge.Y, edge.X);
                axis.Normalize();

                // Find the projection of the polygon on the current axis
                float minA = 0;
                float minB = 0;
                float maxA = 0;
                float maxB = 0;
                ProjectPolygon(axis, polygonA, ref minA, ref maxA);
                ProjectPolygon(axis, polygonB, ref minB, ref maxB);

                // Check if the polygon projections are currentlty intersecting
                if (IntervalDistance(minA, maxA, minB, maxB) > 0) result.Intersect = false;

                // ===== 2. Now find if the polygons *will* intersect =====

                // Project the velocity on the current axis
                float velocityProjection = Vector2.Dot(axis, velocity);

                // Get the projection of polygon A during the movement
                if (velocityProjection < 0)
                {
                    minA += velocityProjection;
                }
                else
                {
                    maxA += velocityProjection;
                }

                // Do the same test as above for the new projection
                float intervalDistance = IntervalDistance(minA, maxA, minB, maxB);
                if (intervalDistance > 0) result.WillIntersect = false;

                // If the polygons are not intersecting and won't intersect, exit the loop
                if (!result.Intersect && !result.WillIntersect) break;

                // Check if the current interval distance is the minimum one. If so store
                // the interval distance and the current distance.
                // This will be used to calculate the minimum translation vector
                intervalDistance = System.Math.Abs(intervalDistance);
                if (intervalDistance < minIntervalDistance)
                {
                    minIntervalDistance = intervalDistance;
                    translationAxis = axis;

                    Vector2 d = polygonA.Center - polygonB.Center;
                    if (Vector2.Dot(d, translationAxis) < 0) translationAxis = -translationAxis;
                }
            }

            // The minimum translation vector can be used to push the polygons appart.
            // First moves the polygons by their velocity
            // then move polygonA by MinimumTranslationVector.
            if (result.WillIntersect) result.MinimumTranslationVector = translationAxis*minIntervalDistance;
            result.IntervalDistance = minIntervalDistance;

            return result;
        }
예제 #5
0
 public static PolygonCollisionResult PolygonCollision(Polygon polygonA, Polygon polygonB)
 {
     return PolygonCollision(polygonA, polygonB, Vector2.Zero);
 }
예제 #6
0
 public bool IsIntersecting(Polygon p)
 {
     PolygonCollisionResult polygonCollisionResult = PolygonCollision(this, p);
     return polygonCollisionResult.Intersect;
 }
예제 #7
0
파일: Camera.cs 프로젝트: opcon/Substructio
        private void ClampTranslations()
        {
            GenerateCameraBoundingBox();

            var bbox = new Polygon(CameraBox);
            bbox.Scale(TargetScale);
            bbox.BuildEdges();
            bbox.CalculateMaxMin();

            if (bbox.Width > CameraBounds.Width && CameraBounds.Width >= CameraBounds.Height)
            {
                TargetScale.X = CameraBounds.Width/(PreferredWidth);
            }
            if (bbox.Height > CameraBounds.Height && CameraBounds.Height >= CameraBounds.Width)
            {
                TargetScale.Y = CameraBounds.Height/(PreferredHeight);
            }

            if (TargetScale.Y > TargetScale.X)
            {
                TargetScale.Y = TargetScale.X;
            }
            else if (TargetScale.X > TargetScale.Y)
            {
                TargetScale.X = TargetScale.Y;
            }

            CameraBox.Scale(Scale);

            CameraBox.BuildEdges();
            CameraBox.CalculateMaxMin();

            //Clamp translation values
            if (CameraBox.Max.X > CameraBounds.Max.X)
            {
                TargetWorldTranslation.X += ((CameraBox.Max.X) - CameraBounds.Max.X);
            }
            else if (CameraBox.Min.X < CameraBounds.Min.X)
            {
                TargetWorldTranslation.X += ((CameraBox.Min.X) - CameraBounds.Min.X);
            }

            //Clamp translation values
            if (CameraBox.Max.Y > CameraBounds.Max.Y)
            {
                TargetWorldTranslation.Y += (CameraBox.Max.Y - CameraBounds.Max.Y);
            }
            else if (CameraBox.Min.Y < CameraBounds.Min.Y)
            {
                TargetWorldTranslation.Y += (CameraBox.Min.Y - CameraBounds.Min.Y);
            }
        }