Beispiel #1
0
    /// <summary>
    /// Constructor. Copies the contents of the xyPolygon parameter.
    /// </summary>
    /// <param name="xyPolygon">Polygon to copy.</param>
    /// <returns>None</returns>
    public XYPolygon(XYPolygon xyPolygon)
		{
		//	Points = new ArrayList();
			foreach (XYPoint xypoint in xyPolygon.Points)
			{
				Points.Add(new XYPoint(xypoint.X, xypoint.Y));
			}
		}
Beispiel #2
0
 /// <summary>
 /// Constructor. Copies the contents of the xyPolygon parameter.
 /// </summary>
 /// <param name="xyPolygon">Polygon to copy.</param>
 /// <returns>None</returns>
 public XYPolygon(XYPolygon xyPolygon)
 {
     //	Points = new ArrayList();
     foreach (XYPoint xypoint in xyPolygon.Points)
     {
         Points.Add(xypoint);
     }
 }
Beispiel #3
0
        public void Equals()
        {
            XYPolygon p1 = new XYPolygon();
              p1.Points.Add(new XYPoint(0, 3));
              p1.Points.Add(new XYPoint(3, 0));
              p1.Points.Add(new XYPoint(8, 0));
              p1.Points.Add(new XYPoint(8, 2));
              p1.Points.Add(new XYPoint(3, 1));
              p1.Points.Add(new XYPoint(3, 3));
              p1.Points.Add(new XYPoint(8, 3));
              p1.Points.Add(new XYPoint(4, 7));

              XYPolygon p2 = new XYPolygon();
              p2.Points.Add(new XYPoint(0, 3));
              p2.Points.Add(new XYPoint(3, 0));
              p2.Points.Add(new XYPoint(8, 0));
              p2.Points.Add(new XYPoint(8, 2));
              p2.Points.Add(new XYPoint(3, 1));
              p2.Points.Add(new XYPoint(3, 3));
              p2.Points.Add(new XYPoint(8, 3));
              p2.Points.Add(new XYPoint(4, 7));

              XYPolygon p3 = new XYPolygon();
              p3.Points.Add(new XYPoint(0, 3));
              p3.Points.Add(new XYPoint(3, 0));
              p3.Points.Add(new XYPoint(8, 0));
              p3.Points.Add(new XYPoint(8, 2));
              p3.Points.Add(new XYPoint(3, 1.1));
              p3.Points.Add(new XYPoint(3, 3));
              p3.Points.Add(new XYPoint(8, 3));
              p3.Points.Add(new XYPoint(4, 7));

              XYPolygon p4 = new XYPolygon();
              p4.Points.Add(new XYPoint(0, 3));
              p4.Points.Add(new XYPoint(3, 0));
              p4.Points.Add(new XYPoint(8, 0));
              p4.Points.Add(new XYPoint(8, 2));
              p4.Points.Add(new XYPoint(3, 1));
              p4.Points.Add(new XYPoint(3, 3));
              p4.Points.Add(new XYPoint(8, 3));

              XYPolyline p5 = new XYPolyline();
              p5.Points.Add(new XYPoint(0, 3));
              p5.Points.Add(new XYPoint(3, 0));
              p5.Points.Add(new XYPoint(8, 0));
              p5.Points.Add(new XYPoint(8, 2));
              p5.Points.Add(new XYPoint(3, 1.1));
              p5.Points.Add(new XYPoint(3, 3));
              p5.Points.Add(new XYPoint(8, 3));
              p5.Points.Add(new XYPoint(4, 7));

              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(p4),"Test4");
              Assert.AreEqual(false, p1.Equals(p5),"Test5");
        }
Beispiel #4
0
        public static XYPolygon CreateFromXYPolygon(IElementSet elementSet, int index)
        {
            if (elementSet.ElementType != ElementType.Polygon)
            {
                throw new Exception("Cannot create XYPolyline");
            }

            XYPolygon xyPolygon = new XYPolygon();

            for (int i = 0; i < elementSet.GetVertexCount(index); i++)
            {
                xyPolygon.Points.Add(new XYPoint(elementSet.GetVertexXCoordinate(index, i),
                                                 elementSet.GetVertexYCoordinate(index, i)));
            }

            return(xyPolygon);
        }
Beispiel #5
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>
        /// Determines if a point in inside or outside a polygon.
        /// Works for both convex and concave polygons (Winding number test)
        /// </summary>
        /// <param name="x">x-coordinate for the point</param>
        /// <param name="y">y-coordiante for the point</param>
        /// <param name="polygon">Polygon</param>
        /// <returns>
        ///	<p>true:  If the point is inside the polygon</p>
        ///	<p>false: If the point is outside the polygon.</p>
        /// </returns>
        public static bool IsPointInPolygon(double x, double y, XYPolygon polygon)
        {
            double x1, x2, y1, y2;
            double xinters;
            bool   isInside = false;
            int    n        = polygon.Points.Count;

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

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

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

            double area = 0;

            for (int ia = 0; ia < triangleListA.Count; ia++)
            {
                XYPolygon triangleA = new XYPolygon((XYPolygon)triangleListA[ia]);
                for (int ib = 0; ib < triangleListB.Count; ib++)
                {
                    XYPolygon triangleB = new XYPolygon((XYPolygon)triangleListB[ib]);
                    area = area + TriangleIntersectionArea(triangleA, triangleB);
                }
            }
            return(area);
        }
 protected void CalculateFactors(IElementSet elementSet)
 {
     for (int i = 0; i < elementSet.ElementCount; i++)
     {
         XYPolygon element = ElementMapper.CreateXYPolygon(elementSet, i);
         double    area    = element.GetArea();
         if (_areaExponent == 1)
         {
             _factors[i] = area;
         }
         else if (_areaExponent == -1)
         {
             _factors[i] = 1.0 / area;
         }
         else
         {
             _factors[i] = Math.Pow(area, _areaExponent);
         }
     }
 }
        /// <summary>
        /// Determines if a point in inside or outside a polygon. Inside
        /// includes on the edge for this method.
        /// Works for both convex and concave polygons (Winding number test)
        /// </summary>
        /// <param name="x">x-coordinate for the point</param>
        /// <param name="y">y-coordiante for the point</param>
        /// <param name="polygon">Polygon</param>
        /// <returns>
        ///	<p>true:  If the point is inside the polygon</p>
        ///	<p>false: If the point is outside the polygon.</p>
        /// </returns>
        protected static bool IsPointInPolygonOrOnEdge(double x, double y, XYPolygon polygon)
        {
            bool result = IsPointInPolygon(x, y, polygon);

            if (result)
            {
                return(result);
            }
            else
            {
                int iLine = 0;
                while ((!result) && (iLine < polygon.Points.Count))
                {
                    var line = polygon.GetLine(iLine);
                    result = IsPointInLine(x, y, line);
                    iLine++;
                }
            }
            return(result);
        }
		public void GetArea()
		{
			// -- Rectangle --
			XYPolygon xypolygon = new XYPolygon();
			xypolygon.Points.Add(new XYPoint(1,1));
			xypolygon.Points.Add(new XYPoint(9,1));
			xypolygon.Points.Add(new XYPoint(9,6));
			xypolygon.Points.Add(new XYPoint(1,6));
			Assert.AreEqual((double) 40, xypolygon.GetArea());

			// -- Triangle -- 
			XYPolygon xypolygon2 = new XYPolygon();
			xypolygon2.Points.Add(new XYPoint(1,1));
			xypolygon2.Points.Add(new XYPoint(9,1));
			xypolygon2.Points.Add(new XYPoint(9,6));
			Assert.AreEqual((double) 20, xypolygon2.GetArea());

			// -- concave --
			XYPolygon xypolygon3 = new XYPolygon();
			xypolygon3.Points.Add(new XYPoint(1,1));
			xypolygon3.Points.Add(new XYPoint(5,3));
			xypolygon3.Points.Add(new XYPoint(9,1));
			xypolygon3.Points.Add(new XYPoint(9,6));
			xypolygon3.Points.Add(new XYPoint(1,6));
			Assert.AreEqual((double) 32, xypolygon3.GetArea());

			// -- concave --
			XYPolygon xypolygon4 = new XYPolygon();
			xypolygon4.Points.Add(new XYPoint(1,1));
			xypolygon4.Points.Add(new XYPoint(9,1));
			xypolygon4.Points.Add(new XYPoint(5,5));
			xypolygon4.Points.Add(new XYPoint(5,3));
			xypolygon4.Points.Add(new XYPoint(3,3));
			xypolygon4.Points.Add(new XYPoint(3,8));
			xypolygon4.Points.Add(new XYPoint(9,8));
			xypolygon4.Points.Add(new XYPoint(9,11));
			xypolygon4.Points.Add(new XYPoint(1,11));
			Assert.AreEqual((double) 50, xypolygon4.GetArea());
		}
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);
        }
    /// <summary>
    /// Determines if a point in inside or outside a polygon.
    /// Works for both convex and concave polygons (Winding number test)
    /// </summary>
    /// <param name="x">x-coordinate for the point</param>
    /// <param name="y">y-coordiante for the point</param>
    /// <param name="polygon">Polygon</param>
    /// <returns>
    ///	<p>true:  If the point is inside the polygon</p>
    ///	<p>false: If the point is outside the polygon.</p>
    /// </returns>
    public static bool IsPointInPolygon(double x, double y, XYPolygon polygon)
    {
        double x1,x2,y1,y2;
        double xinters;
        bool isInside = false;
        int  n = polygon.Points.Count;

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

        if (y > Math.Min(y1,y2))
        {
          if (y <= Math.Max(y1,y2))
          {
            if ( x <= Math.Max(x1,x2))
            {
              if (y1 != y2)
              {
                xinters = (y - y1)*(x2 - x1)/(y2 - y1) + x1;
								
                if (x1 == x2 || x <= xinters)
                {
                  isInside = !isInside;
                }
              }
            }
          }
        }
      }
      return isInside;
    }
    /// <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 void Protected_CalculateLengthOfLineInsidePolygon()
    {
      XYPolygon xypolygon = new XYPolygon();
      xypolygon.Points.Add(new XYPoint(1,1));
      xypolygon.Points.Add(new XYPoint(9,1));
      xypolygon.Points.Add(new XYPoint(5,5));
      xypolygon.Points.Add(new XYPoint(5,3));
      xypolygon.Points.Add(new XYPoint(3,3));
      xypolygon.Points.Add(new XYPoint(3,8));
      xypolygon.Points.Add(new XYPoint(9,8));
      xypolygon.Points.Add(new XYPoint(9,11));
      xypolygon.Points.Add(new XYPoint(1,11));

      Assert.AreEqual(0, AXYGeometryTools.ACalculateLengthOfLineInsidePolygon(new XYLine(-2,12,11,12),xypolygon),"Test1");
      Assert.AreEqual(4, AXYGeometryTools.ACalculateLengthOfLineInsidePolygon(new XYLine(-2,11,11,11),xypolygon),"Test2");
      Assert.AreEqual(8, AXYGeometryTools.ACalculateLengthOfLineInsidePolygon(new XYLine(-2,10,11,10),xypolygon),"Test3");
      Assert.AreEqual(8, AXYGeometryTools.ACalculateLengthOfLineInsidePolygon(new XYLine(-2,9,11,9),xypolygon),"Test4");
      
      Assert.AreEqual(5, AXYGeometryTools.ACalculateLengthOfLineInsidePolygon(new XYLine(-2,8,11,8),xypolygon),"Test5");
      Assert.AreEqual(2, AXYGeometryTools.ACalculateLengthOfLineInsidePolygon(new XYLine(-2,7,11,7),xypolygon),"Test6");
      Assert.AreEqual(2, AXYGeometryTools.ACalculateLengthOfLineInsidePolygon(new XYLine(-2,5,11,5),xypolygon),"Test7");
      Assert.AreEqual(3, AXYGeometryTools.ACalculateLengthOfLineInsidePolygon(new XYLine(-2,4,11,4),xypolygon),"Test8");

      Assert.AreEqual(3, AXYGeometryTools.ACalculateLengthOfLineInsidePolygon(new XYLine(-2,4,11,4),xypolygon),"Test9");
      Assert.AreEqual(5, AXYGeometryTools.ACalculateLengthOfLineInsidePolygon(new XYLine(-2,3,11,3),xypolygon),"Test10");
      Assert.AreEqual(7, AXYGeometryTools.ACalculateLengthOfLineInsidePolygon(new XYLine(-2,2,11,2),xypolygon),"Test11");
      Assert.AreEqual(4, AXYGeometryTools.ACalculateLengthOfLineInsidePolygon(new XYLine(-2,1,11,1),xypolygon),"Test12");
      Assert.AreEqual(0, AXYGeometryTools.ACalculateLengthOfLineInsidePolygon(new XYLine(-2,0,11,0),xypolygon),"Test13");

      Assert.AreEqual(10, AXYGeometryTools.ACalculateLengthOfLineInsidePolygon(new XYLine(2,12,2,0),xypolygon),"Test14");
      Assert.AreEqual(6,  AXYGeometryTools.ACalculateLengthOfLineInsidePolygon(new XYLine(6,12,6,0),xypolygon),"Test15");
      Assert.AreEqual(Math.Sqrt(8)+1.5*Math.Sqrt(0.5),AXYGeometryTools.ACalculateLengthOfLineInsidePolygon(new XYLine(1,0.5,10,9.5),xypolygon),"Test16");
      Assert.AreEqual(1, AXYGeometryTools.ACalculateLengthOfLineInsidePolygon(new XYLine(-2,4,2,4),xypolygon),"Test17");
      Assert.AreEqual(5, AXYGeometryTools.ACalculateLengthOfLineInsidePolygon(new XYLine(4,12,4,0),xypolygon),"Test18");
    }
    public void CalculateSharedArea()
    {
      XYPolygon p1 = new XYPolygon();
      p1.Points.Add(new XYPoint(0, 3));
      p1.Points.Add(new XYPoint(3, 0));
      p1.Points.Add(new XYPoint(8, 0));
      p1.Points.Add(new XYPoint(8, 2));
      p1.Points.Add(new XYPoint(3, 1));
      p1.Points.Add(new XYPoint(3, 3));
      p1.Points.Add(new XYPoint(8, 3));
      p1.Points.Add(new XYPoint(4, 7));

      XYPolygon p2 = new XYPolygon();
      p2.Points.Add(new XYPoint(3, 3));
      p2.Points.Add(new XYPoint(4, 3));
      p2.Points.Add(new XYPoint(4, 4));
      p2.Points.Add(new XYPoint(3, 4));

      XYPolygon p3 = new XYPolygon();
      p3.Points.Add(new XYPoint(0, 0));
      p3.Points.Add(new XYPoint(8, 0));
      p3.Points.Add(new XYPoint(8, 8));
      p3.Points.Add(new XYPoint(0, 8));

      XYPolygon p4 = new XYPolygon();
      p4.Points.Add(new XYPoint(-2, 0));
      p4.Points.Add(new XYPoint(3, 0));
      p4.Points.Add(new XYPoint(3, 2));
      p4.Points.Add(new XYPoint(0, 2));
      p4.Points.Add(new XYPoint(0, 5));
      p4.Points.Add(new XYPoint(4, 5));
      p4.Points.Add(new XYPoint(4, 7));
      p4.Points.Add(new XYPoint(-2, 7));

      Assert.AreEqual(p1.GetArea(),XYGeometryTools.CalculateSharedArea(p1,p1),1e-12,"Test1 - Polygon1 in Polygon1");  
      Assert.AreEqual(p2.GetArea(),XYGeometryTools.CalculateSharedArea(p2,p2),1e-12,"Test2 - Polygon1 in Polygon1");  
      Assert.AreEqual(p4.GetArea(),XYGeometryTools.CalculateSharedArea(p4,p4),1e-12,"Test3 - Polygon1 in Polygon1");  
      Assert.AreEqual(p2.GetArea(),XYGeometryTools.CalculateSharedArea(p1,p2),1e-12,"Test4 - Polygon2 in Polygon1");  
      Assert.AreEqual(p1.GetArea(),XYGeometryTools.CalculateSharedArea(p1,p3),1e-12,"Test5 - Polygon1 in Polygon2");  
      Assert.AreEqual(4,XYGeometryTools.CalculateSharedArea(p1,p4),1e-12,"Test6 - Polygon1 in Polygon3");  
    }
        /// <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>
        /// 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);
        }
Beispiel #18
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);
            }
        }
Beispiel #19
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 #20
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;
    }      
 public static double ACalculateLengthOfLineInsidePolygon(XYLine line, XYPolygon polygon)
 {
   return CalculateLengthOfLineInsidePolygon(line, polygon);
 }
		public void Protected_TriangleIntersectionArea()
		{
			XYPolygon t1 = new XYPolygon();
			t1.Points.Add(new XYPoint(0.0, 0.5));
			t1.Points.Add(new XYPoint(6.0, 0.5));
			t1.Points.Add(new XYPoint(1.0, 7.0));

			XYPolygon t2 = new XYPolygon();
      t2.Points.Add(new XYPoint(1,1));
			t2.Points.Add(new XYPoint(5,1));
			t2.Points.Add(new XYPoint(1,5));

			XYPolygon t3 = new XYPolygon();
      t3.Points.Add(new XYPoint(1,1));
			t3.Points.Add(new XYPoint(3,1));
			t3.Points.Add(new XYPoint(1,3));

			XYPolygon t4 = new XYPolygon();
      t4.Points.Add(new XYPoint(1,2));
			t4.Points.Add(new XYPoint(3,2));
			t4.Points.Add(new XYPoint(3,4));

			XYPolygon t5 = new XYPolygon();
      t5.Points.Add(new XYPoint(6.5,3.5));
			t5.Points.Add(new XYPoint(9.5,3.4));
			t5.Points.Add(new XYPoint(7,5));

      XYPolygon t6 = new XYPolygon();
      t6.Points.Add(new XYPoint(-2,0));
      t6.Points.Add(new XYPoint(3,0));
      t6.Points.Add(new XYPoint(3,2));

			//t2 is fully inside t1	
			Assert.AreEqual(8,AXYGeometryTools.ATriangleIntersectionArea(t2,t1),"t2, t1");
      Assert.AreEqual(8,AXYGeometryTools.ATriangleIntersectionArea(t1,t2),"t1, t2");

			// t4 is partly inside t2
			Assert.AreEqual((double)7/ (double) 4, AXYGeometryTools.ATriangleIntersectionArea(t2,t4),"t2, t4");
      Assert.AreEqual((double)7/ (double) 4, AXYGeometryTools.ATriangleIntersectionArea(t4,t2),"t4, t2");

			// t3 is inside t2 but is sharing two edges
    	Assert.AreEqual(2, AXYGeometryTools.ATriangleIntersectionArea(t2,t3),"t2, t3");
    	Assert.AreEqual(2, AXYGeometryTools.ATriangleIntersectionArea(t3,t2),"t3, t2");

			// t1 and t5 has no overlap
			Assert.AreEqual(0, AXYGeometryTools.ATriangleIntersectionArea(t1,t5),"t1, t5");
			Assert.AreEqual(0, AXYGeometryTools.ATriangleIntersectionArea(t5,t1),"t5, t1");

      // two times t6
      Assert.AreEqual(t6.GetArea(), AXYGeometryTools.ATriangleIntersectionArea(t6,t6),"t6, t6");
		}
 public static bool AIsPointInPolygonOrOnEdge(double x, double y, XYPolygon polygon)
 {
   return IsPointInPolygonOrOnEdge(x, y, polygon);
 }
 /// <summary>
 /// Determines if a point in inside or outside a polygon. Inside
 /// includes on the edge for this method.
 /// Works for both convex and concave polygons (Winding number test)
 /// </summary>
 /// <param name="x">x-coordinate for the point</param>
 /// <param name="y">y-coordiante for the point</param>
 /// <param name="polygon">Polygon</param>
 /// <returns>
 ///	<p>true:  If the point is inside the polygon</p>
 ///	<p>false: If the point is outside the polygon.</p>
 /// </returns>
 protected static bool IsPointInPolygonOrOnEdge(double x, double y, XYPolygon polygon)
 {
   bool result = IsPointInPolygon(x, y, polygon);
   if( result )
   {
     return result;
   }
   else
   {
     int iLine = 0;
     while( (!result) && (iLine < polygon.Points.Count) )
     {
       XYLine line = new XYLine();
       line = polygon.GetLine(iLine);
       result = IsPointInLine(x, y, line);
       iLine++;
     }
   }
   return result;
 }
 public void GetTriangulation()
 {
   XYPolygon p1 = new XYPolygon();
   p1.Points.Add(new XYPoint(0, 3));
   p1.Points.Add(new XYPoint(3, 0));
   p1.Points.Add(new XYPoint(8, 0));
   p1.Points.Add(new XYPoint(8, 2));
   p1.Points.Add(new XYPoint(3, 1));
   p1.Points.Add(new XYPoint(3, 3));
   p1.Points.Add(new XYPoint(8, 3));
   p1.Points.Add(new XYPoint(4, 7));
   ArrayList triangleList = p1.GetTriangulation();
   XYPolygon refTriangle1 = new XYPolygon();
   refTriangle1.Points.Add(new XYPoint(3,0));
   refTriangle1.Points.Add(new XYPoint(8,0));
   refTriangle1.Points.Add(new XYPoint(8,2));
   XYPolygon refTriangle2 = new XYPolygon();
   refTriangle2.Points.Add(new XYPoint(3,0));
   refTriangle2.Points.Add(new XYPoint(8,2));
   refTriangle2.Points.Add(new XYPoint(3,1));
   XYPolygon refTriangle3 = new XYPolygon();
   refTriangle3.Points.Add(new XYPoint(0,3));
   refTriangle3.Points.Add(new XYPoint(3,0));
   refTriangle3.Points.Add(new XYPoint(3,1));
   XYPolygon refTriangle4 = new XYPolygon();
   refTriangle4.Points.Add(new XYPoint(0,3));
   refTriangle4.Points.Add(new XYPoint(3,1));
   refTriangle4.Points.Add(new XYPoint(3,3));
   XYPolygon refTriangle5 = new XYPolygon();
   refTriangle5.Points.Add(new XYPoint(4,7));
   refTriangle5.Points.Add(new XYPoint(0,3));
   refTriangle5.Points.Add(new XYPoint(3,3));
   XYPolygon refTriangle6 = new XYPolygon();
   refTriangle6.Points.Add(new XYPoint(3,3));
   refTriangle6.Points.Add(new XYPoint(8,3));
   refTriangle6.Points.Add(new XYPoint(4,7));
   Assert.AreEqual(refTriangle1 ,(XYPolygon) triangleList[0]);
   Assert.AreEqual(refTriangle2 ,(XYPolygon) triangleList[1]);
   Assert.AreEqual(refTriangle3 ,(XYPolygon) triangleList[2]);
   Assert.AreEqual(refTriangle4 ,(XYPolygon) triangleList[3]);
   Assert.AreEqual(refTriangle5 ,(XYPolygon) triangleList[4]);
   Assert.AreEqual(refTriangle6 ,(XYPolygon) triangleList[5]);
 }	
   /// <summary>
   /// The methods calculates the shared area of two arbitrarily shaped 
   /// polygons.
   /// </summary>
   /// <param name="polygonA">Polygon</param>
   /// <param name="polygonB">Polygon</param>
   /// <returns>
   ///	<p>The shared area.</p>
   /// </returns>
   public static double CalculateSharedArea (XYPolygon polygonA, XYPolygon polygonB)
   {
 	  ArrayList triangleListA = polygonA.GetTriangulation();
     ArrayList triangleListB = polygonB.GetTriangulation();
     
     double area = 0;
     for (int ia = 0; ia < triangleListA.Count; ia++)
     {
 	    XYPolygon triangleA = new XYPolygon((XYPolygon)triangleListA[ia]);
       for (int ib = 0; ib < triangleListB.Count; ib++)
       {
   		  XYPolygon triangleB = new XYPolygon((XYPolygon)triangleListB[ib]);
         area = area + TriangleIntersectionArea(triangleA, triangleB);
       }
     }
     return area;
   }      
 public void Protected_IsPointInPolygonOrOnEdge()
 {
   XYPolygon p1 = new XYPolygon();
   p1.Points.Add(new XYPoint(0, 3));
   p1.Points.Add(new XYPoint(3, 0));
   p1.Points.Add(new XYPoint(8, 0));
   p1.Points.Add(new XYPoint(8, 2));
   p1.Points.Add(new XYPoint(3, 1));
   p1.Points.Add(new XYPoint(3, 3));
   p1.Points.Add(new XYPoint(8, 3));
   p1.Points.Add(new XYPoint(4, 7));
   Assert.AreEqual(true,  AXYGeometryTools.AIsPointInPolygonOrOnEdge(0,3,p1),"Test1");
   Assert.AreEqual(true,  AXYGeometryTools.AIsPointInPolygonOrOnEdge(1,3,p1),"Test2");
   Assert.AreEqual(false, AXYGeometryTools.AIsPointInPolygonOrOnEdge(1,5,p1),"Test3");
   Assert.AreEqual(true,  AXYGeometryTools.AIsPointInPolygonOrOnEdge(3,2,p1),"Test4");
   Assert.AreEqual(true,  AXYGeometryTools.AIsPointInPolygonOrOnEdge(3,3,p1),"Test5");
   Assert.AreEqual(true,  AXYGeometryTools.AIsPointInPolygonOrOnEdge(6,1,p1),"Test6");
   Assert.AreEqual(false, AXYGeometryTools.AIsPointInPolygonOrOnEdge(6,2,p1),"Test7");
   Assert.AreEqual(false, AXYGeometryTools.AIsPointInPolygonOrOnEdge(6,7,p1),"Test8");
 }
        /// <summary>
        /// Calculates the length of polyline inside polygon. Lines segments on the edges of
        /// polygons are included with half their length.
        /// </summary>
        /// <param name="polyline">Polyline</param>
        /// <param name="polygon">Polygon</param>
        /// <returns>
        /// Length of polyline inside polygon.
        /// </returns>
        public static double CalculateLengthOfPolylineInsidePolygon(XYPolyline polyline, XYPolygon polygon)
        {
            double lengthInside         = 0;
            int    numberOfLineSegments = polyline.Points.Count - 1;

            for (int i = 0; i < numberOfLineSegments; i++)
            {
                var line = polyline.GetLine(i);
                lengthInside += CalculateLengthOfLineInsidePolygon(line, polygon);
            }
            return(lengthInside);
        }
		public void IsPointInPolygon()
		{
			XYPolygon xypolygon = new XYPolygon();
			xypolygon.Points.Add(new XYPoint(1,1));
			xypolygon.Points.Add(new XYPoint(9,1));
			xypolygon.Points.Add(new XYPoint(5,5));
			xypolygon.Points.Add(new XYPoint(5,3));
			xypolygon.Points.Add(new XYPoint(3,3));
			xypolygon.Points.Add(new XYPoint(3,8));
			xypolygon.Points.Add(new XYPoint(9,8));
			xypolygon.Points.Add(new XYPoint(9,11));
			xypolygon.Points.Add(new XYPoint(1,11));

			Assert.AreEqual(true, XYGeometryTools.IsPointInPolygon(2,2,xypolygon));
			Assert.AreEqual(true, XYGeometryTools.IsPointInPolygon(2,4,xypolygon));
			Assert.AreEqual(true, XYGeometryTools.IsPointInPolygon(2,10,xypolygon));
			Assert.AreEqual(true, XYGeometryTools.IsPointInPolygon(7,10,xypolygon));
			Assert.AreEqual(true, XYGeometryTools.IsPointInPolygon(4,2,xypolygon));
			Assert.AreEqual(true, XYGeometryTools.IsPointInPolygon(7,2,xypolygon));
			Assert.AreEqual(true, XYGeometryTools.IsPointInPolygon(6,3.5,xypolygon));
			Assert.AreEqual(true, XYGeometryTools.IsPointInPolygon(7.5,2,xypolygon));

			Assert.AreEqual(false, XYGeometryTools.IsPointInPolygon(0,0,xypolygon));
			Assert.AreEqual(false, XYGeometryTools.IsPointInPolygon(4,4,xypolygon));
			Assert.AreEqual(false, XYGeometryTools.IsPointInPolygon(4,5,xypolygon));
			Assert.AreEqual(false, XYGeometryTools.IsPointInPolygon(10,8,xypolygon));
			Assert.AreEqual(false, XYGeometryTools.IsPointInPolygon(9,12,xypolygon));

			Assert.AreEqual(true, XYGeometryTools.IsPointInPolygon(new XYPoint(7.5,2),xypolygon));
			Assert.AreEqual(false, XYGeometryTools.IsPointInPolygon(new XYPoint(0,0),xypolygon));
		}
        /// <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);
            }
        }
	  private XYPolygon CreateXYPolygon(IElementSet elementSet, int index)
	  {
		  if (elementSet.ElementType != ElementType.XYPolygon)
		  {
			  throw new System.Exception("Cannot create XYPolyline");
		  }

		  XYPolygon xyPolygon = new XYPolygon();

		  for (int i = 0; i < elementSet.GetVertexCount(index); i++)
		  {
			  xyPolygon.Points.Add(new XYPoint(elementSet.GetXCoordinate(index,i), elementSet.GetYCoordinate(index,i)));
		  }

		  return xyPolygon;
	  }
 /// <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>
    /// 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);
      }
    }
    public void CalculateLengthOfPolylineInsidePolygon()
    {
        XYPolygon xypolygon = new XYPolygon();
        xypolygon.Points.Add(new XYPoint(1,1));
        xypolygon.Points.Add(new XYPoint(9,1));
        xypolygon.Points.Add(new XYPoint(5,5));
        xypolygon.Points.Add(new XYPoint(5,3));
        xypolygon.Points.Add(new XYPoint(3,3));
        xypolygon.Points.Add(new XYPoint(3,8));
        xypolygon.Points.Add(new XYPoint(9,8));
        xypolygon.Points.Add(new XYPoint(9,11));
        xypolygon.Points.Add(new XYPoint(1,11));

        XYPolyline xypolyline = new XYPolyline();
        xypolyline.Points.Add(new XYPoint(9,13));
        xypolyline.Points.Add(new XYPoint(7,12));
        xypolyline.Points.Add(new XYPoint(7,10));
        xypolyline.Points.Add(new XYPoint(2,10));
        xypolyline.Points.Add(new XYPoint(2,3));

        Assert.AreEqual(13,XYGeometryTools.CalculateLengthOfPolylineInsidePolygon(xypolyline, xypolygon));

        XYPolygon rectangle = new XYPolygon();
        rectangle.Points.Add(new XYPoint(10,10));
        rectangle.Points.Add(new XYPoint(20,10));
        rectangle.Points.Add(new XYPoint(20,40));
        rectangle.Points.Add(new XYPoint(10,40));

        XYPolyline line1 = new XYPolyline();
        line1.Points.Add(new XYPoint(0,20));
        line1.Points.Add(new XYPoint(30,20));
        Assert.AreEqual(10, XYGeometryTools.CalculateLengthOfPolylineInsidePolygon(line1, rectangle));  // horizontal line crossing
        
        XYPolyline line2 = new XYPolyline();
        line2.Points.Add(new XYPoint(10,20));
        line2.Points.Add(new XYPoint(20,20));
        Assert.AreEqual(10, XYGeometryTools.CalculateLengthOfPolylineInsidePolygon(line2, rectangle));  // fits inside

        XYPolyline line3 = new XYPolyline();
        line3.Points.Add(new XYPoint(0,40));
        line3.Points.Add(new XYPoint(30,40));
        Assert.AreEqual(5, XYGeometryTools.CalculateLengthOfPolylineInsidePolygon(line3, rectangle));

        XYPolyline line4 = new XYPolyline();
        line4.Points.Add(new XYPoint(20,40));
        line4.Points.Add(new XYPoint(20,0));
        
        Assert.AreEqual(15, XYGeometryTools.CalculateLengthOfPolylineInsidePolygon(line4, rectangle));

        XYPolyline line5 = new XYPolyline();
        line5.Points.Add(new XYPoint(20,40));
        line5.Points.Add(new XYPoint(20,10));
        Assert.AreEqual(15, XYGeometryTools.CalculateLengthOfPolylineInsidePolygon(line5, rectangle));

        XYPolyline line6 = new XYPolyline();
        line6.Points.Add(new XYPoint(10,40));
        line6.Points.Add(new XYPoint(30,40));
        Assert.AreEqual(5, XYGeometryTools.CalculateLengthOfPolylineInsidePolygon(line6, rectangle));

        XYPolyline line7 = new XYPolyline();
        line7.Points.Add(new XYPoint(10,20));
        line7.Points.Add(new XYPoint(30,20));
        Assert.AreEqual(10, XYGeometryTools.CalculateLengthOfPolylineInsidePolygon(line7, rectangle));


        



    }
    /// <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);
    }  
		[Test] public void GetLine()
		{
			// -- Triangle -- 
			XYPolygon xypolygon = new XYPolygon();
			xypolygon.Points.Add(new XYPoint(1,2));
			xypolygon.Points.Add(new XYPoint(4,3));
			xypolygon.Points.Add(new XYPoint(2,5));

			Assert.AreEqual(new XYLine(1,2,4,3),xypolygon.GetLine(0));
			Assert.AreEqual(new XYLine(4,3,2,5),xypolygon.GetLine(1));
			Assert.AreEqual(new XYLine(2,5,1,2),xypolygon.GetLine(2));

			
			// -- concave polygon --
			XYPolygon xypolygon4 = new XYPolygon();
			xypolygon4.Points.Add(new XYPoint(1,1));
			xypolygon4.Points.Add(new XYPoint(9,1));
			xypolygon4.Points.Add(new XYPoint(5,5));
			xypolygon4.Points.Add(new XYPoint(5,3));
			xypolygon4.Points.Add(new XYPoint(3,3));
			xypolygon4.Points.Add(new XYPoint(3,8));
			xypolygon4.Points.Add(new XYPoint(9,8));
			xypolygon4.Points.Add(new XYPoint(9,11));
			xypolygon4.Points.Add(new XYPoint(1,11));

			Assert.AreEqual(new XYLine(1, 1, 9,  1),xypolygon4.GetLine(0));
			Assert.AreEqual(new XYLine(9, 1, 5,  5),xypolygon4.GetLine(1));
			Assert.AreEqual(new XYLine(5, 5, 5,  3),xypolygon4.GetLine(2));
			Assert.AreEqual(new XYLine(5, 3, 3,  3),xypolygon4.GetLine(3));
			Assert.AreEqual(new XYLine(3, 3, 3,  8),xypolygon4.GetLine(4));
			Assert.AreEqual(new XYLine(3, 8, 9,  8),xypolygon4.GetLine(5));
			Assert.AreEqual(new XYLine(9, 8, 9, 11),xypolygon4.GetLine(6));
			Assert.AreEqual(new XYLine(9,11, 1 ,11),xypolygon4.GetLine(7));
			Assert.AreEqual(new XYLine(1,11, 1 , 1),xypolygon4.GetLine(8));
		}
 public static double ATriangleIntersectionArea(XYPolygon triangleA, XYPolygon triangleB)
 {
   return TriangleIntersectionArea(triangleA, triangleB);
 }
		/// <summary>
		/// Calculates the length of polyline inside polygon. Lines segments on the edges of 
		/// polygons are included with half their length.
		/// </summary>
		/// <param name="polyline">Polyline</param>
		/// <param name="polygon">Polygon</param>
		/// <returns>
		/// Length of polyline inside polygon.
		/// </returns>
		public static double CalculateLengthOfPolylineInsidePolygon(XYPolyline polyline, XYPolygon polygon)
		{
			double lengthInside = 0;
			int numberOfLineSegments = polyline.Points.Count - 1;
			for (int i = 0; i < numberOfLineSegments; i++)
			{
				XYLine line = new XYLine(polyline.GetLine(i));
				lengthInside += CalculateLengthOfLineInsidePolygon(line,polygon);
			}
			return lengthInside;
		}
    /// <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;
		}
Beispiel #40
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 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>
 /// 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);
     }
 }
        private void panelViewer_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            // write x and y coordinates			
			double x = ((e.X - _margin) /  _scale) + _minX;
			double y = _minY - (e.Y + _margin - panelViewer.ClientSize.Height) / _scale;
			if( _scale != double.MaxValue )
				this.label3.Text = "(" + x.ToString("F3") +", " + y.ToString("F3") + ")";			
			else
				this.label3.Text = "";


            // write elementSet ID and element index
            this.label4.Text = " ";
            this.label7.Text = " ";
            this.label8.Text = " ";
            this.label9.Text = " ";
            this.label10.Text = " ";
            this.label11.Text = " ";

            for (int elementSetNumber = 0; elementSetNumber < this._elementSets.Count; elementSetNumber++)
            {
                string elementID = " ";
                int elementIndex = -9;
                double distance = 10e30;

                IElementSet elementSet = (IElementSet) _elementSets[elementSetNumber];
                
                if (elementSetNumber == 0)
                {
                    this.label7.Text = elementSet.ID.Substring(0, Math.Min(20, elementSet.ID.Length));
                }
                if (elementSetNumber == 1)
                {
                    this.label9.Text = elementSet.ID.Substring(0, Math.Min(20, elementSet.ID.Length));
                }

                for (int index = 0; index < elementSet.ElementCount; index++)
                {
                    if (((IElementSet) _elementSets[elementSetNumber]).ElementType == ElementType.XYPolygon)
                    {
                        XYPolygon xyPolygon = new XYPolygon();

                        for (int i = 0; i < elementSet.GetVertexCount(index); i++)
                        {
                            xyPolygon.Points.Add(new XYPoint(elementSet.GetXCoordinate(index,i), elementSet.GetYCoordinate(index,i)));
                        }

                        if (XYGeometryTools.IsPointInPolygon(x,y,xyPolygon))
                        {
                            elementID = elementSet.GetElementID(index);
                            elementIndex = index;
                        }
                    }

                    
                    if (((IElementSet) _elementSets[elementSetNumber]).ElementType == ElementType.XYPolyLine)
                    {
                        XYPolyline xyPolyline = new XYPolyline();
                        for (int i = 0; i < elementSet.GetVertexCount(index); i++)
                        {
                            xyPolyline.Points.Add(new XYPoint(elementSet.GetXCoordinate(index,i), elementSet.GetYCoordinate(index,i)));
                        }
                        double xx =  XYGeometryTools.CalculatePolylineToPointDistance(xyPolyline, new XYPoint(x,y));
                        if (xx < distance)
                        {
                            distance = xx;
                            if (xx < 0.3 * xyPolyline.GetLength())
                            {
                                elementIndex = index;
                                elementID = elementSet.GetElementID(index);
                            }
                        }

                    }

                    if (elementSetNumber == 0 && elementIndex >= 0)
                    {
                        this.label4.Text = "Index: " + elementIndex.ToString();
                        this.label8.Text = "ID: " + elementID.Substring(0, Math.Min(17, elementID.Length));
                    }
                    if (elementSetNumber == 1 && elementIndex >= 0)
                    {
                        this.label10.Text = "Index: " + elementIndex.ToString();
                        this.label11.Text = "ID: " + elementID.Substring(0, Math.Min(17, elementID.Length));
                    }
                }
            }
        }