コード例 #1
0
        public bool Equals(IPolygon2D other)
        {
            var poly = other as Polygon2D;

            if (poly == null)
            {
                return(false);
            }

            if (VertexCount != poly.VertexCount)
            {
                return(false);
            }

            var vertices      = Vertices.ToList();
            var otherVertices = poly.Vertices.ToList();

            for (var i = 0; i < VertexCount; i++)
            {
                if (!vertices[i].Equals(otherVertices[i]))
                {
                    return(false);
                }
            }

            return(true);
        }
コード例 #2
0
        public ConvexHullTest()
        {
            m_vertices = new List <Vector2>()
            {
                new Vector2(0, 0),
                new Vector2(1, 1),
                new Vector2(0, 2),
                new Vector2(3, 2),
                new Vector2(2, -1),
                new Vector2(0, -1),
                new Vector2(-1, -2),
                new Vector2(-3, -1),
                new Vector2(-1, -0.5f),
                new Vector2(-4, 1),
                new Vector2(-2, 3),
            };

            m_polygon = new Polygon2D(m_vertices);

            m_upperhull = new List <Vector2>()
            {
                m_vertices[9], m_vertices[10], m_vertices[3]
            };
            m_lowerhull = new List <Vector2>()
            {
                m_vertices[9], m_vertices[7], m_vertices[6], m_vertices[4], m_vertices[3]
            };

            m_hull = new Polygon2D(new List <Vector2>()
            {
                m_vertices[9], m_vertices[10], m_vertices[3], // upperhull
                m_vertices[4], m_vertices[6], m_vertices[7]   // lowerhull
            });
        }
コード例 #3
0
        public bool Equals(IPolygon2D other)
        {
            var poly = other as MultiPolygon2D;

            if (poly == null)
            {
                return(false);
            }

            if (Polygons.Count != poly.Polygons.Count)
            {
                return(false);
            }

            var polygons      = Polygons.ToList();
            var otherPolygons = poly.Polygons.ToList();

            for (var i = 0; i < Polygons.Count; i++)
            {
                if (!polygons[i].Equals(otherPolygons[i]))
                {
                    return(false);
                }
            }

            return(true);
        }
コード例 #4
0
 /// <summary>
 /// Checks to see if two polygons intersect
 /// </summary>
 /// <param name="a">The first polygon.</param>
 /// <param name="b">The second polygon.</param>
 /// <returns>True if the two polygons intersect.  False otherwise.</returns>
 public static bool Intersects(IPolygon2D a, IPolygon2D b)
 {
     // See if this polygon's points are contained in the other polygon
     for (int i = 0; i < a.NumSides; i++)
     {
         if (b.Contains(a.Vertices[i]))
         {
             return(true);
         }
     }
     // See if this polygon contains the other polygon's points
     for (int i = 0; i < b.NumSides; i++)
     {
         if (a.Contains(b.Vertices[i]))
         {
             return(true);
         }
     }
     // See if any of the polygon edges intersect each other
     for (int i = 0; i < a.NumSides; i++)
     {
         Vector2 edgeStart = a.Vertices[i];
         Vector2 edgeEnd   = (i == a.NumSides - 1 ? a.Vertices[0] : a.Vertices[i + 1]);
         for (int j = 0; j < b.NumSides; j++)
         {
             Vector2 otherEdgeStart = a.Vertices[j];
             Vector2 otherEdgeEnd   = (j == a.NumSides - 1 ? a.Vertices[0] : a.Vertices[j + 1]);
             if (ShapeUtility.AreEdgesIntersecting(edgeStart, edgeEnd, otherEdgeStart, otherEdgeEnd))
             {
                 return(true);
             }
         }
     }
     return(false);
 }
コード例 #5
0
        public bool Equals(IPolygon2D other)
        {
            var poly = other as Polygon2DWithHoles;

            if (poly == null)
            {
                return(false);
            }

            if (!Outside.Equals(poly.Outside))
            {
                return(false);
            }
            if (Holes.Count != poly.Holes.Count)
            {
                return(false);
            }

            var holes      = Holes.ToList();
            var otherHoles = poly.Holes.ToList();

            for (var i = 0; i < holes.Count; i++)
            {
                if (!holes[i].Equals(otherHoles[i]))
                {
                    return(false);
                }
            }

            return(true);
        }
コード例 #6
0
        /// <summary>
        /// Divide <c>ParabolicArcSegment2D</c> on straight lines polygon.
        /// </summary>
        /// <param name="start">The start point of segment.</param>
        /// <param name="source">The segment to discretization.</param>
        /// <param name="target">The <c>Region2D</c> as target of discretization.</param>
        public void Discretize(Point start, ISegment2D source, IPolygon2D target)
        {
            var segment = source as ParabolicArcSegment2D;

            // The angle in degrees
            double totalAngle = segment.GetAngle(ref start);

            if (angle < Math.Abs(totalAngle) || this.numberOfTiles > 1)
            {
                int numberOfTiles = Math.Max((int)Math.Ceiling(Math.Abs(totalAngle) / angle), this.numberOfTiles);

                double deltaAngle = totalAngle / numberOfTiles;
                var    mat        = new Matrix();
                mat.Rotate(deltaAngle);
                var t = segment.GetTangentOnSegment(ref start, 0);
                for (int i = 1; i < numberOfTiles; ++i)
                {
                    t = mat.Transform(t);
                    if (segment.CoordinatesFromTangent(ref start, t, out Point p))
                    {
                        target.Add(p);
                    }
                }
            }

            target.Add(segment.EndPoint);
        }
コード例 #7
0
        private static List <IntPoint> CreatePolygon(IPolygon2D polygon, bool counterClockwise)
        {
            if (polygon.IsCounterClockwise != counterClockwise)
            {
                polygon.Reverse();
            }

            return(CreatePolygon(polygon));
        }
コード例 #8
0
        protected static List <IntPoint> CreatePolygon(IPolygon2D polygon)
        {
            var count    = polygon.Count;
            var cpolygon = new List <IntPoint>(count);

            for (int i = 0; i < count; ++i)
            {
                cpolygon.Add(new IntPoint((long)(polygon[i].X * ClipperScale), (long)(polygon[i].Y * ClipperScale)));
            }

            return(cpolygon);
        }
コード例 #9
0
        /// <summary>
        /// Calculates the average of all vertices on a polygon
        /// </summary>
        /// <param name="shape">The polygon.</param>
        /// <returns>The center point of the polygon.</returns>
        public static Vector2 CalculateCenterPoint(IPolygon2D shape)
        {
            Vector2 pointSum = VectorUtility.Zero;

            for (int i = 0; i < shape.NumSides; i++)
            {
                pointSum += shape.Vertices[i];
            }
            Vector2 pointAverage = pointSum / shape.NumSides;

            return(pointAverage);
        }
コード例 #10
0
        /// <summary>
        /// Compare points of polygon with <paramref name="pattern"/>.
        /// </summary>
        /// <param name="pattern">Polygon to be compared with this instance.</param>
        /// <param name="tolerance">Tolerance used in comparison of coordinates</param>
        /// <returns>True if all points are equal.</returns>
        public bool EqualPoints(IPolygon2D pattern, double tolerance)
        {
            for (int i = 0, sz = this.Count; i < sz; i++)
            {
                Point left  = this[i];
                Point right = pattern[i];
                if (!left.X.IsEqual(right.X, tolerance) || !left.Y.IsEqual(right.Y, tolerance))
                {
                    return(false);
                }
            }

            return(true);
        }
コード例 #11
0
ファイル: ConvexHull.cs プロジェクト: HSJMDMG/CHGame
        /// <summary>
        /// combine 2 convex hulls
        /// </summary>

        public static Polygon2D ComputeConvexHull(IPolygon2D polygon1, IPolygon2D polygon2)
        {
            //TODO: change to O(n) algorithm
            List <Vector2> vl = new List <Vector2>();

            foreach (var v in polygon1.Vertices)
            {
                vl.Add(v);
            }
            foreach (var v in polygon2.Vertices)
            {
                vl.Add(v);
            }
            return(ComputeConvexHull(vl));
        }
コード例 #12
0
        /// <summary>
        /// Calculates the vector pointing to the furthest vertex of the specified polygon if the polygon is centered at 0,0.
        /// </summary>
        /// <param name="shape">The polygon.</param>
        /// <returns>The vector pointing to the furthest vertex of the specified polygon if the polygon is centered at 0,0.</returns>
        public static Vector2 CalculateOuterRadius(IPolygon2D shape)
        {
            Vector2 max = VectorUtility.Zero;
            Vector2 vector;

            for (int i = 0; i < shape.NumSides; i++)
            {
                vector = shape.Vertices[i] - shape.Center;
                if (vector.Length() > max.Length())
                {
                    max = vector;
                }
            }

            return(max);
        }
コード例 #13
0
        /// <summary>
        /// Divide <c>LineSegment2D</c> on straight lines polygon.
        /// </summary>
        /// <param name="start">The start point of segment.</param>
        /// <param name="source">The segment to discretization.</param>
        /// <param name="target">The <c>Polygon2D</c> as target of discretization.</param>
        public void Discretize(Point start, ISegment2D source, IPolygon2D target)
        {
            double length = source.GetLength(ref start);

            if (numberOfTiles > 1 || length > lengthOfTile)
            {
                int           tiles   = Math.Max(numberOfTiles, (int)Math.Ceiling(length / lengthOfTile));
                LineSegment2D segment = source as LineSegment2D;
                Vector        u       = Point.Subtract(segment.EndPoint, start) / tiles;
                Point         pt      = start;
                for (int i = 1; i < tiles; ++i)
                {
                    pt = Point.Add(pt, u);
                    target.Add(pt);
                }
            }

            target.Add(source.EndPoint);
        }
コード例 #14
0
        public static IEnumerable <IPolyLine2D> BuildOffset(IPolygon2D polygon, double delta, JoinType joinType, EndType endType, double mitterLimit, double maxDiscretizationAngle = 5)
        {
            bool containsCircArc = false;
            var  p = CreatePolygon(polygon);

            if (joinType == JoinType.jtRound || endType == EndType.etOpenRound)
            {
                containsCircArc = true;
            }

            var co = new ClipperOffset(mitterLimit);

            co.AddPath(p, joinType, endType);
            var solution = new List <List <IntPoint> >();

            co.Execute(ref solution, delta * ClipperScale);
            foreach (var poly in solution)
            {
                yield return(CreatePolyline(poly, containsCircArc, maxDiscretizationAngle + 1));
            }
        }
コード例 #15
0
        /// <summary>
        /// Discretize of <c>PolyLine2D</c> to <c>Polygon2D</c>.
        /// </summary>
        /// <param name="source">The <c>PolyLine2D</c> to discretization.</param>
        /// <param name="target">The <c>Polygon2D</c> as destination.</param>
        /// <param name="targetInxs">The <c>IList</c> as destination.</param>
        public void Discretize(IPolyLine2D source, ref IPolygon2D target, IList <int> targetInxs)
        {
            if (source == null)
            {
                return;
            }

            Point start = source.StartPoint;

            target.Add(start);
            int i       = 0;
            int lastInx = 0;

            foreach (var segment in source.Segments)
            {
                SelectSegment2DDiscretizator(segment.GetType()).Discretize(start, segment, target);
                start = segment.EndPoint;
                if (targetInxs != null)
                {
                    for (int j = lastInx; j < target.Count; j++)
                    {
                        targetInxs.Add(i);
                    }

                    lastInx = target.Count;
                }

                i++;
            }

            if (targetInxs != null)
            {
                if (source.IsClosed && (targetInxs.Count > 0))
                {
                    targetInxs[0] = targetInxs[targetInxs.Count - 1];
                }
            }
        }
コード例 #16
0
        /// <summary>
        /// Divide <c>CircularArcSegment2D</c> on straight lines polygon.
        /// </summary>
        /// <param name="start">The start point of segment.</param>
        /// <param name="source">The segment to discretization.</param>
        /// <param name="target">The <c>Region2D</c> as target of discretization.</param>
        public void Discretize(Point start, ISegment2D source, IPolygon2D target)
        {
            CircularArcSegment2D segment = source as CircularArcSegment2D;

            // The angle in degrees
            double totalAngle = Math.Abs(segment.GetAngle(ref start));

            if (angle < totalAngle || this.numberOfTiles > 1)
            {
                int numberOfTiles = Math.Max((int)Math.Ceiling(totalAngle / angle), this.numberOfTiles);

                double deltaAngle = totalAngle / numberOfTiles * segment.IsCounterClockwise(ref start);
                Matrix mat        = new Matrix();
                Point  centre     = segment.GetCentre(ref start);
                for (int i = 1; i < numberOfTiles; ++i)
                {
                    mat.RotateAt(deltaAngle, centre.X, centre.Y);
                    target.Add(mat.Transform(start));
                }
            }

            target.Add(segment.EndPoint);
        }
コード例 #17
0
        internal static IPolyLine3D ConvertTo3D(IPolygon2D polygon2D, Func <double, double, IPoint3D> createPoint, IMatrix44 lcs = null)
        {
            if (polygon2D == null)
            {
                return(null);
            }

            var count = polygon2D.Count;

            if (count > 1)
            {
                var polyline3D = new PolyLine3D();
                var beg        = createPoint(polygon2D[0].X, polygon2D[0].Y);
                for (var i = 1; i < count; ++i)
                {
                    var end = createPoint(polygon2D[i].X, polygon2D[i].Y);
                    var seg = new LineSegment3D(beg, end);
                    polyline3D.Add(seg);
                    beg = end;
                }

                if (polygon2D.IsClosed)
                {
                    polyline3D.Segments.Last().EndPoint = polyline3D.Segments.First().StartPoint;
                }

                if (lcs != null)
                {
                    GeomOperation.TransformToGCS(lcs, polyline3D);
                }

                return(polyline3D);
            }

            return(null);
        }
コード例 #18
0
        /// <summary>
        /// Checks for intersection between a polygon and a circle.
        /// </summary>
        /// <param name="polygon">The circle.</param>
        /// <param name="circle">The polygon.</param>
        /// <returns>True if the two shapes intersect.  False othwerise.</returns>
        public static bool Intersects(IPolygon2D polygon, ICircle2D circle)
        {
            // See if the closest point of each edge to the circle's center is inside the center
            Vector2 circleCenter = circle.Center;

            for (int i = 0; i < polygon.NumSides; i++)
            {
                Vector2 closestPointOfEdge =
                    (i == polygon.NumSides - 1 ?
                     ShapeUtility.CalculateClosestPointOnEdge(circleCenter, polygon.Vertices[i], polygon.Vertices[0]) :
                     ShapeUtility.CalculateClosestPointOnEdge(circleCenter, polygon.Vertices[i], polygon.Vertices[i + 1]));
                if (circle.Contains(closestPointOfEdge))
                {
                    return(true);
                }
            }

            // See if this polygon contains the other circle
            if (polygon.Contains(circle.Center))
            {
                return(true);
            }
            return(false);
        }
コード例 #19
0
        /// <summary>
        /// Triangulates this polygon using the two ears theorem. This is O(n^2).
        /// </summary>
        /// <remarks>
        /// Currently runs in O(n^2) time.
        /// TODO improve this to O(n log n) or O(n log log n).
        /// </remarks>
        /// <param name="polygon"></param>
        /// <param name="setTwinPointers"> whether the triangulation should set twin pointers </param>
        /// <returns>A list of clockwise triangles whose disjoint union is this polygon</returns>
        public static Triangulation Triangulate(IPolygon2D polygon, bool setTwinPointers = true)
        {
            // cannot yet triangulate non-simple polygons

            /* assume it to be, checks takes too long
             * if (!polygon.IsSimple())
             * {
             *  throw new ArgumentException("Polygon must be simple: " + polygon);
             * }
             */

            if (polygon.VertexCount < 3)
            {
                return(new Triangulation());
            }

            var T = TriangulateRecursive(polygon.Vertices.ToList());

            if (setTwinPointers)
            {
                T.SetTwinPointers();
            }
            return(T);
        }
コード例 #20
0
ファイル: ShapeCircle.cs プロジェクト: raphaelmun/MonoXen
 public bool Intersects(IPolygon2D other)
 {
     return(ShapeUtility.Intersects(other, this));
 }
コード例 #21
0
ファイル: ConvexHull.cs プロジェクト: HSJMDMG/CHGame
 /// <summary>
 /// Computes the lower hull of the given polygon
 /// </summary>
 /// <param name="polygon"></param>
 /// <returns></returns>
 public static List <Vector2> ComputeLowerHull(IPolygon2D polygon)
 {
     return(ComputeHull(polygon.Vertices, -1));
 }
コード例 #22
0
ファイル: PolygonExtent.cs プロジェクト: raphaelmun/MonoXen
 public override bool Intersects(IPolygon2D other)
 {
     return(ShapeUtility.Intersects(this, other));
 }
コード例 #23
0
 public bool Equals(IPolygon2D other)
 {
     throw new NotImplementedException();
 }
コード例 #24
0
        public void Add(IPolygon2D polygon, PolyType type)
        {
            var p = CreatePolygon(polygon);

            this.clipper.AddPath(p, type, polygon.IsClosed);
        }
コード例 #25
0
ファイル: ExtentBase.cs プロジェクト: raphaelmun/MonoXen
 public abstract bool Intersects(IPolygon2D other);
コード例 #26
0
ファイル: SpriteBatchEx.cs プロジェクト: raphaelmun/MonoXen
 public static void DrawPolygon(this SpriteBatch spriteBatch, IPolygon2D polygon, Color color)
 {
     DrawPolygon(spriteBatch, polygon.Vertices, polygon.NumSides, color, Matrix.Identity);
 }
コード例 #27
0
ファイル: SpriteBatchEx.cs プロジェクト: raphaelmun/MonoXen
 public static void DrawPolygon(this SpriteBatch spriteBatch, IPolygon2D polygon, Color color, Matrix transformFromWorldToCamera)
 {
     DrawPolygon(spriteBatch, polygon.Vertices, polygon.NumSides, color, transformFromWorldToCamera);
 }
コード例 #28
0
 /// <summary>
 /// Finds the closets point on the polygon to the specified point.
 /// </summary>
 /// <param name="point">The point to find the closest point to.</param>
 /// <param name="polygon">The polygon on which to find the closets point.</param>
 /// <returns>The point on the polygon that is closest to the specified point.</returns>
 public static Vector2 FindClosestPointOnPolygon(Vector2 point, IPolygon2D polygon)
 {
     return(FindClosestPointOnPolygon(point, polygon.Vertices, polygon.NumSides));
 }
コード例 #29
0
 /// <summary>
 /// Checks to see whether the specified point lies in the specified complex polygon.  Complex polygon here
 /// means that the polygon may contain convex vertices.
 /// </summary>
 /// <param name="point">The point to check containment for.</param>
 /// <param name="polygon">The polygon to check containment for.</param>
 /// <returns>True if the point lies within the polygon, false otherwise.</returns>
 public static bool ContainsForComplexPolygon(Vector2 point, IPolygon2D polygon)
 {
     return(ContainsForComplexPolygon(point, polygon.Vertices, polygon.NumSides));
 }
コード例 #30
0
 /// <summary>
 /// Calculates the vector pointing to the nearest point on the polygon if the center is at 0,0.
 /// </summary>
 /// <param name="shape">The polygon.</param>
 /// <returns>The vector pointing to the nearest point on the polygon if the center is at 0,0.</returns>
 public static Vector2 CalculateInnerRadius(IPolygon2D shape)
 {
     return(shape.FindClosestPoint(shape.Center) - shape.Center);
 }