Beispiel #1
0
    /// <summary>
		/// Constructor.
		/// </summary>
		/// <param name="x1">x-coordinate for line start point</param>
		/// <param name="y1">y-coordinate for line start point</param>
		/// <param name="x2">x-coordinate for line end point</param>
		/// <param name="y2">y-coordinate for line end point</param>
    /// <returns>None</returns>
    public XYLine(double x1, double y1, double x2, double y2)
		{
			_p1 = new XYPoint();
			_p2 = new XYPoint();
			_p1.X = x1;
			_p1.Y = y1;
			_p2.X = x2;
			_p2.Y = y2;
		}
Beispiel #2
0
    /// <summary>
		/// Constructor.
		/// </summary>
		/// <param name="point1">Line start point</param>
		/// <param name="point2">Line end point</param>
    /// <returns>None</returns>
    public XYLine(XYPoint point1, XYPoint point2)
		{
			_p1 = new XYPoint();
			_p2 = new XYPoint();

			_p1.X = point1.X;
			_p1.Y = point1.Y;;
			_p2.X = point2.X;
			_p2.Y = point2.Y;
		}
 public void Equals()
 {
   XYPoint p1 = new XYPoint(2,3);
   XYPoint p2 = new XYPoint(2,3);
   XYPoint p3 = new XYPoint(2,-3);
   XYLine l1 = new XYLine(2,3,3,4);
   Assert.AreEqual(true, p1.Equals(p1),"Test1");
   Assert.AreEqual(true, p1.Equals(p2),"Test2");
   Assert.AreEqual(false, p1.Equals(p3),"Test3");
   Assert.AreEqual(false, p1.Equals(l1),"Test4");
 }
Beispiel #4
0
        public void PropertyTest()
        {
            XYPoint xypoint = new XYPoint(2,3);
            Assert.AreEqual((double) 2, xypoint.X);
            Assert.AreEqual((double) 3, xypoint.Y);

            xypoint.X = 6;
            xypoint.Y = 7;
            Assert.AreEqual((double) 6, xypoint.X);
            Assert.AreEqual((double) 7, xypoint.Y);
        }
        /// <summary>
        /// Add point to the search tree, thereby building the tree.
        /// </summary>
        /// <param name="point">xy point to add</param>
        public void Add(XYPoint point)
        {
            if (HasElements)
            {
                throw new Exception("Can not add nodes when tree has elements");
            }
            bool added = _head.Add(point);

            if (added)
            {
                _numNodes++;
            }
        }
Beispiel #6
0
        /// <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)
        {
            double x = 0;
            double y = 0;
            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;
            bool intersected = false;

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

                if (((((j != im1) && (j != i)) && (j != ip1)) && XYGeometryTools.IsPointInPolygon(x, y, localPolygon)))
                {
                    return(true);
                }
                else
                {
                    j++;
                }
            }
            return(false);
        }
Beispiel #7
0
        /// <summary>
        /// Calculate intersection point between two line segments.
        /// </summary>
        /// <param name="p1">First point in first line</param>
        /// <param name="p2">Second point in first line</param>
        /// <param name="p3">First point in second line</param>
        /// <param name="p4">Second point in second line</param>
        /// <returns>Intersection point</returns>
        public static XYPoint CalculateIntersectionPoint(XYPoint p1, XYPoint p2, XYPoint p3, XYPoint p4)
        {
            if (!DoLineSegmentsIntersect(p1,p2,p3,p4))
            {
                throw new System.Exception("Attempt to calculate intersection point between non intersecting lines. CalculateIntersectionPoint failed.");
            }

            XYPoint interSectionPoint = new XYPoint();

            double a = p1.X * p2.Y - p2.X * p1.Y;
            double b = p3.X * p4.Y - p4.X * p3.Y;
            double c = (p1.X - p2.X) * (p3.Y - p4.Y) - (p3.X - p4.X) * (p1.Y - p2.Y);

            interSectionPoint.X = (a * (p3.X - p4.X) - (b * (p1.X - p2.X))) / c;
            interSectionPoint.Y = (a * (p3.Y - p4.Y) - (b * (p1.Y - p2.Y))) / c;

            return interSectionPoint;
        }
        /// <summary>
        /// Calculate intersection point between two line segments.
        /// </summary>
        /// <param name="p1">First point in first line</param>
        /// <param name="p2">Second point in first line</param>
        /// <param name="p3">First point in second line</param>
        /// <param name="p4">Second point in second line</param>
        /// <returns>Intersection point</returns>
        public static XYPoint CalculateIntersectionPoint(XYPoint p1, XYPoint p2, XYPoint p3, XYPoint p4)
        {
            if (!DoLineSegmentsIntersect(p1, p2, p3, p4))
            {
                throw new System.Exception("Attempt to calculate intersection point between non intersecting lines. CalculateIntersectionPoint failed.");
            }

            XYPoint interSectionPoint = new XYPoint();

            double a = p1.X * p2.Y - p2.X * p1.Y;
            double b = p3.X * p4.Y - p4.X * p3.Y;
            double c = (p1.X - p2.X) * (p3.Y - p4.Y) - (p3.X - p4.X) * (p1.Y - p2.Y);

            interSectionPoint.X = (a * (p3.X - p4.X) - (b * (p1.X - p2.X))) / c;
            interSectionPoint.Y = (a * (p3.Y - p4.Y) - (b * (p1.Y - p2.Y))) / c;

            return(interSectionPoint);
        }
        /// <summary>
        /// Finds the shortest distance between any line segment of the polyline
        /// and the point.
        /// </summary>
        /// <param name="polyLine">PolyLine.</param>
        /// <param name="point">Point</param>
        /// <returns>
        ///	<p>Length of the shortest path between the polyline and the point.</p>
        /// </returns>
        public static double CalculatePolylineToPointDistance(XYPolyline polyLine, XYPoint point)
        {
            double dist = 0;
            int    i    = 0;

            while (i < polyLine.Points.Count - 1)
            {
                if (i == 0)
                {
                    dist = CalculateLineToPointDistance(polyLine.GetLine(0), point);
                }
                else
                {
                    dist = Math.Min(dist, CalculateLineToPointDistance(polyLine.GetLine(i), point));
                }
                i++;
            }
            return(dist);
        }
            public bool Add(XYPoint point)
            {
                bool added = false;

                // Check if inside this domain
                if (!_extent.Contains(point.X, point.Y))
                {
                    return(false);
                }

                // If has children, add recursively
                if (HasChildren)
                {
                    foreach (TreeNode child in _children)
                    {
                        added |= child.Add(point);
                    }
                }
                else // it does not have children, add it here
                {
                    // Check if it already exists
                    foreach (XYPoint existingPoint in _points)
                    {
                        if (point.X == existingPoint.X && point.Y == existingPoint.Y)
                        {
                            return(false); // It did exist, do nothing
                        }
                    }
                    // Add point
                    _points.Add(point);
                    added = true;

                    // Check if we should subdivide
                    if (_points.Count > MaxPointsPerNode)
                    {
                        SubDivide();
                    }
                }
                return(added);
            }
Beispiel #11
0
        /// <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()
        {
            int i   = 0;
            int im1 = 0;
            int ip1 = 0;
            int n   = 0;

            XYPolygon LocalPolygon = new XYPolygon(this);
            ArrayList TriangleList = new ArrayList();

            while (LocalPolygon.Points.Count > 3)
            {
                i   = LocalPolygon.FindEar();
                n   = LocalPolygon.Points.Count;
                im1 = i - 1;
                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);
        }
Beispiel #12
0
        /// <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)
        {
            // TODO: Implement new algorithm - it is not very robust.
            // Consider an approach similar to the one used by DotSpatial and Java Topology Suite

            try
            {
                if (triangleA.Points.Count != 3 || triangleB.Points.Count != 3)
                {
                    throw new System.Exception("Argument must be a polygon with 3 points");
                }

                // TODO: implement an epsilon depending on the two triangles at hand.
                //XYExtent extentA = XYExtentUtil.GetExtent(triangleA);
                //XYExtent extentB = XYExtentUtil.GetExtent(triangleB);
                //double scalingLength
                //  = Math.Max(extentA.XMax - extentA.XMin,
                //    Math.Max(extentA.YMax - extentA.YMin,
                //    Math.Max(extentB.XMax - extentB.XMin, extentB.YMax - extentB.YMin)));
                //double epsilon = EPSILON * scalingLength;

                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 = 0;                              // Intersection area. Returned.
                XYPolygon intersectionPolygon = new XYPolygon(); // Intersection polygon.
                XYPoint   pFirst     = new XYPoint();            // First intersection point between triangles
                XYPoint   pIntersect = new XYPoint();            // Latest intersection node found

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

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

                        // The sideOf tells if the vb vector or the va vector is the one pointing "left"
                        // If sideOf is positive, vb is pointing left, otherwise va is pointing left
                        // The "left" vector is the one that is inside the polygon.
                        double sideOf = vax * vby - vay * vbx;

                        // Make sure to get out of EPSILON reach from the original point, hence 2*EPSILON
                        if (sideOf < 0 && IsPointInPolygon(pIntersect.X + 2 * EPSILON * vax, pIntersect.Y + 2 * EPSILON * vay, triangleB))
                        {
                            Intersect(triangleA, triangleB, ref pIntersect, ref i, ref j, ref intersectionPolygon);
                        }
                        else if (sideOf > 0 && IsPointInPolygon(pIntersect.X + 2 * EPSILON * vbx, pIntersect.Y + 2 * EPSILON * vby, triangleA))
                        {
                            Intersect(triangleB, triangleA, ref pIntersect, ref j, ref i, ref intersectionPolygon);
                        }
                        // can be true if the point is on the edge of the triangleB
                        // TODO: Replace with IsPointOnEdge of triangleB
                        else if (IsPointInPolygonOrOnEdge(pIntersect.X + 2 * EPSILON * vax, pIntersect.Y + 2 * EPSILON * vay, triangleB))
                        {
                            Intersect(triangleA, triangleB, ref pIntersect, ref i, ref j, ref intersectionPolygon);
                        }
                        // can be true if the point is on the edge of the triangleA
                        // Should never happen, since above test basically does the same
                        // TODO: Replace with IsPointOnEdge of triangleA
                        else if (IsPointInPolygonOrOnEdge(pIntersect.X + 2 * EPSILON * vbx, pIntersect.Y + 2 * EPSILON * vby, triangleA))
                        {
                            Intersect(triangleB, triangleA, ref pIntersect, 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(pIntersect, pFirst) < EPSILON);
                        }
                        count++;
                        if (count > 20)
                        {
                            throw new System.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 (System.Exception e)
            {
                throw new System.Exception("TriangleIntersectionArea failed", e);
            }
        }
        /// <summary>
        /// Calculate intersection point between two line segments with
        /// translation to local coordinates for improved precision.
        /// </summary>
        /// <param name="p1">First point in first line</param>
        /// <param name="p2">Second point in first line</param>
        /// <param name="p3">First point in second line</param>
        /// <param name="p4">Second point in second line</param>
        /// <returns>Intersection point</returns>
        public static XYPoint CalculateIntersectionPointWithTranslation(XYPoint p1, XYPoint p2, XYPoint p3, XYPoint p4)
        {
            // Like CalculateIntersectionPoint except that points are translated to local origin for calculation, then
            // translated back to original coordinate system for return. ERB 8/30/2012
            if (!DoLineSegmentsIntersect(p1, p2, p3, p4))
            {
                throw new System.Exception("Attempt to calculate intersection point between non intersecting lines. CalculateIntersectionPointWithTranslation failed.");
            }

            // Define local origin as p1.X, p1.Y.

            double originX = p1.X;
            double originY = p1.Y;

            // Determine local coordinates of points 2, 3, and 4
            XYPoint lp2 = new XYPoint(p2.X - originX, p2.Y - originY);
            XYPoint lp3 = new XYPoint(p3.X - originX, p3.Y - originY);
            XYPoint lp4 = new XYPoint(p4.X - originX, p4.Y - originY);

            XYPoint interSectionPoint = new XYPoint();

            // Apply Cramer's Rule in local coordinate system, simplified because point p1 is defined as origin
            double b      = lp3.X * lp4.Y - lp4.X * lp3.Y;
            double c      = -lp2.X * (lp3.Y - lp4.Y) - (lp3.X - lp4.X) * (-lp2.Y);
            double localX = (b * lp2.X) / c;
            double localY = (b * lp2.Y) / c;

            // Translate back to original coordinate system
            interSectionPoint.X = localX + originX;
            interSectionPoint.Y = localY + originY;

            return(interSectionPoint);
        }
 /// <summary>
 /// Finds the shortest distance between any line segment of the polyline 
 /// and the point.
 /// </summary>
 /// <param name="polyLine">PolyLine.</param>
 /// <param name="point">Point</param>
 /// <returns>
 ///	<p>Length of the shortest path between the polyline and the point.</p>
 /// </returns>
 public static double CalculatePolylineToPointDistance (XYPolyline polyLine, XYPoint point)
 {
   double dist = 0;
   int i = 0;
   while (i < polyLine.Points.Count - 1) 
   {
     if (i == 0) 
     {
       dist = CalculateLineToPointDistance (polyLine.GetLine(0), point);
     }
     else
     {
       dist = Math.Min(dist, CalculateLineToPointDistance (polyLine.GetLine(i), point));
     }
     i++;
   }
   return dist;
 }
		/// <summary>
		/// OverLoad of DoLineSegmentsIntersect(x1, y1, x2, y2, x3, y3, x4, y4)
		/// </summary>
		/// <param name="p1">First point in first line</param>
		/// <param name="p2">Second point in first line</param>
		/// <param name="p3">First point in second line</param>
		/// <param name="p4">Second point in second line</param>
		/// <returns>true if the line segmenst intersects otherwise false</returns>
    public static bool DoLineSegmentsIntersect(XYPoint p1, XYPoint p2, XYPoint p3, XYPoint p4)
		{
			return DoLineSegmentsIntersect(p1.X, p1.Y, p2.X, p2.Y, p3.X, p3.Y, p4.X, p4.Y);
		}
 public void Protected_IsPointInLineInterior()
 {
   XYPoint point = new XYPoint();
   Assert.AreEqual(false,AXYGeometryTools.AIsPointInLineInterior(new XYPoint(0,0), new XYLine(0, 0, 1, 1)),"Test1");
   Assert.AreEqual(true,AXYGeometryTools.AIsPointInLineInterior(new XYPoint(0.5,0.5), new XYLine(0, 0, 1, 1)),"Test2");
   Assert.AreEqual(false,AXYGeometryTools.AIsPointInLineInterior(new XYPoint(1,1), new XYLine(0, 0, 1, 1)),"Test3");
   Assert.AreEqual(false,AXYGeometryTools.AIsPointInLineInterior(new XYPoint(0.5,0), new XYLine(0, 0, 1, 1)),"Test4");
   Assert.AreEqual(false,AXYGeometryTools.AIsPointInLineInterior(new XYPoint(20,40), new XYLine(20, 40, 20, 0)),"Test5");
 }
 /// <summary>
 /// Determines if a point is included in a lines interior. I.e. included 
 /// in the line and not an endpoint. 
 /// <p>Overload to:IsPointInLineInterior(double x, double y, XYLine line)</p>
 /// </summary>
 /// <param name="point">Point.</param>
 /// <param name="line">Line.</param>
 /// <returns>
 ///	<p>Determines if a point is included in a line.</p>
 /// </returns>
 protected static bool IsPointInLineInterior(XYPoint point, XYLine line)
 {
   return IsPointInLineInterior( point.X, point.Y, line);
 }
Beispiel #18
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="x1">x-coordinate for line start point</param>
 /// <param name="y1">y-coordinate for line start point</param>
 /// <param name="x2">x-coordinate for line end point</param>
 /// <param name="y2">y-coordinate for line end point</param>
 /// <returns>None</returns>
 public XYLine(double x1, double y1, double x2, double y2)
 {
     P1 = new XYPoint(x1, y1);
     P2 = new XYPoint(x2, y2);
 }
 /// <summary>
 /// Determines if a point is included in a lines interior. I.e. included
 /// in the line and not an endpoint.
 /// <p>Overload to:IsPointInLineInterior(double x, double y, XYLine line)</p>
 /// </summary>
 /// <param name="point">Point.</param>
 /// <param name="line">Line.</param>
 /// <returns>
 ///	<p>Determines if a point is included in a line.</p>
 /// </returns>
 protected static bool IsPointInLineInterior(XYPoint point, XYLine line)
 {
     return(IsPointInLineInterior(point.X, point.Y, line));
 }
Beispiel #20
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <returns>None</returns>
 public XYLine()
 {
     _p1 = new XYPoint();
     _p2 = new XYPoint();
 }
    /// <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.XYPoint)
        {
          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.XYPolyLine)
        {
          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.GetXCoordinate(i,j),elementSet.GetYCoordinate(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.XYPolygon)
        {
          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.GetXCoordinate(i,j),elementSet.GetYCoordinate(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.ID+" is invalid",e);
      }
		}
 public static bool AIsPointInLineInterior(XYPoint point, XYLine line)
 {
   return IsPointInLineInterior(point, line);
 } 
 public static bool AIntersectionPoint(XYLine lineA, XYLine lineB, ref XYPoint intersectionPoint)
 {
   return IntersectionPoint(lineA, lineB, ref intersectionPoint);
 }
 public static double ACalculateLineToPointDistance(XYLine line, XYPoint point)
 {
   return CalculateLineToPointDistance(line, point);
 }
        /// <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)
        {
            var lineList = new List <XYLine> {
                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, lineList[n].P2));
                        lineList[n].P2.X = IntersectionPoint.X;
                        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));
                        lineList[i].P2.X = polygon.GetLine(j).P1.X;
                        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);
        }
    /// <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 System.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 = 0; // Intersection area. Returned.
        XYPolygon intersectionPolygon = new XYPolygon(); // Intersection polygon.
        XYPoint pFirst = new XYPoint(); // 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)
        { 
          int jStop = Increase(j, 2);
          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 System.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 (System.Exception e)
      {
        throw new System.Exception("TriangleIntersectionArea failed",e);
      }
    }
        /// <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      = new XYLine(lineA);
                    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);
            }
        }
		/// <summary>
		/// Returns the distance between the two points.
		/// </summary>
		/// <param name="p1">Point</param>
		/// <param name="p2">Point</param>
		/// <returns>Point to point distance</returns>
		public static double CalculatePointToPointDistance(XYPoint p1, XYPoint p2)
		{
		return Math.Sqrt( (p1.X-p2.X)*(p1.X-p2.X)+(p1.Y -p2.Y )*(p1.Y -p2.Y ) );
		}
Beispiel #29
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="point1">Line start point</param>
        /// <param name="point2">Line end point</param>
        /// <returns>None</returns>
        public XYLine(XYPoint point1, XYPoint point2)
        {
            P1 = new XYPoint();
            P2 = new XYPoint();

            P1.X = point1.X;
            P1.Y = point1.Y;;
            P2.X = point2.X;
            P2.Y = point2.Y;
        }
	  private XYPoint CreateXYPoint(IElementSet elementSet, int index)
	  {
		  if (elementSet.ElementType != ElementType.XYPoint)
		  {
			  throw new System.Exception("Cannot create XYPoint");
		  }

		  XYPoint xyPoint = new XYPoint();
		  xyPoint.X = elementSet.GetXCoordinate(index,0);
		  xyPoint.Y = elementSet.GetYCoordinate(index,0);
		  return xyPoint;
	  }
    /// <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);
      }
    }
Beispiel #32
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <returns>None</returns>
 public XYPoint(XYPoint xypoint)
 {
     X = xypoint.X;
     Y = xypoint.Y;
 }
 /// <summary>
 /// Checks if the lines lineA and lineB shares a point either as a real 
 /// crossing point or as a shared end point or a end point of the one 
 /// line being in the other line.
 /// </summary>
 /// <param name="Linea">Line.</param>
 /// <param name="Lineb">Line.</param>
 /// <param name="intersectionPoint">Point.</param>
 /// <returns>
 ///	<p>True if lineA and lineB has shared point. False otherwise</p>
 ///	<p>The shared point if any is returned in the intersectionPoint 
 ///	parameter that is called by reference</p>
 /// </returns>
 protected static bool IntersectionPoint(XYLine Linea, XYLine Lineb, ref XYPoint intersectionPoint)
 {
   if( DoLineSegmentsIntersect(Linea, Lineb))
   {
     intersectionPoint = CalculateIntersectionPoint(Linea, Lineb);
     return true;
   }
   if( IsPointInLine(Linea.P2, Lineb))
   {
     intersectionPoint = Linea.P2;
     return true;
   }
   if( IsPointInLine(Lineb.P2, Linea))
   {
     intersectionPoint = Lineb.P2;
     return true;
   }
   if( IsPointInLine(Lineb.P1, Linea))
   {
     intersectionPoint = Lineb.P1;
     return true;
   }
   if( IsPointInLine(Linea.P1, Lineb))
   {
     intersectionPoint = Linea.P1;
     return true;
   }
   return false;
 }
Beispiel #34
0
    /// <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)
    {
      double x = 0;
      double y = 0;
      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;
      bool intersected = false;
      while (((j < n-1) && (!intersected)))
      {
        x = ((XYPoint) Points[j]).X;
        y = ((XYPoint) Points[j]).Y;

        if (((((j!=im1) && (j!=i)) && (j!=ip1)) && XYGeometryTools.IsPointInPolygon(x,y,localPolygon)))
        {
          return true;
        }
        else
        {
          j++;
        }
      }
      return false;
    }      
 /// <summary>
 /// Calculates the distance from a polyline to a point in the plane. 
 /// The algorithm decides weather the point lies besides the line 
 /// segment in which case the distance is the length along a line 
 /// perpendicular to the line. Alternatively the distance is the 
 /// smallest of the distances to either endpoint.
 /// </summary>
 /// <param name="line">Line</param>
 /// <param name="point">Point</param>
 /// <returns>
 ///	<p>Length of the shortest path between the line and the point.</p>
 /// </returns>
 protected static double CalculateLineToPointDistance (XYLine line, XYPoint point)
 {
   double dist = 0;
   double a = Math.Sqrt((line.P2.X-point.X)*(line.P2.X-point.X) + (line.P2.Y-point.Y)*(line.P2.Y-point.Y));
   double b = Math.Sqrt((line.P2.X-line.P1.X)*(line.P2.X-line.P1.X)+(line.P2.Y-line.P1.Y)*(line.P2.Y-line.P1.Y));
   double c = Math.Sqrt((line.P1.X-point.X)*(line.P1.X-point.X)+(line.P1.Y-point.Y)*(line.P1.Y-point.Y));
   if ((a == 0) || (c == 0))
   {
     dist = 0;
   }
   else if (b == 0)
   {
     dist = a;
   }
   else
   {
     double alpha = Math.Acos((b*b+c*c-a*a)/(2*b*c));
     double beta = Math.Acos((a*a+b*b-c*c)/(2*a*b));
     if (Math.Max(alpha,beta)<Math.PI/2)
     {
       dist = Math.Abs((line.P2.X-line.P1.X)*(line.P1.Y-point.Y)-(line.P1.X-point.X)*(line.P2.Y-line.P1.Y))/b;
     }
     else
     {
       dist = Math.Min(a, c);
     }
   }
   return dist;
 }
Beispiel #36
0
   /// <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()
   {
     int i = 0;
     int im1 = 0;
     int ip1 = 0;
     int n = 0;
     
     XYPolygon LocalPolygon = new XYPolygon(this);
 	  ArrayList TriangleList = new ArrayList();
     while (LocalPolygon.Points.Count > 3)
     {
       i = LocalPolygon.FindEar();
       n = LocalPolygon.Points.Count;
       im1 = i-1;
       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;
   }
    /// <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);
    }  
Beispiel #38
0
        /// <summary>
        /// Calculate intersection point between two line segments with 
        /// translation to local coordinates for improved precision.
        /// </summary>
        /// <param name="p1">First point in first line</param>
        /// <param name="p2">Second point in first line</param>
        /// <param name="p3">First point in second line</param>
        /// <param name="p4">Second point in second line</param>
        /// <returns>Intersection point</returns>
        public static XYPoint CalculateIntersectionPointWithTranslation(XYPoint p1, XYPoint p2, XYPoint p3, XYPoint p4)
        {
            // Like CalculateIntersectionPoint except that points are translated to local origin for calculation, then
            // translated back to original coordinate system for return. ERB 8/30/2012
            if (!DoLineSegmentsIntersect(p1, p2, p3, p4))
            {
                throw new System.Exception("Attempt to calculate intersection point between non intersecting lines. CalculateIntersectionPointWithTranslation failed.");
            }

            // Define local origin as p1.X, p1.Y.

            double originX = p1.X;
            double originY = p1.Y;

            // Determine local coordinates of points 2, 3, and 4
            XYPoint lp2 = new XYPoint(p2.X - originX, p2.Y - originY);
            XYPoint lp3 = new XYPoint(p3.X - originX, p3.Y - originY);
            XYPoint lp4 = new XYPoint(p4.X - originX, p4.Y - originY);

            XYPoint interSectionPoint = new XYPoint();

            // Apply Cramer's Rule in local coordinate system, simplified because point p1 is defined as origin
            double b = lp3.X * lp4.Y - lp4.X * lp3.Y;
            double c = -lp2.X * (lp3.Y - lp4.Y) - (lp3.X - lp4.X) * (-lp2.Y);
            double localX = (b * lp2.X) / c;
            double localY = (b * lp2.Y) / c;

            // Translate back to original coordinate system
            interSectionPoint.X = localX + originX;
            interSectionPoint.Y = localY + originY;

            return interSectionPoint;
        }
Beispiel #39
0
 public static XYPoint CreateVector(XYPoint from, XYPoint to)
 {
     return(new XYPoint(to.X - from.X, to.Y - from.Y));
 }
Beispiel #40
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <returns>None</returns>
 public XYLine()
 {
     P1 = new XYPoint();
     P2 = new XYPoint();
 }
Beispiel #41
0
    /// <summary>
    /// Constructor.
    /// </summary>
    /// <returns>None</returns>
    public XYPoint(XYPoint xypoint)
	  {
		  _x = xypoint.X;
		  _y = xypoint.Y;
	  }
 /// <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));
 }
        /// <summary>
        /// Calculates the length that two lines overlap.
        /// </summary>
        /// <param name="lineA">Line</param>
        /// <param name="lineB">Line</param>
        /// <returns>
        /// Length of shared line segment.
        /// </returns>
        protected static double CalculateSharedLength(XYLine lineA, XYLine lineB)
        {
            if (Math.Abs(lineA.P2.X - lineA.P1.X) < EPSILON && Math.Abs(lineB.P2.X - lineB.P1.X) < EPSILON && Math.Abs(lineA.P1.X - lineB.P1.X) < EPSILON)
            {
                double YP1A = Math.Min(lineA.P1.Y, lineA.P2.Y);
                double YP2A = Math.Max(lineA.P1.Y, lineA.P2.Y);
                double YP1B = Math.Min(lineB.P1.Y, lineB.P2.Y);
                double YP2B = Math.Max(lineB.P1.Y, lineB.P2.Y);

                double YP1 = Math.Max(YP1A, YP1B);
                double YP2 = Math.Min(YP2A, YP2B);
                if (YP1 < YP2)
                {
                    return(YP2 - YP1);
                }
                else
                {
                    return(0);
                }
            }
            else if (Math.Abs(lineA.P2.X - lineA.P1.X) < EPSILON || Math.Abs(lineB.P2.X - lineB.P1.X) < EPSILON)
            {
                return(0);
            }
            else
            {
                XYPoint P1A = new XYPoint();
                XYPoint P2A = new XYPoint();
                if (lineA.P1.X < lineA.P2.X)
                {
                    P1A = lineA.P1;
                    P2A = lineA.P2;
                }
                else
                {
                    P1A = lineA.P2;
                    P2A = lineA.P1;
                }
                XYPoint P1B = new XYPoint();
                XYPoint P2B = new XYPoint();
                if (lineB.P1.X < lineB.P2.X)
                {
                    P1B = lineB.P1;
                    P2B = lineB.P2;
                }
                else
                {
                    P1B = lineB.P2;
                    P2B = lineB.P1;
                }

                double alphaA = (P2A.Y - P1A.Y) / (P2A.X - P1A.X);
                double betaA  = -alphaA * P2A.X + P2A.Y;
                double alphaB = (P2B.Y - P1B.Y) / (P2B.X - P1B.X);
                double betaB  = -alphaA * P2B.X + P2B.Y;
                if (Math.Abs(alphaA - alphaB) < EPSILON && Math.Abs(betaA - betaB) < EPSILON)
                {
                    double x1 = Math.Max(P1A.X, P1B.X);
                    double x2 = Math.Min(P2A.X, P2B.X);
                    if (x1 < x2)
                    {
                        XYLine line = new XYLine(x1, alphaA * x1 + betaA, x2, alphaA * x2 + betaA);
                        return(line.GetLength());
                    }
                    else
                    {
                        return(0);
                    }
                }
                else
                {
                    return(0);
                }
            }
        }
Beispiel #44
0
        /// <summary>
        /// Calculates the mapping matrix between fromElements and toElements. The mapping method
        /// is decided from the combination of methodDescription, fromElements.ElementType and
        /// toElements.ElementType.
        /// The valid values for methodDescription is obtained through use of the
        /// GetAvailableMethods method.
        /// </summary>
        ///
        /// <remarks>
        /// UpdateMappingMatrix is called during initialisation. UpdateMappingMatrix must be called prior
        /// to Mapvalues.
        /// </remarks>
        ///
        /// <param name="methodIdentifier">String identification of mapping method</param>
        /// <param name="fromElements">The IElementset to map from.</param>
        /// <param name="toElements">The IElementset to map to</param>
        ///
        /// <returns>
        /// The method has no return value.
        /// </returns>
        private void UpdateMappingMatrix(ref IIdentifiable methodIdentifier, ref IElementSet fromElements, ref IElementSet toElements)
        {
            try
            {
                ElementSetChecker.CheckElementSet(fromElements);
                ElementSetChecker.CheckElementSet(toElements);

                _method              = SpatialAdaptedOutputFactory.GetMethod(methodIdentifier);
                _numberOfToRows      = toElements.ElementCount;
                _numberOfFromColumns = fromElements.ElementCount;
                _mappingMatrix       = new DoubleSparseMatrix(_numberOfToRows, _numberOfFromColumns);

                if (fromElements.ElementType == ElementType.Point && toElements.ElementType == ElementType.Point)
                {
                    #region

                    try
                    {
                        for (int i = 0; i < _numberOfToRows; i++)
                        {
                            XYPoint toPoint = CreateXYPoint(toElements, i);
                            for (int j = 0; j < _numberOfFromColumns; j++)
                            {
                                XYPoint fromPoint = CreateXYPoint(fromElements, j);
                                _mappingMatrix[i, j] = XYGeometryTools.CalculatePointToPointDistance(toPoint, fromPoint);
                            }
                        }

                        if (_method == ElementMapperMethod.Nearest)
                        {
                            for (int i = 0; i < _numberOfToRows; i++)
                            {
                                double minDist = _mappingMatrix[i, 0];
                                for (int j = 1; j < _numberOfFromColumns; j++)
                                {
                                    if (_mappingMatrix[i, j] < minDist)
                                    {
                                        minDist = _mappingMatrix[i, j];
                                    }
                                }
                                int denominator = 0;
                                for (int j = 0; j < _numberOfFromColumns; j++)
                                {
                                    if (_mappingMatrix[i, j] == minDist)
                                    {
                                        _mappingMatrix[i, j] = 1;
                                        denominator++;
                                    }
                                    else
                                    {
                                        _mappingMatrix[i, j] = 0;
                                    }
                                }
                                for (int j = 0; j < _numberOfFromColumns; j++)
                                {
                                    _mappingMatrix[i, j] = _mappingMatrix[i, j] / denominator;
                                }
                            }
                        }
                        else if (_method == ElementMapperMethod.Inverse)
                        {
                            for (int i = 0; i < _numberOfToRows; i++)
                            {
                                double minDist = _mappingMatrix[i, 0];
                                for (int j = 1; j < _numberOfFromColumns; j++)
                                {
                                    if (_mappingMatrix[i, j] < minDist)
                                    {
                                        minDist = _mappingMatrix[i, j];
                                    }
                                }
                                if (minDist == 0)
                                {
                                    int denominator = 0;
                                    for (int j = 0; j < _numberOfFromColumns; j++)
                                    {
                                        if (_mappingMatrix[i, j] == minDist)
                                        {
                                            _mappingMatrix[i, j] = 1;
                                            denominator++;
                                        }
                                        else
                                        {
                                            _mappingMatrix[i, j] = 0;
                                        }
                                    }
                                    for (int j = 0; j < _numberOfFromColumns; j++)
                                    {
                                        _mappingMatrix[i, j] = _mappingMatrix[i, j] / denominator;
                                    }
                                }
                                else
                                {
                                    double denominator = 0;
                                    for (int j = 0; j < _numberOfFromColumns; j++)
                                    {
                                        _mappingMatrix[i, j] = 1 / _mappingMatrix[i, j];
                                        denominator          = denominator + _mappingMatrix[i, j];
                                    }
                                    for (int j = 0; j < _numberOfFromColumns; j++)
                                    {
                                        _mappingMatrix[i, j] = _mappingMatrix[i, j] / denominator;
                                    }
                                }
                            }
                        }
                        else
                        {
                            throw new Exception("methodDescription unknown for point point mapping");
                        }
                    }
                    catch (Exception e)
                    {
                        throw new Exception("Point to point mapping failed", e);
                    }

                    #endregion
                }
                else if (fromElements.ElementType == ElementType.Point && toElements.ElementType == ElementType.PolyLine)
                {
                    #region

                    try
                    {
                        for (int i = 0; i < _numberOfToRows; i++)
                        {
                            XYPolyline toPolyLine = CreateXYPolyline(toElements, i);
                            for (int j = 0; j < _numberOfFromColumns; j++)
                            {
                                XYPoint fromPoint = CreateXYPoint(fromElements, j);
                                _mappingMatrix[i, j] = XYGeometryTools.CalculatePolylineToPointDistance(toPolyLine,
                                                                                                        fromPoint);
                            }
                        }

                        if (_method == ElementMapperMethod.Nearest)
                        {
                            for (int i = 0; i < _numberOfToRows; i++)
                            {
                                double minDist = _mappingMatrix[i, 0];
                                for (int j = 1; j < _numberOfFromColumns; j++)
                                {
                                    if (_mappingMatrix[i, j] < minDist)
                                    {
                                        minDist = _mappingMatrix[i, j];
                                    }
                                }
                                int denominator = 0;
                                for (int j = 0; j < _numberOfFromColumns; j++)
                                {
                                    if (_mappingMatrix[i, j] == minDist)
                                    {
                                        _mappingMatrix[i, j] = 1;
                                        denominator++;
                                    }
                                    else
                                    {
                                        _mappingMatrix[i, j] = 0;
                                    }
                                }
                                for (int j = 0; j < _numberOfFromColumns; j++)
                                {
                                    _mappingMatrix[i, j] = _mappingMatrix[i, j] / denominator;
                                }
                            }
                        }
                        else if (_method == ElementMapperMethod.Inverse)
                        {
                            for (int i = 0; i < _numberOfToRows; i++)
                            {
                                double minDist = _mappingMatrix[i, 0];
                                for (int j = 1; j < _numberOfFromColumns; j++)
                                {
                                    if (_mappingMatrix[i, j] < minDist)
                                    {
                                        minDist = _mappingMatrix[i, j];
                                    }
                                }
                                if (minDist == 0)
                                {
                                    int denominator = 0;
                                    for (int j = 0; j < _numberOfFromColumns; j++)
                                    {
                                        if (_mappingMatrix[i, j] == minDist)
                                        {
                                            _mappingMatrix[i, j] = 1;
                                            denominator++;
                                        }
                                        else
                                        {
                                            _mappingMatrix[i, j] = 0;
                                        }
                                    }
                                    for (int j = 0; j < _numberOfFromColumns; j++)
                                    {
                                        _mappingMatrix[i, j] = _mappingMatrix[i, j] / denominator;
                                    }
                                }
                                else
                                {
                                    double denominator = 0;
                                    for (int j = 0; j < _numberOfFromColumns; j++)
                                    {
                                        _mappingMatrix[i, j] = 1 / _mappingMatrix[i, j];
                                        denominator          = denominator + _mappingMatrix[i, j];
                                    }
                                    for (int j = 0; j < _numberOfFromColumns; j++)
                                    {
                                        _mappingMatrix[i, j] = _mappingMatrix[i, j] / denominator;
                                    }
                                }
                            }
                        }
                        else
                        {
                            throw new Exception("methodDescription unknown for point to polyline mapping");
                        }
                    }
                    catch (Exception e)
                    {
                        throw new Exception("Point to polyline mapping failed", e);
                    }

                    #endregion
                }
                else if (fromElements.ElementType == ElementType.Point &&
                         toElements.ElementType == ElementType.Polygon)
                {
                    #region

                    try
                    {
                        for (int i = 0; i < _numberOfToRows; i++)
                        {
                            XYPolygon polygon = CreateXYPolygon(toElements, i);
                            int       count   = 0;
                            XYPoint   point;
                            for (int n = 0; n < _numberOfFromColumns; n++)
                            {
                                point = CreateXYPoint(fromElements, n);
                                if (XYGeometryTools.IsPointInPolygon(point, polygon))
                                {
                                    if (_method == ElementMapperMethod.Mean)
                                    {
                                        count = count + 1;
                                    }
                                    else if (_method == ElementMapperMethod.Sum)
                                    {
                                        count = 1;
                                    }
                                    else
                                    {
                                        throw new Exception(
                                                  "methodDescription unknown for point to polygon mapping");
                                    }
                                }
                            }
                            for (int n = 0; n < _numberOfFromColumns; n++)
                            {
                                point = CreateXYPoint(fromElements, n);

                                if (XYGeometryTools.IsPointInPolygon(point, polygon))
                                {
                                    _mappingMatrix[i, n] = 1.0 / count;
                                }
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        throw new Exception("Point to polygon mapping failed", e);
                    }

                    #endregion
                }
                else if (fromElements.ElementType == ElementType.PolyLine &&
                         toElements.ElementType == ElementType.Point)
                {
                    #region

                    try
                    {
                        for (int i = 0; i < _numberOfToRows; i++)
                        {
                            XYPoint toPoint = CreateXYPoint(toElements, i);
                            for (int j = 0; j < _numberOfFromColumns; j++)
                            {
                                XYPolyline fromPolyLine = CreateXYPolyline(fromElements, j);
                                _mappingMatrix[i, j] =
                                    XYGeometryTools.CalculatePolylineToPointDistance(fromPolyLine, toPoint);
                            }
                        }

                        if (_method == ElementMapperMethod.Nearest)
                        {
                            for (int i = 0; i < _numberOfToRows; i++)
                            {
                                double minDist = _mappingMatrix[i, 0];
                                for (int j = 1; j < _numberOfFromColumns; j++)
                                {
                                    if (_mappingMatrix[i, j] < minDist)
                                    {
                                        minDist = _mappingMatrix[i, j];
                                    }
                                }
                                int denominator = 0;
                                for (int j = 0; j < _numberOfFromColumns; j++)
                                {
                                    if (_mappingMatrix[i, j] == minDist)
                                    {
                                        _mappingMatrix[i, j] = 1;
                                        denominator++;
                                    }
                                    else
                                    {
                                        _mappingMatrix[i, j] = 0;
                                    }
                                }
                                for (int j = 0; j < _numberOfFromColumns; j++)
                                {
                                    _mappingMatrix[i, j] = _mappingMatrix[i, j] / denominator;
                                }
                            }
                        }
                        else if (_method == ElementMapperMethod.Inverse)
                        {
                            for (int i = 0; i < _numberOfToRows; i++)
                            {
                                double minDist = _mappingMatrix[i, 0];
                                for (int j = 1; j < _numberOfFromColumns; j++)
                                {
                                    if (_mappingMatrix[i, j] < minDist)
                                    {
                                        minDist = _mappingMatrix[i, j];
                                    }
                                }
                                if (minDist == 0)
                                {
                                    int denominator = 0;
                                    for (int j = 0; j < _numberOfFromColumns; j++)
                                    {
                                        if (_mappingMatrix[i, j] == minDist)
                                        {
                                            _mappingMatrix[i, j] = 1;
                                            denominator++;
                                        }
                                        else
                                        {
                                            _mappingMatrix[i, j] = 0;
                                        }
                                    }
                                    for (int j = 0; j < _numberOfFromColumns; j++)
                                    {
                                        _mappingMatrix[i, j] = _mappingMatrix[i, j] / denominator;
                                    }
                                }
                                else
                                {
                                    double denominator = 0;
                                    for (int j = 0; j < _numberOfFromColumns; j++)
                                    {
                                        _mappingMatrix[i, j] = 1 / _mappingMatrix[i, j];
                                        denominator          = denominator + _mappingMatrix[i, j];
                                    }
                                    for (int j = 0; j < _numberOfFromColumns; j++)
                                    {
                                        _mappingMatrix[i, j] = _mappingMatrix[i, j] / denominator;
                                    }
                                }
                            }
                        }
                        else
                        {
                            throw new Exception("methodDescription unknown for polyline to point mapping");
                        }
                    }
                    catch (Exception e) // Catch for all of the Point to Polyline part
                    {
                        throw new Exception("Polyline to point mapping failed", e);
                    }

                    #endregion
                }
                else if (fromElements.ElementType == ElementType.PolyLine &&
                         toElements.ElementType == ElementType.Polygon)
                {
                    #region

                    try
                    {
                        // For each polygon in target
                        for (int i = 0; i < _numberOfToRows; i++)
                        {
                            XYPolygon polygon = CreateXYPolygon(toElements, i);

                            if (_method == ElementMapperMethod.WeightedMean)
                            {
                                double totalLineLengthInPolygon = 0;
                                for (int n = 0; n < _numberOfFromColumns; n++)
                                {
                                    XYPolyline polyline = CreateXYPolyline(fromElements, n);
                                    _mappingMatrix[i, n] =
                                        XYGeometryTools.CalculateLengthOfPolylineInsidePolygon(
                                            polyline, polygon);
                                    totalLineLengthInPolygon += _mappingMatrix[i, n];
                                }
                                if (totalLineLengthInPolygon > 0)
                                {
                                    for (int n = 0; n < _numberOfFromColumns; n++)
                                    {
                                        _mappingMatrix[i, n] = _mappingMatrix[i, n] /
                                                               totalLineLengthInPolygon;
                                    }
                                }
                            }
                            else if (_method == ElementMapperMethod.WeightedSum)
                            {
                                // For each line segment in PolyLine
                                for (int n = 0; n < _numberOfFromColumns; n++)
                                {
                                    XYPolyline polyline = CreateXYPolyline(fromElements, n);
                                    _mappingMatrix[i, n] =
                                        XYGeometryTools.CalculateLengthOfPolylineInsidePolygon(
                                            polyline, polygon) / polyline.GetLength();
                                }
                            }
                            else
                            {
                                throw new Exception(
                                          "methodDescription unknown for polyline to polygon mapping");
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        throw new Exception("Polyline to polygon mapping failed", e);
                    }

                    #endregion
                }
                else if (fromElements.ElementType == ElementType.Polygon &&
                         toElements.ElementType == ElementType.Point)
                {
                    #region

                    try
                    {
                        if (_method != ElementMapperMethod.Value)
                        {
                            throw new Exception("methodDescription unknown for polygon to point mapping");
                        }

                        // Only create search tree if number of cols/rows is larger than say 10/10.
                        bool useSearchTree = _numberOfFromColumns > 10 && _numberOfToRows > 10;
                        XYElementSearchTree <int> fromSearchTree     = null;
                        ICollection <int>         fromCandidateElmts = null;
                        if (useSearchTree)
                        {
                            fromSearchTree = XYElementSearchTree <int> .BuildSearchTree(fromElements);
                        }
                        else
                        {
                            fromCandidateElmts = new IntSequence(0, _numberOfFromColumns - 1);
                        }

                        for (int n = 0; n < _numberOfToRows; n++)
                        {
                            XYPoint point = CreateXYPoint(toElements, n);
                            if (useSearchTree)
                            {
                                XYExtent toExtent = XYExtentUtil.GetExtent(point, XYGeometryTools.EPSILON);
                                fromCandidateElmts = fromSearchTree.FindElements(toExtent);
                            }

                            int count = 0;

                            // Check first for strict inclusion
                            foreach (int i in fromCandidateElmts)
                            {
                                XYPolygon polygon = CreateXYPolygon(fromElements, i);
                                if (XYGeometryTools.IsPointInPolygon(point, polygon))
                                {
                                    _mappingMatrix[n, i] = 1.0;
                                    count++;
                                }
                            }
                            if (count == 0)
                            {
                                // Not strictly inside any polygon, check also edges
                                foreach (int i in fromCandidateElmts)
                                {
                                    XYPolygon polygon = CreateXYPolygon(fromElements, i);
                                    if (XYGeometryTools.IsPointInPolygonOrOnEdge(point, polygon))
                                    {
                                        _mappingMatrix[n, i] = 1.0;
                                        count++;
                                    }
                                }
                            }
                            if (count > 1)
                            {
                                // In case of more than one hit, use average
                                foreach (int i in fromCandidateElmts)
                                {
                                    if (_mappingMatrix[n, i] != 0.0)
                                    {
                                        _mappingMatrix[n, i] = 1.0 / count;
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        throw new Exception("Polygon to point mapping failed", e);
                    }

                    #endregion
                }
                else if (fromElements.ElementType == ElementType.Polygon &&
                         toElements.ElementType == ElementType.PolyLine)
                // Polygon to PolyLine
                {
                    #region

                    try
                    {
                        for (int i = 0; i < _numberOfToRows; i++)
                        {
                            XYPolyline polyline = CreateXYPolyline(toElements, i);

                            if (_method == ElementMapperMethod.WeightedMean)
                            {
                                for (int n = 0; n < _numberOfFromColumns; n++)
                                {
                                    XYPolygon polygon = CreateXYPolygon(fromElements, n);
                                    _mappingMatrix[i, n] =
                                        XYGeometryTools.CalculateLengthOfPolylineInsidePolygon(
                                            polyline, polygon) / polyline.GetLength();
                                }
                                double sum = 0;
                                for (int n = 0; n < _numberOfFromColumns; n++)
                                {
                                    sum += _mappingMatrix[i, n];
                                }
                                for (int n = 0; n < _numberOfFromColumns; n++)
                                {
                                    _mappingMatrix[i, n] = _mappingMatrix[i, n] / sum;
                                }
                            }
                            else if (_method == ElementMapperMethod.WeightedSum)
                            {
                                for (int n = 0; n < _numberOfFromColumns; n++)
                                {
                                    XYPolygon polygon = CreateXYPolygon(fromElements, n);
                                    _mappingMatrix[i, n] =
                                        XYGeometryTools.CalculateLengthOfPolylineInsidePolygon(
                                            polyline, polygon) / polyline.GetLength();
                                }
                            }
                            else
                            {
                                throw new Exception(
                                          "methodDescription unknown for polygon to polyline mapping");
                            }
                        }
                    }
                    catch (Exception e) // catch for all of Polygon to PolyLine
                    {
                        throw new Exception("Polygon to polyline mapping failed", e);
                    }

                    #endregion
                }
                else if (fromElements.ElementType == ElementType.Polygon &&
                         toElements.ElementType == ElementType.Polygon)
                // Polygon to Polygon
                {
                    #region

                    try
                    {
                        // Only create search tree if number of cols/rows is larger than say 100/10.
                        bool useSearchTree = _numberOfFromColumns > 10 && _numberOfToRows > 10;
                        XYElementSearchTree <int> fromSearchTree     = null;
                        ICollection <int>         fromCandidateElmts = null;
                        if (useSearchTree)
                        {
                            fromSearchTree = XYElementSearchTree <int> .BuildSearchTree(fromElements);
                        }
                        else
                        {
                            fromCandidateElmts = new IntSequence(0, _numberOfFromColumns - 1);
                        }

                        for (int i = 0; i < _numberOfToRows; i++)
                        {
                            XYPolygon toPolygon = CreateXYPolygon(toElements, i);
                            if (useSearchTree)
                            {
                                XYExtent toExtent = XYExtentUtil.GetExtent(toPolygon);
                                fromCandidateElmts = fromSearchTree.FindElements(toExtent);
                            }

                            foreach (int j in fromCandidateElmts)
                            {
                                XYPolygon fromPolygon = CreateXYPolygon(fromElements, j);
                                _mappingMatrix[i, j] = XYGeometryTools.CalculateSharedArea(
                                    toPolygon, fromPolygon);
                                if (_method == ElementMapperMethod.Distribute)
                                {
                                    _mappingMatrix[i, j] /= fromPolygon.GetArea();
                                }
                            }

                            if (_method == ElementMapperMethod.WeightedMean)
                            {
                                double denominator = 0;
                                foreach (int j in fromCandidateElmts)
                                {
                                    denominator = denominator + _mappingMatrix[i, j];
                                }
                                foreach (int j in fromCandidateElmts)
                                {
                                    if (denominator != 0)
                                    {
                                        _mappingMatrix[i, j] = _mappingMatrix[i, j] / denominator;
                                    }
                                }
                            }
                            else if (_method == ElementMapperMethod.WeightedSum)
                            {
                                foreach (int j in fromCandidateElmts)
                                {
                                    _mappingMatrix[i, j] = _mappingMatrix[i, j] / toPolygon.GetArea();
                                }
                            }
                            else if (_method != ElementMapperMethod.Distribute)
                            {
                                throw new Exception(
                                          "methodDescription unknown for polygon to polygon mapping");
                            }
                        }
                    }
                    catch (Exception e) // catch for all of Polygon to Polygon
                    {
                        throw new Exception("Polygon to polygon mapping failed", e);
                    }

                    #endregion
                }
                else // if the fromElementType, toElementType combination is no implemented
                {
                    throw new Exception(
                              "Mapping of specified ElementTypes not included in ElementMapper");
                }
            }
            catch (Exception e)
            {
                throw new Exception("UpdateMappingMatrix failed to update mapping matrix", e);
            }
        }
        /// <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 System.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 = 0;                              // Intersection area. Returned.
                XYPolygon intersectionPolygon = new XYPolygon(); // Intersection polygon.
                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);

                if (j != -1)
                {
                    // ERB 8/30/2012: For efficiency, allocate and initialize pFirst inside if block
                    XYPoint pFirst = new XYPoint(); // First intersection point between triangles
                    pFirst = p;
                    int  jStop    = Increase(j, 2);
                    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 System.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 (System.Exception e)
            {
                throw new System.Exception("TriangleIntersectionArea failed", e);
            }
        }
Beispiel #46
0
        /// <summary>
        /// Constructor. Copies input line.
        /// </summary>
        /// <param name="line">Line to copy</param>
        public XYLine(XYLine line)
        {
            P1 = new XYPoint();
            P2 = new XYPoint();

            P1.X = line.P1.X;
            P1.Y = line.P1.Y;
            P2.X = line.P2.X;
            P2.Y = line.P2.Y;
        }
 /// <summary>
 /// Returns the distance between the two points.
 /// </summary>
 /// <param name="p1">Point</param>
 /// <param name="p2">Point</param>
 /// <returns>Point to point distance</returns>
 public static double CalculatePointToPointDistance(XYPoint p1, XYPoint p2)
 {
     return(Math.Sqrt((p1.X - p2.X) * (p1.X - p2.X) + (p1.Y - p2.Y) * (p1.Y - p2.Y)));
 }
    /// <summary>
    /// Calculates the length that two lines overlap.
    /// </summary>
    /// <param name="lineA">Line</param>
    /// <param name="lineB">Line</param>
    /// <returns>
    /// Length of shared line segment.
    /// </returns>
    protected static double CalculateSharedLength(XYLine lineA, XYLine lineB)
    {
		  if ( Math.Abs(lineA.P2.X-lineA.P1.X)<EPSILON && Math.Abs(lineB.P2.X-lineB.P1.X)<EPSILON &&Math.Abs(lineA.P1.X-lineB.P1.X)<EPSILON)
		  {
			  double YP1A = Math.Min(lineA.P1.Y, lineA.P2.Y);
			  double YP2A = Math.Max(lineA.P1.Y, lineA.P2.Y);
			  double YP1B = Math.Min(lineB.P1.Y, lineB.P2.Y);
			  double YP2B = Math.Max(lineB.P1.Y, lineB.P2.Y);

			  double YP1 = Math.Max(YP1A, YP1B);
			  double YP2 = Math.Min(YP2A, YP2B);
			  if (YP1 < YP2) 
			  {
				  return YP2-YP1;
			  }
			  else
			  {
				  return 0;
			  }
		  }
		  else if(Math.Abs(lineA.P2.X-lineA.P1.X)<EPSILON || Math.Abs(lineB.P2.X-lineB.P1.X)<EPSILON)
		  {
			  return 0;
		  }
		  else
		  {
			  XYPoint P1A = new XYPoint();
			  XYPoint P2A = new XYPoint();
			  if (lineA.P1.X < lineA.P2.X)
			  {
				  P1A = lineA.P1;
				  P2A = lineA.P2;
			  }
			  else
			  {
				  P1A = lineA.P2;
				  P2A = lineA.P1;
			  }
			  XYPoint P1B = new XYPoint();
			  XYPoint P2B = new XYPoint();
			  if (lineB.P1.X < lineB.P2.X)
			  {
				  P1B = lineB.P1;
				  P2B = lineB.P2;
			  }
			  else
			  {
				  P1B = lineB.P2;
				  P2B = lineB.P1;
			  }

			  double alphaA = (P2A.Y - P1A.Y)/(P2A.X - P1A.X);
			  double betaA = -alphaA*P2A.X + P2A.Y;
			  double alphaB = (P2B.Y - P1B.Y)/(P2B.X - P1B.X);
			  double betaB = -alphaA*P2B.X + P2B.Y;
			  if (Math.Abs(alphaA-alphaB)<EPSILON && Math.Abs(betaA-betaB)<EPSILON)
			  {
				  double x1 = Math.Max(P1A.X, P1B.X);
				  double x2 = Math.Min(P2A.X, P2B.X);
				  if (x1 < x2)
				  {
					  XYLine line = new XYLine(x1, alphaA*x1+betaA, x2, alphaA*x2+betaA);
					  return line.GetLength();
				  }
				  else
				  {
					  return 0;
				  }
			  }
			  else
			  {
				  return 0;
			  }
		  }
    }
Beispiel #49
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <returns>None</returns>
 public XYLine()
 {
     P1 = new XYPoint();
     P2 = new XYPoint();
 }
    /// <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;
		}
 /// <summary>
 /// OverLoad of DoLineSegmentsIntersect(x1, y1, x2, y2, x3, y3, x4, y4)
 /// </summary>
 /// <param name="p1">First point in first line</param>
 /// <param name="p2">Second point in first line</param>
 /// <param name="p3">First point in second line</param>
 /// <param name="p4">Second point in second line</param>
 /// <returns>true if the line segmenst intersects otherwise false</returns>
 public static bool DoLineSegmentsIntersect(XYPoint p1, XYPoint p2, XYPoint p3, XYPoint p4)
 {
     return(DoLineSegmentsIntersect(p1.X, p1.Y, p2.X, p2.Y, p3.X, p3.Y, p4.X, p4.Y));
 }
Beispiel #52
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="x1">x-coordinate for line start point</param>
 /// <param name="y1">y-coordinate for line start point</param>
 /// <param name="x2">x-coordinate for line end point</param>
 /// <param name="y2">y-coordinate for line end point</param>
 /// <returns>None</returns>
 public XYLine(double x1, double y1, double x2, double y2)
 {
     P1 = new XYPoint(x1, y1);
     P2 = new XYPoint(x2, y2);
 }
 /// <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.XYPoint)
         {
             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.XYPolyLine)
         {
             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.GetXCoordinate(i, j), elementSet.GetYCoordinate(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.XYPolygon)
         {
             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.GetXCoordinate(i, j), elementSet.GetYCoordinate(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.ID + " is invalid", e);
     }
 }
Beispiel #54
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <returns>None</returns>
 public XYPoint(XYPoint xypoint)
 {
     _x = xypoint.X;
     _y = xypoint.Y;
 }