Esempio n. 1
0
        //=====================================================================
        // GetTriangulation() : ElementSet
        //=====================================================================
        /// <summary>
        /// Returns an ArrayList of triangles of type XYPolygon describing the
        /// triangalation of the polygon.
        /// </summary>
        /// <param></param>
        /// <returns>
        /// A triangulation of the polygon.
        /// </returns>
        public ArrayList GetTriangulation()
        {
            XYPolygon LocalPolygon = new XYPolygon(this);
            ArrayList TriangleList = new ArrayList();

            while (LocalPolygon.Points.Count > 3)
            {
                int i   = LocalPolygon.FindEar();
                int n   = LocalPolygon.Points.Count;
                int im1 = i - 1;
                int ip1 = i + 1;
                if (i == 0)
                {
                    im1 = n - 1;
                }
                else if (i == n - 1)
                {
                    ip1 = 0;
                }
                XYPoint   Nodeim1  = new XYPoint((XYPoint)LocalPolygon.Points[im1]);
                XYPoint   Nodei    = new XYPoint((XYPoint)LocalPolygon.Points[i]);
                XYPoint   Nodeip1  = new XYPoint((XYPoint)LocalPolygon.Points[ip1]);
                XYPolygon Triangle = new XYPolygon();
                Triangle.Points.Add(Nodeim1);
                Triangle.Points.Add(Nodei);
                Triangle.Points.Add(Nodeip1);
                TriangleList.Add(Triangle);
                LocalPolygon.Points.RemoveAt(i);
            }
            TriangleList.Add(LocalPolygon);
            return(TriangleList);
        }
Esempio n. 2
0
 //=====================================================================
 // XYPolygon(XYPolygon xyPolygon): void
 //=====================================================================
 /// <summary>
 /// Constructor. Copies the contents of the xyPolygon parameter.
 /// </summary>
 /// <param name="xyPolygon">Polygon to copy.</param>
 /// <returns>None</returns>
 public XYPolygon(XYPolygon xyPolygon)
 {
     //	Points = new ArrayList();
     foreach (XYPoint xypoint in xyPolygon.Points)
     {
         Points.Add(new XYPoint(xypoint.X, xypoint.Y));
     }
 }
Esempio n. 3
0
        //=====================================================================
        // IsPointInPolygon (double x, double y, XYPolygon polygon) : bool
        //=====================================================================
        /// <summary>
        /// Determines if a point in inside or outside a polygon.
        /// Works for both convex and concave polygons (Winding number test)
        /// </summary>
        /// <param name="x">x-coordinate for the point</param>
        /// <param name="y">y-coordiante for the point</param>
        /// <param name="polygon">Polygon</param>
        /// <returns>
        ///	<p>true:  If the point is inside the polygon</p>
        ///	<p>false: If the point is outside the polygon.</p>
        /// </returns>
        public static bool IsPointInPolygon(double x, double y, XYPolygon polygon)
        {
            bool isInside = false;
            int  n        = polygon.Points.Count;

            for (int i = 0; i < n; i++)
            {
                double x1;
                double x2;
                double y2;
                double y1;
                if (i < n - 1)
                {
                    x1 = ((XYPoint)polygon.Points[i]).X;
                    x2 = ((XYPoint)polygon.Points[i + 1]).X;
                    y1 = ((XYPoint)polygon.Points[i]).Y;
                    y2 = ((XYPoint)polygon.Points[i + 1]).Y;
                }
                else
                {
                    x1 = ((XYPoint)polygon.Points[n - 1]).X;
                    x2 = ((XYPoint)polygon.Points[0]).X;
                    y1 = ((XYPoint)polygon.Points[n - 1]).Y;
                    y2 = ((XYPoint)polygon.Points[0]).Y;
                }

                if (y > Math.Min(y1, y2))
                {
                    if (y <= Math.Max(y1, y2))
                    {
                        if (x <= Math.Max(x1, x2))
                        {
                            if (y1 != y2)
                            {
                                double xinters = (y - y1) * (x2 - x1) / (y2 - y1) + x1;

                                if (x1 == x2 || x <= xinters)
                                {
                                    isInside = !isInside;
                                }
                            }
                        }
                    }
                }
            }
            return(isInside);
        }
Esempio n. 4
0
        //=====================================================================
        // CalculateSharedArea (XYPolygon polygonA, XYPolygon polygonB) : double
        //=====================================================================
        /// <summary>
        /// The methods calculates the shared area of two arbitrarily shaped
        /// polygons.
        /// </summary>
        /// <param name="polygonA">Polygon</param>
        /// <param name="polygonB">Polygon</param>
        /// <returns>
        ///	<p>The shared area.</p>
        /// </returns>
        public static double CalculateSharedArea(XYPolygon polygonA, XYPolygon polygonB)
        {
            ArrayList triangleListA = polygonA.GetTriangulation();
            ArrayList triangleListB = polygonB.GetTriangulation();

            double area = 0;

            for (int ia = 0; ia < triangleListA.Count; ia++)
            {
                XYPolygon triangleA = new XYPolygon((XYPolygon)triangleListA[ia]);
                for (int ib = 0; ib < triangleListB.Count; ib++)
                {
                    XYPolygon triangleB = new XYPolygon((XYPolygon)triangleListB[ib]);
                    area = area + TriangleIntersectionArea(triangleA, triangleB);
                }
            }
            return(area);
        }
Esempio n. 5
0
        //=====================================================================
        // IsIntersected(integer i) : bool
        //=====================================================================
        /// <summary>
        /// The method decides if the triangle formed by  P(i-1), P(i) and
        /// P(i+1) from Polygon are intersected by any of the other points
        /// of the polygon.
        /// </summary>
        /// <param name="i">Middle index for the three points that forms the triangle</param>
        /// <returns>
        ///	<p>true: If the triangle P(i-1), P(i), P(i+1) is intersected by other parts of Polygon</p>
        ///	<p>false: otherwise</p>
        /// </returns>
        protected bool IsIntersected(int i)
        {
            int n = Points.Count;

            int im1 = i - 1;
            int ip1 = i + 1;

            if (i == 0)
            {
                im1 = n - 1;
            }
            else if (i == n - 1)
            {
                ip1 = 0;
            }

            XYPoint   nodeim1      = new XYPoint((XYPoint)Points[im1]);
            XYPoint   nodei        = new XYPoint((XYPoint)Points[i]);
            XYPoint   nodeip1      = new XYPoint((XYPoint)Points[ip1]);
            XYPolygon localPolygon = new XYPolygon();

            localPolygon.Points.Add(nodeim1);
            localPolygon.Points.Add(nodei);
            localPolygon.Points.Add(nodeip1);

            int j = 0;

            while (((j < n - 1)))
            {
                double x = ((XYPoint)Points[j]).X;
                double y = ((XYPoint)Points[j]).Y;

                if (((((j != im1) && (j != i)) && (j != ip1)) && XYGeometryTools.IsPointInPolygon(x, y, localPolygon)))
                {
                    return(true);
                }
                else
                {
                    j++;
                }
            }
            return(false);
        }
Esempio n. 6
0
        //=====================================================================
        // IsPointInPolygonOrOnEdge (double x, double y, XYPolygon polygon) : bool
        //=====================================================================
        /// <summary>
        /// Determines if a point in inside or outside a polygon. Inside
        /// includes on the edge for this method.
        /// Works for both convex and concave polygons (Winding number test)
        /// </summary>
        /// <param name="x">x-coordinate for the point</param>
        /// <param name="y">y-coordiante for the point</param>
        /// <param name="polygon">Polygon</param>
        /// <returns>
        ///	<p>true:  If the point is inside the polygon</p>
        ///	<p>false: If the point is outside the polygon.</p>
        /// </returns>
        protected static bool IsPointInPolygonOrOnEdge(double x, double y, XYPolygon polygon)
        {
            bool result = IsPointInPolygon(x, y, polygon);

            if (result)
            {
                return(result);
            }
            else
            {
                int iLine = 0;
                while ((!result) && (iLine < polygon.Points.Count))
                {
                    XYLine line;
                    line   = polygon.GetLine(iLine);
                    result = IsPointInLine(x, y, line);
                    iLine++;
                }
            }
            return(result);
        }
Esempio n. 7
0
 //===============================================================================================
 //CheckElementSet(IElementSet elementSet): void static
 //===============================================================================================
 /// <summary>
 /// Static method that validates an object with an IElementSet interface. The method
 /// raises an Exception in case IElementSet does not describe a valid ElementSet.
 /// The checks made are:
 ///   <p>ElementType: Check</p>
 ///   <p>XYPoint:     Only one vertex in each element.</p>
 ///   <p>XYPolyline:  At least two vertices in each element.</p>
 ///   <p>             All line segments in each element has length > 0</p>
 ///   <p>XYPolygon:   At least three vertices in each element.</p>
 ///   <p>             Area of each element is larger than 0</p>
 ///   <p>             All line segments in each element has length > 0</p>
 ///   <p>             No line segments within an element crosses.</p>
 /// </summary>
 ///
 /// <param name="elementSet">Object that implement the IElementSet interface</param>
 ///
 /// <returns>
 /// The method has no return value.
 /// </returns>
 public static void CheckElementSet(IElementSet elementSet)
 {
     try
     {
         if (elementSet.ElementType == ElementType.Point)
         {
             for (int i = 0; i < elementSet.ElementCount; i++)
             {
                 try
                 {
                     if (elementSet.GetVertexCount(i) != 1)
                     {
                         throw new System.Exception("Number of vertices in point element is different from 1.");
                     }
                 }
                 catch (System.Exception e)
                 {
                     throw new System.Exception("ElementID = " + elementSet.GetElementId(i), e);
                 }
             }
         }
         else if (elementSet.ElementType == ElementType.PolyLine)
         {
             for (int i = 0; i < elementSet.ElementCount; i++)
             {
                 try
                 {
                     XYPolyline xypolyline = new XYPolyline();
                     for (int j = 0; j < elementSet.GetVertexCount(i); j++)
                     {
                         XYPoint xypoint = new XYPoint(elementSet.GetVertexXCoordinate(i, j), elementSet.GetVertexYCoordinate(i, j));
                         xypolyline.Points.Add(xypoint);
                     }
                     xypolyline.Validate();
                 }
                 catch (System.Exception e)
                 {
                     throw new System.Exception("ElementID = " + elementSet.GetElementId(i), e);
                 }
             }
         }
         else if (elementSet.ElementType == ElementType.Polygon)
         {
             for (int i = 0; i < elementSet.ElementCount; i++)
             {
                 try
                 {
                     XYPolygon xypolygon = new XYPolygon();
                     for (int j = 0; j < elementSet.GetVertexCount(i); j++)
                     {
                         XYPoint xypoint = new XYPoint(elementSet.GetVertexXCoordinate(i, j), elementSet.GetVertexYCoordinate(i, j));
                         xypolygon.Points.Add(xypoint);
                     }
                     xypolygon.Validate();
                 }
                 catch (System.Exception e)
                 {
                     throw new System.Exception("ElementID = " + elementSet.GetElementId(i), e);
                 }
             }
         }
     }
     catch (System.Exception e)
     {
         throw new System.Exception("ElementSet with ID = " + elementSet.Caption + " is invalid", e);
     }
 }
Esempio n. 8
0
 //=====================================================================
 // IsPointInPolygon (XYPoint point, XYPolygon polygon) : bool
 //=====================================================================
 /// <summary>
 /// Determines if a point in inside or outside a polygon.
 /// Works for both convex and concave polygons (Winding number test)
 /// </summary>
 /// <param name="point">Point</param>
 /// <param name="polygon">Polygon</param>
 /// <returns>
 ///	<p>true:  If the point is inside the polygon</p>
 ///	<p>false: Otherwise.</p>
 /// </returns>
 public static bool IsPointInPolygon(XYPoint point, XYPolygon polygon)
 {
     return(IsPointInPolygon(point.X, point.Y, polygon));
 }
Esempio n. 9
0
        //=====================================================================
        // Intersect(XYPolygon triangleA, XYPolygon triangleB,
        //           ref XYPoint p, ref  int i, ref int j,
        //           ref XYPolygon intersectionPolygon) : void
        //=====================================================================
        /// <summary>
        /// The method calculates the intersection points of triangle a and b both
        /// of type XYPolygon.
        /// </summary>
        /// <param name="triangleA">triangle. The search is started along triangleA.</param>
        /// <param name="triangleB">triangle. Intersection with this triangle are sought.</param>
        /// <param name="p">Starting point for the search. p must be part of triangleA.</param>
        /// <param name="i">on input: End index for the first line segment of triangleA in the search.
        /// on output: End index for the last intersected line segment in triangleA.</param>
        /// <param name="j">on input: -1 if vertices before intersection is not to be added to list.
        /// on output: End index for last intersected line segment of triangleB.</param>
        /// <param name="intersectionPolygon">polygon eventuallu describing the
        /// intersection area between triangleA and triangleB</param>
        /// <returns>
        ///	The p, i, j and intersectionPolygon are called by reference and modified in the method.
        /// </returns>
        private static void Intersect(XYPolygon triangleA, XYPolygon triangleB,
                                      ref XYPoint p, ref int i, ref int j,
                                      ref XYPolygon intersectionPolygon)
        {
            XYLine lineA;
            XYLine lineB;
            int    im1    = Decrease(i, 2);       // "i-1"
            int    count1 = 0;
            bool   found  = false;

            while ((count1 < 3) && (!found))
            {
                lineA = triangleA.GetLine(im1);
                if (count1 == 0)
                {
                    lineA.P1.X = p.X;
                    lineA.P1.Y = p.Y;
                }
                double MinDist  = -1;        // Distance used when a line is crossed more than once
                int    jm1      = 0;         // "j-1"
                int    jm1Store = -1;
                while (jm1 < 3)
                {
                    lineB = triangleB.GetLine(jm1);
                    found = IntersectionPoint(lineA, lineB, ref p);
                    double Dist = CalculatePointToPointDistance(lineA.P1, p);
                    if (Dist < EPSILON)
                    {
                        found = false;
                    }
                    if (found)
                    {
                        if ((MinDist < 0) || (Dist < MinDist))
                        {
                            MinDist  = Dist;
                            jm1Store = jm1;
                        }
                    }
                    jm1++;
                }
                if (jm1Store > -1)
                {
                    lineB = triangleB.GetLine(jm1Store);
                    found = IntersectionPoint(lineA, lineB, ref p);
                    XYPoint HelpCoordinate = new XYPoint(p.X, p.Y);
                    XYPoint HelpNode       = new XYPoint(HelpCoordinate);

                    intersectionPolygon.Points.Add(HelpNode);

                    j = Increase(jm1Store, 2);
                }
                if (!found)
                {
                    count1++;
                    im1 = Increase(im1, 2);
                    i   = Increase(i, 2);
                    if (j != -1)
                    {
                        XYPoint HelpCoordinate = new XYPoint(lineA.P2.X, lineA.P2.Y);
                        XYPoint HelpNode       = new XYPoint(HelpCoordinate);
                        intersectionPolygon.Points.Add(HelpNode);
                    }
                }
            }
            lineA = triangleA.GetLine(Decrease(i, 2));
            if (CalculatePointToPointDistance(p, lineA.P2) < EPSILON)
            {
                i = Increase(i, 2);
            }
            lineB = triangleB.GetLine(Decrease(j, 2));
            if (CalculatePointToPointDistance(p, lineB.P2) < EPSILON)
            {
                j = Increase(j, 2);
            }
        }
Esempio n. 10
0
        //=====================================================================
        // TriangleIntersectionArea(XYPolygon triangleA, XYPolygon triangleB) : double
        //=====================================================================
        /// <summary>
        /// The method calculates the intersection area of triangle a and b both
        /// of type XYPolygon.
        /// </summary>
        /// <param name="triangleA">Triangle of type XYPolygon</param>
        /// <param name="triangleB">Triangle of type XYPolygon</param>
        /// <returns>
        ///	Intersection area between the triangles triangleA and triAngleB.
        /// </returns>
        protected static double TriangleIntersectionArea(XYPolygon triangleA, XYPolygon triangleB)
        {
            try
            {
                if (triangleA.Points.Count != 3 || triangleB.Points.Count != 3)
                {
                    throw new Exception("Argument must be a polygon with 3 points");
                }
                int i = 1;                                       // Index for "next" node in polygon a.
                int j = -1;                                      // Index for "next" node in polygon b.
                // -1 indicates that the first has not yet been found.
                double    area;                                  // Intersection area. Returned.
                XYPolygon intersectionPolygon = new XYPolygon(); // Intersection polygon.
                XYPoint   pFirst;                                // First intersection point between triangles
                XYPoint   p = new XYPoint();                     // Latest intersection node found

                p.X = ((XYPoint)triangleA.Points[0]).X;
                p.Y = ((XYPoint)triangleA.Points[0]).Y;
                Intersect(triangleA, triangleB, ref p, ref i, ref j, ref intersectionPolygon);
                pFirst = p;

                if (j != -1)
                {
                    bool complete = false;
                    int  count    = 0;
                    while (!complete)
                    {
                        // coordinates for vectors pointing to next triangleA and triangleB point respectively
                        double vax = ((XYPoint)triangleA.Points[i]).X - p.X;
                        double vay = ((XYPoint)triangleA.Points[i]).Y - p.Y;
                        double vbx = ((XYPoint)triangleB.Points[j]).X - p.X;
                        double vby = ((XYPoint)triangleB.Points[j]).Y - p.Y;

                        if (IsPointInPolygonOrOnEdge(p.X + EPSILON * vax, p.Y + EPSILON * vay, triangleB))
                        {
                            Intersect(triangleA, triangleB, ref p, ref i, ref j, ref intersectionPolygon);
                        }
                        else if (IsPointInPolygonOrOnEdge(p.X + EPSILON * vbx, p.Y + EPSILON * vby, triangleA))
                        {
                            Intersect(triangleB, triangleA, ref p, ref j, ref i, ref intersectionPolygon);
                        }
                        else                         // triangleA and triangleB only touches one another but do not intersect
                        {
                            area = 0;
                            return(area);
                        }
                        if (intersectionPolygon.Points.Count > 1)
                        {
                            complete = (CalculatePointToPointDistance(p, pFirst) < EPSILON);
                        }
                        count++;
                        if (count > 20)
                        {
                            throw new Exception("Failed to find intersection polygon");
                        }
                    }
                    area = intersectionPolygon.GetArea();
                }
                else
                {
                    XYPoint pa = new XYPoint();                     // internal point in triangle a
                    XYPoint pb = new XYPoint();                     // internal point in triangle b

                    pa.X = (triangleA.GetX(0) + triangleA.GetX(1) + triangleA.GetX(2)) / 3;
                    pa.Y = (triangleA.GetY(0) + triangleA.GetY(1) + triangleA.GetY(2)) / 3;
                    pb.X = (triangleB.GetX(0) + triangleB.GetX(1) + triangleB.GetX(2)) / 3;
                    pb.Y = (triangleB.GetY(0) + triangleB.GetY(1) + triangleB.GetY(2)) / 3;

                    if (IsPointInPolygon(pa, triangleB) || IsPointInPolygon(pb, triangleA))                     // triangleA is completely inside triangleB
                    {
                        area = Math.Min(triangleA.GetArea(), triangleB.GetArea());
                    }
                    else                     // triangleA and triangleB do dot intersect
                    {
                        area = 0;
                    }
                }
                return(area);
            }
            catch (Exception e)
            {
                throw new Exception("TriangleIntersectionArea failed", e);
            }
        }
Esempio n. 11
0
        //=====================================================================================
        //CalculateLengthOfLineInsidePolygon(XYLine line, XYPolygon polygon): double
        //=====================================================================================
        /// <summary>
        /// Calculates length of line inside polygon. Parts of the line that is on the edge of
        /// the polygon only counts with half their length.
        /// </summary>
        /// <param name="line">Line</param>
        /// <param name="polygon">Polygon</param>
        /// <returns>
        /// Length of line inside polygon.
        /// </returns>
        protected static double CalculateLengthOfLineInsidePolygon(XYLine line, XYPolygon polygon)
        {
            ArrayList lineList = new ArrayList();

            lineList.Add(new XYLine(line));

            for (int i = 0; i < polygon.Points.Count; i++)             // For all lines in the polygon
            {
                for (int n = 0; n < lineList.Count; n++)
                {
                    if (lineList.Count > 1000)
                    {
                        throw new Exception("Problems in ElementMapper, line has been cut in more than 1000 pieces !!!");
                    }

                    if (DoLineSegmentsIntersect((XYLine)lineList[n], polygon.GetLine(i)))
                    {
                        // Split the intersecting line into two lines
                        XYPoint IntersectionPoint = new XYPoint(CalculateIntersectionPoint((XYLine)lineList[n], polygon.GetLine(i)));
                        lineList.Add(new XYLine(IntersectionPoint, ((XYLine)lineList[n]).P2));
                        ((XYLine)lineList[n]).P2.X = IntersectionPoint.X;
                        ((XYLine)lineList[n]).P2.Y = IntersectionPoint.Y;
                        break;
                    }
                }
            }

            for (int i = 0; i < lineList.Count; i++)
            {
                if (lineList.Count > 1000)
                {
                    throw new Exception("Problems in ElementMapper, line has been cuttes in more than 100 pieces !!!");
                }
                for (int j = 0; j < polygon.Points.Count; j++)
                {
                    if (IsPointInLineInterior(polygon.GetLine(j).P1, ((XYLine)lineList[i])))
                    {
                        lineList.Add(new XYLine(polygon.GetLine(j).P1, ((XYLine)lineList[i]).P2));
                        ((XYLine)lineList[i]).P2.X = polygon.GetLine(j).P1.X;
                        ((XYLine)lineList[i]).P2.Y = polygon.GetLine(j).P1.Y;
                    }
                }
            }

            double lengthInside = 0;

            for (int i = 0; i < lineList.Count; i++)
            {
                double sharedLength = 0;
                for (int j = 0; j < polygon.Points.Count; j++)
                {
                    sharedLength += CalculateSharedLength(((XYLine)lineList[i]), polygon.GetLine(j));
                }
                if (sharedLength > EPSILON)
                {
                    lengthInside += sharedLength / 2;
                }
                else if (IsPointInPolygon(((XYLine)lineList[i]).GetMidpoint(), polygon))
                {
                    lengthInside += ((XYLine)lineList[i]).GetLength();
                }
            }
            return(lengthInside);
        }
Esempio n. 12
0
        //=========================================================================================
        //CalculateLengthOfPolylineInsidePolygon(XYPolyline polyline, XYPolygon polygon) : double
        //=========================================================================================
        /// <summary>
        /// Calculates the length of polyline inside polygon. Lines segments on the edges of
        /// polygons are included with half their length.
        /// </summary>
        /// <param name="polyline">Polyline</param>
        /// <param name="polygon">Polygon</param>
        /// <returns>
        /// Length of polyline inside polygon.
        /// </returns>
        public static double CalculateLengthOfPolylineInsidePolygon(XYPolyline polyline, XYPolygon polygon)
        {
            double lengthInside         = 0;
            int    numberOfLineSegments = polyline.Points.Count - 1;

            for (int i = 0; i < numberOfLineSegments; i++)
            {
                XYLine line = new XYLine(polyline.GetLine(i));
                lengthInside += CalculateLengthOfLineInsidePolygon(line, polygon);
            }
            return(lengthInside);
        }