IsPointInside() публичный Метод

public IsPointInside ( Vector2 point ) : bool
point Vector2
Результат bool
Пример #1
0
        /// <summary>
        /// Returns whether this instance collides with the argument Polygon.
        /// </summary>
        /// <param name="polygon">The Polygon to test collision against.</param>
        /// <returns>Whether a collision has occurred.</returns>
        #endregion
        public bool CollideAgainst(Polygon polygon)
        {
            UpdateDependencies(TimeManager.CurrentTime);
            polygon.UpdateDependencies(TimeManager.CurrentTime);

            Point transformedPoint1 = new Point(RelativePoint1.X, RelativePoint1.Y);
            Point transformedPoint2 = new Point(RelativePoint2.X, RelativePoint2.Y);


            FlatRedBall.Math.MathFunctions.TransformPoint(ref transformedPoint1, ref mRotationMatrix);
            FlatRedBall.Math.MathFunctions.TransformPoint(ref transformedPoint2, ref mRotationMatrix);

            Point tp1 = new Point(transformedPoint1.X, transformedPoint1.Y);
            Point tp2 = new Point(transformedPoint2.X, transformedPoint2.Y);

            // Get world-positioned segment
            Segment a = new Segment(
                new Point(Position.X + transformedPoint1.X,
                          Position.Y + transformedPoint1.Y),
                new Point(Position.X + transformedPoint2.X,
                          Position.Y + transformedPoint2.Y));

            // Check if one of the segment's endpoints is inside the Polygon
            if (polygon.IsPointInside(ref tp1, ref Position, ref mIdentityMatrix))
            {
                polygon.mLastCollisionPoint = tp1;
                mLastCollisionPoint         = tp1;
                return(true);
            }
            if (polygon.IsPointInside(ref tp2, ref Position, ref mIdentityMatrix))
            {
                polygon.mLastCollisionPoint = tp2;
                mLastCollisionPoint         = tp2;
                return(true);
            }

            Point intersectionPoint;

            // Check if one of the polygon's edges intersects the line segment
            for (int i = 0; i < polygon.Points.Count - 1; i++)
            {
                int indexAfter = i + 1;

                var point1 = new Point(polygon.Vertices[i].Position.X,
                                       polygon.Vertices[i].Position.Y);

                var point2 = new Point(polygon.Vertices[indexAfter].Position.X,
                                       polygon.Vertices[indexAfter].Position.Y);

                if (a.Intersects(new Segment(point1, point2), out intersectionPoint))
                {
                    mLastCollisionPoint         = intersectionPoint;
                    polygon.mLastCollisionPoint = intersectionPoint;
                    return(true);
                }
            }

            // No collision
            return(false);
        }
        public List <TriangulationPoint> GenerateGridPoints(Bounds bounds, float subdivLevel, Polygon _polygon)
        {
            List <TriangulationPoint> GridPoints = new List <TriangulationPoint>();
            float numberDivisions = 6;

            float width  = bounds.max.x - bounds.min.x;
            float height = bounds.max.y - bounds.min.y;

            float subdivWidth  = width / (subdivLevel * numberDivisions);
            float subdivHeight = height / ((subdivLevel * numberDivisions));

            float averagedLength = (subdivWidth + subdivHeight) / 2;
            float widthHeight    = (width + height) / 2;



            for (int i = 1; i < (subdivLevel * numberDivisions / widthHeight) * width; i++)
            {
                for (int j = 1; j < (subdivLevel * numberDivisions / widthHeight) * height; j++)
                {
                    float xPos           = (i * averagedLength) + bounds.min.x;
                    float yPos           = (j * averagedLength) + bounds.min.y;
                    TriangulationPoint t = new TriangulationPoint(xPos, yPos);
                    if (_polygon.IsPointInside(t))
                    {
                        GridPoints.Add(t);
                    }
                }
            }
            return(GridPoints);
        }
Пример #3
0
        // createFluidBody
        public void createFluidBody(List <Vector2> polygonPoints)
        {
            List <PolygonPoint> P2TPoints = new List <PolygonPoint>();
            Polygon             polygon;
            Vector2             topLeft     = polygonPoints[0];
            Vector2             bottomRight = polygonPoints[0];
            float  spacing = RADIUS / 3.7f;
            Random random  = new Random();

            foreach (Vector2 point in polygonPoints)
            {
                topLeft     = Vector2.Min(topLeft, point);
                bottomRight = Vector2.Max(bottomRight, point);
                P2TPoints.Add(new PolygonPoint(point.X, point.Y));
            }
            polygon = new Polygon(P2TPoints);

            for (float i = topLeft.X; i < bottomRight.X; i += spacing)
            {
                for (float j = topLeft.Y; j < bottomRight.Y; j += spacing)
                {
                    Vector2 jitter = new Vector2(-1 + (float)random.NextDouble() * 2, -1 + (float)random.NextDouble() * 2) * (spacing * 0.2f);
                    Vector2 point  = new Vector2(i, j) + jitter;
                    if (polygon.IsPointInside(new PolygonPoint(point.X, point.Y)))
                    {
                        createParticle(point, Vector2.Zero);
                    }
                }
            }
        }
Пример #4
0
        private static bool FruitPolygonCollision(Fruit fruit, Polygon polygon, CCPoint polygonVelocity)
        {
            bool didCollide = polygon.CollideAgainst(fruit.Collision);

            if (didCollide)
            {
                bool isCircleCenterInPolygon = polygon.IsPointInside(
                    fruit.PositionWorldspace.X, fruit.PositionWorldspace.Y);

                float distance;
                var   normal = polygon.GetNormalClosestTo(fruit.PositionWorldspace, out distance);

                if (isCircleCenterInPolygon)
                {
                    distance += fruit.Radius;
                }
                else
                {
                    distance = fruit.Radius - distance;
                }

                // increase the distance by a small amount to make sure that the objects do separate:
                distance += .5f;

                fruit.Position += normal * distance;

                fruit.Velocity = ApplyBounce(fruit.Velocity, polygonVelocity, normal, GameCoefficients.FruitCollisionElasticity);
            }
            return(didCollide);
        }
Пример #5
0
        public void If_point_is_in_within_polygon_return_true_else_return_false(double longitude, double latitude, bool inside)
        {
            var point   = new Point(longitude, latitude);
            var polygon = new Polygon(new[]
            {
                new LineString(new[]
                               { new Point(17.02721, 58.747865),
                                 new Point(17.0272217, 58.7477883),
                                 new Point(17.0272233, 58.7477767),
                                 new Point(17.027224, 58.747765),
                                 new Point(17.02717, 58.7476967),
                                 new Point(17.027155, 58.7476867),
                                 new Point(17.0243233, 58.74786),
                                 new Point(17.0242817, 58.74787),
                                 new Point(17.0242533, 58.7478783),
                                 new Point(17.0242083, 58.7478967),
                                 new Point(17.024185, 58.7479067),
                                 new Point(17.024181, 58.74791),
                                 new Point(17.024147, 58.74794),
                                 new Point(17.024342, 58.748081),
                                 new Point(17.0271167, 58.7478783),
                                 new Point(17.02721, 58.747865) })
            });

            point.IsIntersects(polygon).Should().Be(inside);
            polygon.IsIntersects(point).Should().Be(inside);
            polygon.IsPointInside(point).Should().Be(inside);
        }
        private static void MinMaxDistanceForEdge(
            Vector point,
            Polygon convexHull,
            VertexConstraints constraints1,
            VertexConstraints constraints2,
            out double minDistanceSqr,
            out double maxDistanceSqr)
        {
            if (convexHull.IsPointInside(point))
            {
                minDistanceSqr = 0;
            }
            else
            {
                minDistanceSqr = Double.PositiveInfinity;
                for (int i = 0; i < convexHull.Vertices.Count; ++i)
                {
                    double distanceSqr = point.DistanceToSegmentSquared(
                        convexHull.Vertices[i],
                        convexHull.Vertices[(i + 1) % convexHull.Vertices.Count]);
                    minDistanceSqr = Math.Min(minDistanceSqr, distanceSqr);
                }
            }

            maxDistanceSqr = 0;
            foreach (Vector vertex1 in constraints1.Corners)
            {
                foreach (Vector vertex2 in constraints2.Corners)
                {
                    double distanceSqr = point.DistanceToSegmentSquared(vertex1, vertex2);
                    maxDistanceSqr = Math.Max(maxDistanceSqr, distanceSqr);
                }
            }
        }
Пример #7
0
        /// <summary>
        /// Checks if a point is inside the board.
        /// </summary>
        /// <param name="point">The point to check.</param>
        /// <returns>Is the point inside?</returns>
        public bool IsPointInside(Vector3 point)
        {
            if (point.Y > 0 || point.Y < -Thickness)
            {
                return(false);
            }

            return(mPolygon.IsPointInside(new Poly2Tri.Triangulation.TriangulationPoint(point.X, point.Z)));
        }
Пример #8
0
        public bool CollideAgainst(Polygon polygon)
        {
            polygon.UpdateDependencies(TimeManager.CurrentTime);

            // Check if one of the segment's endpoints is inside the Polygon
            if (polygon.IsPointInside(Point1.X, Point1.Y))
            {
                polygon.mLastCollisionPoint = Point1;
                return(true);
            }

            if (polygon.IsPointInside(Point2.X, Point2.Y))
            {
                polygon.mLastCollisionPoint = Point2;
                return(true);
            }

            Point intersectionPoint;

            // Check if one of the polygon's edges intersects the line segment
            for (int i = 0; i < polygon.Vertices.Length - 1; i++)
            {
                var vertexBefore = polygon.Vertices[i];
                var vertexAfter  = polygon.Vertices[i + 1];

                var currentPolygonSegment =
                    new Segment(
                        new Point(vertexBefore.Position.X,
                                  vertexBefore.Position.Y),
                        new Point(vertexAfter.Position.X,
                                  vertexAfter.Position.Y));


                if (Intersects(currentPolygonSegment, out intersectionPoint))
                {
                    polygon.mLastCollisionPoint = intersectionPoint;
                    return(true);
                }
            }

            // No collision
            return(false);
        }
Пример #9
0
        public void If_point_with_a_polygon_with_whole_then_should_return_intersect_check_correctly(double longitude, double latitude, bool inside)
        {
            var point   = new Point(longitude, latitude);
            var polygon = new Polygon(new[]
            {
                new LineString(new[] { new Point(20, 35), new Point(10, 30), new Point(10, 10), new Point(30, 5), new Point(45, 20), new Point(20, 35) }),
                new LineString(new[] { new Point(30, 20), new Point(20, 15), new Point(20, 25), new Point(30, 20) })
            });

            point.IsIntersects(polygon).Should().Equals(inside);
            polygon.IsIntersects(point).Should().Equals(inside);
            polygon.IsPointInside(point).Should().Equals(inside);
        }
Пример #10
0
        public void KeepThisInsideOf(Polygon polygon)
        {
            UpdateDependencies(TimeManager.CurrentTime);
            polygon.UpdateDependencies(TimeManager.CurrentTime);

            Point3D fromCircleToThis = polygon.VectorFrom(Position.X, Position.Y);

            // The fromCircleToThis will be less than circle.Radius units in length.
            // However much less it is is how far the objects should be moved.

            double length = fromCircleToThis.Length();

            double distanceToMove = Radius - length;

            if (!polygon.IsPointInside(ref Position))
            {
                // If the circle falls inside of the shape, then it should be moved
                // outside.  That means moving to the edge of the polygon then also moving out
                // the distance of the radius.
                distanceToMove = -(Radius + length);
            }
            else if (System.Math.Abs(length) > Radius)
            {
                return;
            }

            double amountToMoveOnX = distanceToMove * fromCircleToThis.X / length;
            double amountToMoveOnY = distanceToMove * fromCircleToThis.Y / length;

            float thisMass  = 0;
            float otherMass = 1;

            float totalMass = thisMass + otherMass;

            LastMoveCollisionReposition.X = -(float)(amountToMoveOnX * otherMass / totalMass);
            LastMoveCollisionReposition.Y = -(float)(amountToMoveOnY * otherMass / totalMass);

            TopParent.Position.X += LastMoveCollisionReposition.X;
            TopParent.Position.Y += LastMoveCollisionReposition.Y;

            polygon.mLastMoveCollisionReposition.X = (float)((thisMass / totalMass) * amountToMoveOnX);
            polygon.mLastMoveCollisionReposition.Y = (float)((thisMass / totalMass) * amountToMoveOnY);

            polygon.TopParent.Position.X += polygon.mLastMoveCollisionReposition.X;
            polygon.TopParent.Position.Y += polygon.mLastMoveCollisionReposition.Y;

            ForceUpdateDependencies();
            polygon.ForceUpdateDependencies();
        }
Пример #11
0
        private static int GetPointToStartAt(Polygon polygon, Polygon otherPolygon)
        {
            int firstPointToStartAt = 0;

            double furthestAwayDistance = otherPolygon.VectorFrom(polygon.mVertices[0].Position.X, polygon.mVertices[0].Position.Y).LengthSquared();


            for (int i = 1; i < polygon.mVertices.Length - 1; i++)
            {
                double distance = otherPolygon.VectorFrom(polygon.mVertices[i].Position.X, polygon.mVertices[i].Position.Y).LengthSquared();

                if (distance > furthestAwayDistance &&
                    !otherPolygon.IsPointInside(ref polygon.mVertices[i].Position))
                {
                    firstPointToStartAt  = i;
                    furthestAwayDistance = distance;
                }
            }
            return(firstPointToStartAt);
        }
Пример #12
0
        public void If_point_with_a_simple_polygon_then_should_return_intersect_check_correctly(double longitude, double latitude, bool inside)
        {
            var point   = new Point(longitude, latitude);
            var polygon = new Polygon(new List <Point>
            {
                new Point(0, 0),
                new Point(5, 0),
                new Point(5, 5),
                new Point(3, 5),
                new Point(3, 3),
                new Point(1, 3),
                new Point(1, 5),
                new Point(0, 5),
                new Point(0, 0),
            });

            point.IsIntersects(polygon).Should().Equals(inside);
            polygon.IsIntersects(point).Should().Equals(inside);
            polygon.IsPointInside(point).Should().Equals(inside);
        }
Пример #13
0
    static bool TryInsertHole(Polygon parent, Polygon hole)
    {
        //Can't go in.
        if (!parent.IsPointInside(hole[0]))
        {
            return(false);
        }

        if (parent.Holes != null)
        {
            foreach (var item in parent.Holes)
            {
                if (TryInsertHole(item, hole))
                {
                    return(true);
                }
            }
        }
        //it doesn't fit into any of the daughter holes.
        parent.AddHole(hole);
        return(true);
    }
        static void MainForConvexHull()
        {
            List <Vector> points = new List <Vector>();

            points.Add(new Vector(0, 0));
            points.Add(new Vector(1, 2));
            points.Add(new Vector(2, 1));
            points.Add(new Vector(3, 2));
            points.Add(new Vector(4, 2));
            points.Add(new Vector(3, -1));

            Polygon p = Polygon.ConvexHull(points);

            Console.WriteLine(p.IsPointInside(new Vector(2, 1)));
            Console.WriteLine(p.IsPointInside(new Vector(2, -1)));
            Console.WriteLine(p.IsPointInside(new Vector(0, -1)));
            Console.WriteLine(p.IsPointInside(new Vector(-1, 0)));
            Console.WriteLine(p.IsPointInside(new Vector(2, 0)));
            Console.WriteLine(p.IsPointInside(new Vector(3, 1)));
        }
Пример #15
0
    /// <summary>
    /// Creates a triangulation of the vertices given, and gives you the indices of it.
    /// </summary>
    /// <param name="aPoints">A list of points to triangulate.</param>
    /// <param name="aTreatAsPath">Should we discard any triangles at all? Use this if you want to get rid of triangles that are outside the path.</param>
    /// <param name="aInvert">if we're treating it as a path, should we instead sicard triangles inside the path?</param>
    /// <returns>A magical list of indices describing the triangulation!</returns>
    ///

    public static void GetVerticesAndIndices(List <Vector2> inputPoints, out List <Vector2> outputPoints, out List <int> outputIndices, float chunkWidth, float chunkHeight, float jitterX, float jitterY)
    {
        Polygon             poly;
        List <PolygonPoint> points             = new List <PolygonPoint>();
        List <Vector2>      interpolatedPoints = new List <Vector2>();
        float edgeCutLength = (chunkWidth + chunkHeight) * 0.5f;
        int   triangleIndex = 0;
        int   numChunksX;
        int   numChunksY;

        outputPoints  = new List <Vector2>();
        outputIndices = new List <int>();

        // Cut all the edges into smaller segments (so triangulation won't create long, thin shards along the edges)
        for (int i = 0; i < inputPoints.Count; i++)
        {
            Vector2 a;
            Vector2 b;
            float   distance;
            int     numCuts;
            float   cutLength;

            a = i == 0 ? inputPoints[inputPoints.Count - 1] : inputPoints[i - 1];
            b = inputPoints[i];

            distance  = (b - a).magnitude;
            numCuts   = (int)(distance / edgeCutLength);
            cutLength = distance / (float)numCuts;

            for (int j = 0; j < numCuts; j++)
            {
                Vector2 p = Vector2.Lerp(a, b, Mathf.Max(0f, Mathf.Min(1f, (j * cutLength / distance))));

                interpolatedPoints.Add(p);
            }
        }

        // Convert points to P2T, and create polygon
        foreach (Vector2 p in interpolatedPoints)
        {
            points.Add(new PolygonPoint(p.x, p.y));
        }
        poly = new Polygon(points);

        // Calculate number of chunks to split the polygon up into
        numChunksX = (int)(poly.Bounds.Width / chunkWidth);
        numChunksY = (int)(poly.Bounds.Height / chunkHeight);

        // Add steiner points (this is the reason for using Poly2Tri)
        UnityEngine.Random.seed = (int)(poly.Bounds.Left * poly.Bounds.Top);
        for (int i = 0; i < numChunksX; i++)
        {
            for (int j = 0; j < numChunksY; j++)
            {
                TriangulationPoint p = new TriangulationPoint(
                    i * chunkWidth + poly.Bounds.Left + UnityEngine.Random.Range(-jitterX, jitterX),
                    j * -chunkHeight + poly.Bounds.Top + UnityEngine.Random.Range(-jitterY, jitterY));

                if (poly.IsPointInside(p))
                {
                    poly.AddSteinerPoint(p);
                }
            }
        }

        // Triangulate
        P2T.Triangulate(poly);

        // Build output from triangulated polygon
        foreach (DelaunayTriangle triangle in poly.Triangles)
        {
            TriangulationPoint p1 = triangle.Points[0];
            TriangulationPoint p2 = triangle.PointCWFrom(p1);
            TriangulationPoint p3 = triangle.PointCWFrom(p2);

            outputPoints.Add(new Vector2(p1.Xf, p1.Yf));
            outputPoints.Add(new Vector2(p2.Xf, p2.Yf));
            outputPoints.Add(new Vector2(p3.Xf, p3.Yf));
            outputIndices.Add(triangleIndex++);
            outputIndices.Add(triangleIndex++);
            outputIndices.Add(triangleIndex++);
        }
    }
Пример #16
0
        public bool CollideAgainst(Polygon polygon)
        {
            polygon.UpdateDependencies(TimeManager.CurrentTime);

            // Check if one of the segment's endpoints is inside the Polygon
            if (polygon.IsPointInside(Point1.X, Point1.Y))
            {
                polygon.mLastCollisionPoint = Point1;
                return true;
            }                                                  

            if (polygon.IsPointInside(Point2.X, Point2.Y))
            {
                polygon.mLastCollisionPoint = Point2;
                return true;
            }

            Point intersectionPoint;

            // Check if one of the polygon's edges intersects the line segment
            for (int i = 0; i < polygon.Points.Count - 1; i++)
            {
                if (Intersects(new Segment(
                      new Point(polygon.Position.X + polygon.Points[i].X,
                                polygon.Position.Y + polygon.Points[i].Y),
                      new Point(polygon.Position.X + polygon.Points[i + 1].X,
                                polygon.Position.Y + polygon.Points[i + 1].Y)), out intersectionPoint))
                {
                    polygon.mLastCollisionPoint = intersectionPoint;
                    return true;
                }
            }

            // No collision
            return false;
        }
    public List<TriangulationPoint> GenerateGridPoints(Bounds bounds, float subdivLevel, Polygon _polygon)
    {
        List<TriangulationPoint> GridPoints = new List<TriangulationPoint> ();
        float numberDivisions = 6;

        float width = bounds.max.x - bounds.min.x;
        float height = bounds.max.y - bounds.min.y;

        float subdivWidth = width / (subdivLevel*numberDivisions);
        float subdivHeight = height / ((subdivLevel*numberDivisions) );

        float averagedLength = (subdivWidth + subdivHeight) / 2;
        float widthHeight = (width + height) / 2;

        for(int i=1;i<(subdivLevel*numberDivisions/widthHeight)*width;i++)
        {
            for(int j=1;j<(subdivLevel*numberDivisions/widthHeight)*height;j++)
            {
                float xPos = (i*averagedLength) + bounds.min.x;
                float yPos = (j*averagedLength) + bounds.min.y;
                TriangulationPoint t = new TriangulationPoint (xPos, yPos);
                if(_polygon.IsPointInside(t))
                    GridPoints.Add(t);

            }
        }
        return GridPoints;
    }
Пример #18
0
 public bool IsOn(Polygon polygon, Camera camera)
 {
     return(polygon.IsPointInside(WorldXAt(polygon.Z, camera), WorldYAt(polygon.Z, camera)));
 }
Пример #19
0
        private static void SetPointsFromContactPointsAndVertices(Polygon polygon, Polygon otherPolygon, List<ContactPoint> contactPoints, int polygonPointToStartAt, List<Vector3> thisVertices, List<Vector3> otherVertices)
        {
            Polygon currentPolygon = polygon;

            List<Vector3> newPolygonPoints = new List<Vector3>();
            int otherIndex = 0;
            int otherIndexToStartAt = -1;
            int thisIndex = polygonPointToStartAt;
            while (true)
            {
                if (newPolygonPoints.Count > 3 * (polygon.Points.Count + otherPolygon.Points.Count))
                {
                    // just break here for now
                    break;
                }

                bool isThereAContactPoint = false;

                if (currentPolygon == polygon)
                {
                    
                    newPolygonPoints.Add(thisVertices[thisIndex]);
                    isThereAContactPoint = DoesContactPointsHaveThisIndex(thisIndex, contactPoints);
                }
                else
                {
                    newPolygonPoints.Add(otherVertices[otherIndex]);
                    isThereAContactPoint = DoesContactPointsHaveOtherIndex(otherIndex, contactPoints);
                }

                if (isThereAContactPoint)
                {
                    ContactPoint cp = new ContactPoint();
                    if (currentPolygon == polygon)
                    {
                        cp = GetContactPointAtThisIndex(thisIndex, contactPoints, thisVertices[thisIndex]);
                    }
                    else
                    {
                        cp = GetContactPointAtOtherIndex(otherIndex, contactPoints, otherVertices[otherIndex]);
                    }

                    #region If it's a segment intersection, drop the point and swap the current polygon

                    if (cp.ContactType == ContactType.SegmentIntersection)
                    {

                        if (currentPolygon == polygon)
                        {
                            currentPolygon = otherPolygon;
                            otherIndex = cp.OtherIndex + 1;

                            if (otherIndex == otherVertices.Count - 1)
                            {
                                otherIndex = 0;
                            }
                            if (otherIndex == otherIndexToStartAt)
                            {
                                newPolygonPoints.Add(newPolygonPoints[0]);
                                break;
                            }

                            if (otherIndexToStartAt == -1)
                            {
                                otherIndexToStartAt = otherIndex;
                            }
                        }
                        else
                        {
                            currentPolygon = polygon;
                            thisIndex = cp.ThisIndex + 1;

                            if (thisIndex == polygon.Points.Count - 1)
                            {
                                thisIndex = 0;
                            }
                            if (thisIndex == polygonPointToStartAt)
                            {
                                // close off the polygon and stop adding points
                                newPolygonPoints.Add(newPolygonPoints[0]);
                                break;
                            }
                        }

                        newPolygonPoints.Add(cp.Position);


                    }
                    #endregion
                    
                    else if(cp.ContactType == ContactType.PointOnSegment)
                    {
                        // See which next point is the furthest away, and decide based off of that.

                        int nextOtherIndex = cp.OtherIndex + 1;
                        if (cp.OtherEndpoint != -1)
                        {
                            nextOtherIndex = cp.OtherEndpoint + 1;
                        }
                        if (nextOtherIndex >= otherVertices.Count - 1)
                        {
                            nextOtherIndex -= (otherVertices.Count - 1);
                        }


                        int nextThisIndex = cp.ThisIndex + 1;
                        if (cp.ThisEndpoint != -1)
                        {
                            nextThisIndex = cp.ThisEndpoint + 1;
                        }
                        if (nextThisIndex >= thisVertices.Count - 1)
                        {
                            nextThisIndex -= (thisVertices.Count - 1);
                        }

                        Vector3 nextThisVector = thisVertices[nextThisIndex] - cp.Position;
                        Vector3 nextOtherVector = otherVertices[nextOtherIndex] - cp.Position;
                        double distanceAwayFromThis = 0;
                        double distanceAwayFromOther = 0;

                        bool doWhile = true;

                        int numberOfExtraDoWhiles = 0;

                        int thisIndexBeforeDoWhile = nextThisIndex;
                        int otherIndexBeforeDoWhile = nextOtherIndex;

                        // The doWhile section will find out which path will take us
                        // furtest away from the other Polygon.  This works most of the time
                        // but in some cases (like if the initial two paths are parallel), we'll
                        // want to special case which we use
                        bool forceUseThis = false;
                        bool forceUseOther = false;

                        while (doWhile)
                        {

                            if (nextThisVector.Length() < .0001f)
                            {
                                nextThisIndex++;
                                if (nextThisIndex == thisVertices.Count - 1)
                                {
                                    nextThisIndex = 0;
                                }
                                nextThisVector = thisVertices[nextThisIndex] - cp.Position;
                            }

                            if (nextOtherVector.Length() < .0001f)
                            {
                                nextOtherIndex++;
                                if (nextOtherIndex == otherVertices.Count - 1)
                                {
                                    nextOtherIndex = 0;
                                }
                                nextOtherVector = otherVertices[nextOtherIndex] - cp.Position;
                            }

                            float thisVectorLength = nextThisVector.Length();
                            float otherVectorLength = nextOtherVector.Length();

                            float smallestDistance = System.Math.Min(thisVectorLength, otherVectorLength);

                            nextThisVector.Normalize();
                            nextOtherVector.Normalize();

                            nextThisVector *= smallestDistance / 2.0f;
                            nextOtherVector *= smallestDistance / 2.0f;

                            nextThisVector += cp.Position;
                            nextOtherVector += cp.Position;

                            if (nextThisVector == nextOtherVector)
                            {

                                forceUseThis = thisVectorLength < otherVectorLength;
                                forceUseOther = !forceUseThis;

                                break;
                            }



                            double minimumDistance = .00001;

                            if (polygon.IsPointInside(ref nextOtherVector))
                            {
                                distanceAwayFromThis = 0;
                            }
                            else
                            {
                                distanceAwayFromThis = polygon.VectorFrom(nextOtherVector.X, nextOtherVector.Y).Length();

                                if (distanceAwayFromThis < minimumDistance)
                                {
                                    distanceAwayFromThis = 0;
                                }
                            }

                            if (otherPolygon.IsPointInside(ref nextThisVector))
                            {
                                distanceAwayFromOther = 0;
                            }
                            else
                            {
                                distanceAwayFromOther = otherPolygon.VectorFrom(nextThisVector.X, nextThisVector.Y).Length();

                                if (distanceAwayFromOther < minimumDistance)
                                {
                                    distanceAwayFromOther = 0;
                                }
                            }

                            if (distanceAwayFromOther == distanceAwayFromThis)
                            {
                                // We need a tiebreaker.  Let's move an extra index and see what happens, shall we?
                                nextThisIndex++;
                                if (nextThisIndex == thisVertices.Count - 1)
                                {
                                    nextThisIndex = 0;
                                }
                                nextThisVector = thisVertices[nextThisIndex] - cp.Position;

                                nextOtherIndex++;
                                if (nextOtherIndex == otherVertices.Count - 1)
                                {
                                    nextOtherIndex = 0;
                                }
                                nextOtherVector = otherVertices[nextOtherIndex] - cp.Position;

                                numberOfExtraDoWhiles++;
                            }
                            else
                            {
                                doWhile = false;
                            }
                        }

                        nextThisIndex = thisIndexBeforeDoWhile;
                        nextOtherIndex = otherIndexBeforeDoWhile;

                        bool useThis = distanceAwayFromThis < distanceAwayFromOther;

                        if (forceUseThis)
                            useThis = true;
                        else if (forceUseOther)
                            useThis = false;

                        if (useThis && currentPolygon == polygon)
                        {
                            // make sure there are no other contact points on the current segment on this
                            for (int i = 0; i < contactPoints.Count; i++)
                            {
                                ContactPoint otherCp = contactPoints[i];

                                if (otherCp.Position != cp.Position && otherCp.ThisIndex == cp.ThisIndex)
                                {
                                    useThis = false;
                                    break;
                                }
                            }
                        }

                        else if (!useThis && currentPolygon == otherPolygon)
                        {
                            // make sure there are no other contact points on the current segment on this
                            for (int i = 0; i < contactPoints.Count; i++)
                            {
                                ContactPoint otherCp = contactPoints[i];

                                if (otherCp.Position != cp.Position && otherCp.OtherIndex == cp.OtherIndex)
                                {
                                    useThis = true;
                                    break;
                                }
                            }
                        }

                        newPolygonPoints.Add(cp.Position);

                        if (distanceAwayFromThis == distanceAwayFromOther)
                        {
                            useThis = currentPolygon == polygon;

                        }
                        if (useThis)
                        {
                            currentPolygon = polygon;

                            thisIndex = nextThisIndex;

                            if (thisIndex == polygonPointToStartAt)
                            {
                                // close off the polygon and stop adding points
                                newPolygonPoints.Add(newPolygonPoints[0]);
                                break;
                            }
                        }
                        else
                        {
                            currentPolygon = otherPolygon;

                            otherIndex = nextOtherIndex;

                            if (otherIndex == otherIndexToStartAt)
                            {
                                newPolygonPoints.Add(newPolygonPoints[0]);
                                break;
                            }                            
                            
                            if (otherIndexToStartAt == -1)
                            {
                                otherIndexToStartAt = otherIndex;
                            }


                        }


                    }
                }
                else
                {
                    if (currentPolygon == polygon)
                    {

                        thisIndex++;
                        if (thisIndex == polygon.Points.Count - 1)
                        {
                            thisIndex = 0;
                        }
                        if (thisIndex == polygonPointToStartAt)
                        {
                            // close off the polygon and stop adding points
                            newPolygonPoints.Add(newPolygonPoints[0]);

                            break;
                        }
                    }
                    else
                    {
                        otherIndex++;
                        if (otherIndex == otherPolygon.Points.Count - 1)
                        {
                            otherIndex = 0;
                        }
                        if (otherIndex == otherIndexToStartAt)
                        {
                            // close off the polygon and stop adding points
                            newPolygonPoints.Add(newPolygonPoints[0]);

                            break;
                        }
                    }
                }
            }

            SetPolygonPoints(polygon, newPolygonPoints);
        }
Пример #20
0
        private static void SetPointsFromContactPointsAndVertices(Polygon polygon, Polygon otherPolygon, List <ContactPoint> contactPoints, int polygonPointToStartAt, List <Vector3> thisVertices, List <Vector3> otherVertices)
        {
            Polygon currentPolygon = polygon;

            List <Vector3> newPolygonPoints    = new List <Vector3>();
            int            otherIndex          = 0;
            int            otherIndexToStartAt = -1;
            int            thisIndex           = polygonPointToStartAt;

            while (true)
            {
                if (newPolygonPoints.Count > 3 * (polygon.Points.Count + otherPolygon.Points.Count))
                {
                    // just break here for now
                    break;
                }

                bool isThereAContactPoint = false;

                if (currentPolygon == polygon)
                {
                    newPolygonPoints.Add(thisVertices[thisIndex]);
                    isThereAContactPoint = DoesContactPointsHaveThisIndex(thisIndex, contactPoints);
                }
                else
                {
                    newPolygonPoints.Add(otherVertices[otherIndex]);
                    isThereAContactPoint = DoesContactPointsHaveOtherIndex(otherIndex, contactPoints);
                }

                if (isThereAContactPoint)
                {
                    ContactPoint cp = new ContactPoint();
                    if (currentPolygon == polygon)
                    {
                        cp = GetContactPointAtThisIndex(thisIndex, contactPoints, thisVertices[thisIndex]);
                    }
                    else
                    {
                        cp = GetContactPointAtOtherIndex(otherIndex, contactPoints, otherVertices[otherIndex]);
                    }

                    #region If it's a segment intersection, drop the point and swap the current polygon

                    if (cp.ContactType == ContactType.SegmentIntersection)
                    {
                        if (currentPolygon == polygon)
                        {
                            currentPolygon = otherPolygon;
                            otherIndex     = cp.OtherIndex + 1;

                            if (otherIndex == otherVertices.Count - 1)
                            {
                                otherIndex = 0;
                            }
                            if (otherIndex == otherIndexToStartAt)
                            {
                                newPolygonPoints.Add(newPolygonPoints[0]);
                                break;
                            }

                            if (otherIndexToStartAt == -1)
                            {
                                otherIndexToStartAt = otherIndex;
                            }
                        }
                        else
                        {
                            currentPolygon = polygon;
                            thisIndex      = cp.ThisIndex + 1;

                            if (thisIndex == polygon.Points.Count - 1)
                            {
                                thisIndex = 0;
                            }
                            if (thisIndex == polygonPointToStartAt)
                            {
                                // close off the polygon and stop adding points
                                newPolygonPoints.Add(newPolygonPoints[0]);
                                break;
                            }
                        }

                        newPolygonPoints.Add(cp.Position);
                    }
                    #endregion

                    else if (cp.ContactType == ContactType.PointOnSegment)
                    {
                        // See which next point is the furthest away, and decide based off of that.

                        int nextOtherIndex = cp.OtherIndex + 1;
                        if (cp.OtherEndpoint != -1)
                        {
                            nextOtherIndex = cp.OtherEndpoint + 1;
                        }
                        if (nextOtherIndex >= otherVertices.Count - 1)
                        {
                            nextOtherIndex -= (otherVertices.Count - 1);
                        }


                        int nextThisIndex = cp.ThisIndex + 1;
                        if (cp.ThisEndpoint != -1)
                        {
                            nextThisIndex = cp.ThisEndpoint + 1;
                        }
                        if (nextThisIndex >= thisVertices.Count - 1)
                        {
                            nextThisIndex -= (thisVertices.Count - 1);
                        }

                        Vector3 nextThisVector        = thisVertices[nextThisIndex] - cp.Position;
                        Vector3 nextOtherVector       = otherVertices[nextOtherIndex] - cp.Position;
                        double  distanceAwayFromThis  = 0;
                        double  distanceAwayFromOther = 0;

                        bool doWhile = true;

                        int numberOfExtraDoWhiles = 0;

                        int thisIndexBeforeDoWhile  = nextThisIndex;
                        int otherIndexBeforeDoWhile = nextOtherIndex;

                        // The doWhile section will find out which path will take us
                        // furtest away from the other Polygon.  This works most of the time
                        // but in some cases (like if the initial two paths are parallel), we'll
                        // want to special case which we use
                        bool forceUseThis  = false;
                        bool forceUseOther = false;

                        while (doWhile)
                        {
                            if (nextThisVector.Length() < .0001f)
                            {
                                nextThisIndex++;
                                if (nextThisIndex == thisVertices.Count - 1)
                                {
                                    nextThisIndex = 0;
                                }
                                nextThisVector = thisVertices[nextThisIndex] - cp.Position;
                            }

                            if (nextOtherVector.Length() < .0001f)
                            {
                                nextOtherIndex++;
                                if (nextOtherIndex == otherVertices.Count - 1)
                                {
                                    nextOtherIndex = 0;
                                }
                                nextOtherVector = otherVertices[nextOtherIndex] - cp.Position;
                            }

                            float thisVectorLength  = nextThisVector.Length();
                            float otherVectorLength = nextOtherVector.Length();

                            float smallestDistance = System.Math.Min(thisVectorLength, otherVectorLength);

                            nextThisVector.Normalize();
                            nextOtherVector.Normalize();

                            nextThisVector  *= smallestDistance / 2.0f;
                            nextOtherVector *= smallestDistance / 2.0f;

                            nextThisVector  += cp.Position;
                            nextOtherVector += cp.Position;

                            if (nextThisVector == nextOtherVector)
                            {
                                forceUseThis  = thisVectorLength < otherVectorLength;
                                forceUseOther = !forceUseThis;

                                break;
                            }



                            double minimumDistance = .00001;

                            if (polygon.IsPointInside(ref nextOtherVector))
                            {
                                distanceAwayFromThis = 0;
                            }
                            else
                            {
                                distanceAwayFromThis = polygon.VectorFrom(nextOtherVector.X, nextOtherVector.Y).Length();

                                if (distanceAwayFromThis < minimumDistance)
                                {
                                    distanceAwayFromThis = 0;
                                }
                            }

                            if (otherPolygon.IsPointInside(ref nextThisVector))
                            {
                                distanceAwayFromOther = 0;
                            }
                            else
                            {
                                distanceAwayFromOther = otherPolygon.VectorFrom(nextThisVector.X, nextThisVector.Y).Length();

                                if (distanceAwayFromOther < minimumDistance)
                                {
                                    distanceAwayFromOther = 0;
                                }
                            }

                            if (distanceAwayFromOther == distanceAwayFromThis)
                            {
                                // We need a tiebreaker.  Let's move an extra index and see what happens, shall we?
                                nextThisIndex++;
                                if (nextThisIndex == thisVertices.Count - 1)
                                {
                                    nextThisIndex = 0;
                                }
                                nextThisVector = thisVertices[nextThisIndex] - cp.Position;

                                nextOtherIndex++;
                                if (nextOtherIndex == otherVertices.Count - 1)
                                {
                                    nextOtherIndex = 0;
                                }
                                nextOtherVector = otherVertices[nextOtherIndex] - cp.Position;

                                numberOfExtraDoWhiles++;
                            }
                            else
                            {
                                doWhile = false;
                            }
                        }

                        nextThisIndex  = thisIndexBeforeDoWhile;
                        nextOtherIndex = otherIndexBeforeDoWhile;

                        bool useThis = distanceAwayFromThis < distanceAwayFromOther;

                        if (forceUseThis)
                        {
                            useThis = true;
                        }
                        else if (forceUseOther)
                        {
                            useThis = false;
                        }

                        if (useThis && currentPolygon == polygon)
                        {
                            // make sure there are no other contact points on the current segment on this
                            for (int i = 0; i < contactPoints.Count; i++)
                            {
                                ContactPoint otherCp = contactPoints[i];

                                if (otherCp.Position != cp.Position && otherCp.ThisIndex == cp.ThisIndex)
                                {
                                    useThis = false;
                                    break;
                                }
                            }
                        }

                        else if (!useThis && currentPolygon == otherPolygon)
                        {
                            // make sure there are no other contact points on the current segment on this
                            for (int i = 0; i < contactPoints.Count; i++)
                            {
                                ContactPoint otherCp = contactPoints[i];

                                if (otherCp.Position != cp.Position && otherCp.OtherIndex == cp.OtherIndex)
                                {
                                    useThis = true;
                                    break;
                                }
                            }
                        }

                        newPolygonPoints.Add(cp.Position);

                        if (distanceAwayFromThis == distanceAwayFromOther)
                        {
                            useThis = currentPolygon == polygon;
                        }
                        if (useThis)
                        {
                            currentPolygon = polygon;

                            thisIndex = nextThisIndex;

                            if (thisIndex == polygonPointToStartAt)
                            {
                                // close off the polygon and stop adding points
                                newPolygonPoints.Add(newPolygonPoints[0]);
                                break;
                            }
                        }
                        else
                        {
                            currentPolygon = otherPolygon;

                            otherIndex = nextOtherIndex;

                            if (otherIndex == otherIndexToStartAt)
                            {
                                newPolygonPoints.Add(newPolygonPoints[0]);
                                break;
                            }

                            if (otherIndexToStartAt == -1)
                            {
                                otherIndexToStartAt = otherIndex;
                            }
                        }
                    }
                }
                else
                {
                    if (currentPolygon == polygon)
                    {
                        thisIndex++;
                        if (thisIndex == polygon.Points.Count - 1)
                        {
                            thisIndex = 0;
                        }
                        if (thisIndex == polygonPointToStartAt)
                        {
                            // close off the polygon and stop adding points
                            newPolygonPoints.Add(newPolygonPoints[0]);

                            break;
                        }
                    }
                    else
                    {
                        otherIndex++;
                        if (otherIndex == otherPolygon.Points.Count - 1)
                        {
                            otherIndex = 0;
                        }
                        if (otherIndex == otherIndexToStartAt)
                        {
                            // close off the polygon and stop adding points
                            newPolygonPoints.Add(newPolygonPoints[0]);

                            break;
                        }
                    }
                }
            }

            SetPolygonPoints(polygon, newPolygonPoints);
        }
Пример #21
0
        private static int GetPointToStartAt(Polygon polygon, Polygon otherPolygon)
        {
            int firstPointToStartAt = 0;

            double furthestAwayDistance = otherPolygon.VectorFrom(polygon.mVertices[0].Position.X, polygon.mVertices[0].Position.Y).LengthSquared();


            for (int i = 1; i < polygon.mVertices.Length - 1; i++)
            {
                double distance = otherPolygon.VectorFrom(polygon.mVertices[i].Position.X, polygon.mVertices[i].Position.Y).LengthSquared();

                if(distance > furthestAwayDistance &&
                    !otherPolygon.IsPointInside(ref polygon.mVertices[i].Position))
                {
                    firstPointToStartAt = i;
                    furthestAwayDistance = distance;
                }
            }
            return firstPointToStartAt;
        }
Пример #22
0
 public bool IsOn(Polygon polygon)
 {
     return(polygon.IsPointInside(WorldXAt(polygon.Z), WorldYAt(polygon.Z)));
 }
Пример #23
0
    static bool TryInsertHole(Polygon parent, Polygon hole)
    {
        //Can't go in.
        if (!parent.IsPointInside(hole[0]))
            return false;

        if (parent.Holes != null)
            foreach (var item in parent.Holes)
            {
                if (TryInsertHole(item, hole))
                    return true;
            }
        //it doesn't fit into any of the daughter holes.
        parent.AddHole(hole);
        return true;
    }
Пример #24
0
 private static bool Check( Triangle tri, Polygon boundary )
 {
     if( boundary == null ||
         (boundary.IsPointInside( tri.a ) &&
         boundary.IsPointInside( tri.b ) &&
         boundary.IsPointInside( tri.c )) )
         return true;
     return false;
 }