コード例 #1
0
        //=====================================================================
        // IsPointInLine(double x, double y, XYLine line) : bool
        //=====================================================================
        /// <summary>
        /// Determines if a point is included in a line either in the interior
        /// or as one of the end points.
        /// </summary>
        /// <param name="x">x-coordinate</param>
        /// <param name="y">y-coordinate</param>
        /// <param name="line">Line.</param>
        /// <returns>
        ///	<p>Determines if a point is included in a line.</p>
        /// </returns>
        protected static bool IsPointInLine(double x, double y, XYLine line)
        {
            bool result = false;

            if (line.P1.X - line.P2.X != 0)
            {
                if ((x >= Math.Min(line.P1.X, line.P2.X)) && (x <= Math.Max(line.P1.X, line.P2.X)))
                {
                    if (Math.Abs(y - line.P1.Y - (line.P2.Y - line.P1.Y) / (line.P1.X - line.P2.X) * (line.P1.X - x)) < EPSILON * EPSILON)
                    {
                        result = true;
                    }
                }
            }
            else
            {
                if (line.P1.X == x)
                {
                    if ((y >= Math.Min(line.P1.Y, line.P2.Y)) && (y <= Math.Max(line.P1.Y, line.P2.Y)))
                    {
                        result = true;
                    }
                }
            }
            return(result);
        }
コード例 #2
0
        //=====================================================================
        // CalculateLineToPointDistance (XYLine line, XYPoint point) : double
        //=====================================================================
        /// <summary>
        /// Calculates the distance from a polyline to a point in the plane.
        /// The algorithm decides weather the point lies besides the line
        /// segment in which case the distance is the length along a line
        /// perpendicular to the line. Alternatively the distance is the
        /// smallest of the distances to either endpoint.
        /// </summary>
        /// <param name="line">Line</param>
        /// <param name="point">Point</param>
        /// <returns>
        ///	<p>Length of the shortest path between the line and the point.</p>
        /// </returns>
        protected static double CalculateLineToPointDistance(XYLine line, XYPoint point)
        {
            double dist;
            double a = Math.Sqrt((line.P2.X - point.X) * (line.P2.X - point.X) + (line.P2.Y - point.Y) * (line.P2.Y - point.Y));
            double b =
                Math.Sqrt((line.P2.X - line.P1.X) * (line.P2.X - line.P1.X) + (line.P2.Y - line.P1.Y) * (line.P2.Y - line.P1.Y));
            double c = Math.Sqrt((line.P1.X - point.X) * (line.P1.X - point.X) + (line.P1.Y - point.Y) * (line.P1.Y - point.Y));

            if ((a == 0) || (c == 0))
            {
                dist = 0;
            }
            else if (b == 0)
            {
                dist = a;
            }
            else
            {
                double alpha = Math.Acos((b * b + c * c - a * a) / (2 * b * c));
                double beta  = Math.Acos((a * a + b * b - c * c) / (2 * a * b));
                if (Math.Max(alpha, beta) < Math.PI / 2)
                {
                    dist = Math.Abs((line.P2.X - line.P1.X) * (line.P1.Y - point.Y) - (line.P1.X - point.X) * (line.P2.Y - line.P1.Y)) / b;
                }
                else
                {
                    dist = Math.Min(a, c);
                }
            }
            return(dist);
        }
コード例 #3
0
        //=====================================================================
        // IsPointInLineInterior(double x, double y, XYLine line) : bool
        //=====================================================================
        /// <summary>
        /// Determines if a point is included in a lines interior. I.e. included
        /// in the line and not an endpoint.
        /// </summary>
        /// <param name="x">x-coordinate</param>
        /// <param name="y">y-coordinate</param>
        /// <param name="line">Line.</param>
        /// <returns>
        ///	<p>Determines if a point is included in a line.</p>
        /// </returns>
        protected static bool IsPointInLineInterior(double x, double y, XYLine line)
        {
            bool result = false;

            if (line.P1.X - line.P2.X != 0)             //line is not vertical
            {
                if ((x > Math.Min(line.P1.X, line.P2.X)) && (x < Math.Max(line.P1.X, line.P2.X)))
                {
                    if (Math.Abs(y - line.P1.Y - (line.P2.Y - line.P1.Y) / (line.P1.X - line.P2.X) * (line.P1.X - x)) < EPSILON * EPSILON)
                    {
                        result = true;
                    }
                }
            }
            else             //line is vertical
            {
                if (line.P1.X == x)
                {
                    if ((y > Math.Min(line.P1.Y, line.P2.Y)) && (y < Math.Max(line.P1.Y, line.P2.Y)))
                    {
                        result = true;
                    }
                }
            }
            return(result);
        }
コード例 #4
0
 //=====================================================================
 // IntersectionPoint(XYLine lineA, XYLine lineB, ref intersectionPoint): bool
 //=====================================================================
 /// <summary>
 /// Checks if the lines lineA and lineB shares a point either as a real
 /// crossing point or as a shared end point or a end point of the one
 /// line being in the other line.
 /// </summary>
 /// <param name="Linea">Line.</param>
 /// <param name="Lineb">Line.</param>
 /// <param name="intersectionPoint">Point.</param>
 /// <returns>
 ///	<p>True if lineA and lineB has shared point. False otherwise</p>
 ///	<p>The shared point if any is returned in the intersectionPoint
 ///	parameter that is called by reference</p>
 /// </returns>
 protected static bool IntersectionPoint(XYLine Linea, XYLine Lineb, ref XYPoint intersectionPoint)
 {
     if (DoLineSegmentsIntersect(Linea, Lineb))
     {
         intersectionPoint = CalculateIntersectionPoint(Linea, Lineb);
         return(true);
     }
     if (IsPointInLine(Linea.P2, Lineb))
     {
         intersectionPoint = Linea.P2;
         return(true);
     }
     if (IsPointInLine(Lineb.P2, Linea))
     {
         intersectionPoint = Lineb.P2;
         return(true);
     }
     if (IsPointInLine(Lineb.P1, Linea))
     {
         intersectionPoint = Lineb.P1;
         return(true);
     }
     if (IsPointInLine(Linea.P1, Lineb))
     {
         intersectionPoint = Linea.P1;
         return(true);
     }
     return(false);
 }
コード例 #5
0
ファイル: XYLine.cs プロジェクト: muguangyuze/OpenMI
        //=====================================================================
        // XYLine(XYLine line)
        //=====================================================================
        /// <summary>
        /// Constructor. Copies input line.
        /// </summary>
        /// <param name="line">Line to copy</param>
        public XYLine(XYLine line)
        {
            _p1 = new XYPoint();
            _p2 = new XYPoint();

            _p1.X = line.P1.X;
            _p1.Y = line.P1.Y;
            _p2.X = line.P2.X;
            _p2.Y = line.P2.Y;
        }
コード例 #6
0
        //=========================================================================================
        //CalculateLengthOfPolylineInsidePolygon(XYPolyline polyline, XYPolygon polygon) : double
        //=========================================================================================
        /// <summary>
        /// Calculates the length of polyline inside polygon. Lines segments on the edges of
        /// polygons are included with half their length.
        /// </summary>
        /// <param name="polyline">Polyline</param>
        /// <param name="polygon">Polygon</param>
        /// <returns>
        /// Length of polyline inside polygon.
        /// </returns>
        public static double CalculateLengthOfPolylineInsidePolygon(XYPolyline polyline, XYPolygon polygon)
        {
            double lengthInside         = 0;
            int    numberOfLineSegments = polyline.Points.Count - 1;

            for (int i = 0; i < numberOfLineSegments; i++)
            {
                XYLine line = new XYLine(polyline.GetLine(i));
                lengthInside += CalculateLengthOfLineInsidePolygon(line, polygon);
            }
            return(lengthInside);
        }
コード例 #7
0
 //=====================================================================
 // IsPointInLineInterior(XYPoint point, XYLine line) : bool
 //=====================================================================
 /// <summary>
 /// Determines if a point is included in a lines interior. I.e. included
 /// in the line and not an endpoint.
 /// <p>Overload to:IsPointInLineInterior(double x, double y, XYLine line)</p>
 /// </summary>
 /// <param name="point">Point.</param>
 /// <param name="line">Line.</param>
 /// <returns>
 ///	<p>Determines if a point is included in a line.</p>
 /// </returns>
 protected static bool IsPointInLineInterior(XYPoint point, XYLine line)
 {
     return(IsPointInLineInterior(point.X, point.Y, line));
 }
コード例 #8
0
        //=====================================================================================
        //CalculateLengthOfLineInsidePolygon(XYLine line, XYPolygon polygon): double
        //=====================================================================================
        /// <summary>
        /// Calculates length of line inside polygon. Parts of the line that is on the edge of
        /// the polygon only counts with half their length.
        /// </summary>
        /// <param name="line">Line</param>
        /// <param name="polygon">Polygon</param>
        /// <returns>
        /// Length of line inside polygon.
        /// </returns>
        protected static double CalculateLengthOfLineInsidePolygon(XYLine line, XYPolygon polygon)
        {
            ArrayList lineList = new ArrayList();

            lineList.Add(new XYLine(line));

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

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

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

            double lengthInside = 0;

            for (int i = 0; i < lineList.Count; i++)
            {
                double sharedLength = 0;
                for (int j = 0; j < polygon.Points.Count; j++)
                {
                    sharedLength += CalculateSharedLength(((XYLine)lineList[i]), polygon.GetLine(j));
                }
                if (sharedLength > EPSILON)
                {
                    lengthInside += sharedLength / 2;
                }
                else if (IsPointInPolygon(((XYLine)lineList[i]).GetMidpoint(), polygon))
                {
                    lengthInside += ((XYLine)lineList[i]).GetLength();
                }
            }
            return(lengthInside);
        }
コード例 #9
0
        //=========================================================================================
        //CalculateSharedLength(XYLine lineA, XYLine lineB) : double
        //=========================================================================================
        /// <summary>
        /// Calculates the length that two lines overlap.
        /// </summary>
        /// <param name="lineA">Line</param>
        /// <param name="lineB">Line</param>
        /// <returns>
        /// Length of shared line segment.
        /// </returns>
        protected static double CalculateSharedLength(XYLine lineA, XYLine lineB)
        {
            if (Math.Abs(lineA.P2.X - lineA.P1.X) < EPSILON && Math.Abs(lineB.P2.X - lineB.P1.X) < EPSILON &&
                Math.Abs(lineA.P1.X - lineB.P1.X) < EPSILON)
            {
                double YP1A = Math.Min(lineA.P1.Y, lineA.P2.Y);
                double YP2A = Math.Max(lineA.P1.Y, lineA.P2.Y);
                double YP1B = Math.Min(lineB.P1.Y, lineB.P2.Y);
                double YP2B = Math.Max(lineB.P1.Y, lineB.P2.Y);

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

                double alphaA = (P2A.Y - P1A.Y) / (P2A.X - P1A.X);
                double betaA  = -alphaA * P2A.X + P2A.Y;
                double alphaB = (P2B.Y - P1B.Y) / (P2B.X - P1B.X);
                double betaB  = -alphaA * P2B.X + P2B.Y;
                if (Math.Abs(alphaA - alphaB) < EPSILON && Math.Abs(betaA - betaB) < EPSILON)
                {
                    double x1 = Math.Max(P1A.X, P1B.X);
                    double x2 = Math.Min(P2A.X, P2B.X);
                    if (x1 < x2)
                    {
                        XYLine line = new XYLine(x1, alphaA * x1 + betaA, x2, alphaA * x2 + betaA);
                        return(line.GetLength());
                    }
                    else
                    {
                        return(0);
                    }
                }
                else
                {
                    return(0);
                }
            }
        }
コード例 #10
0
 //=========================================================================================
 //CalculateIntersectionPoint(XYLine line1, XYLine line2) : XYPoint
 //=========================================================================================
 /// <summary>
 /// OverLoad of CalculateIntersectionPoint(XYPoint p1, XYPoint p2, XYPoint p3, XYPoint p4)
 /// </summary>
 /// <param name="line1">First line</param>
 /// <param name="line2">Second line</param>
 /// <returns>Intersection point</returns>
 public static XYPoint CalculateIntersectionPoint(XYLine line1, XYLine line2)
 {
     return(CalculateIntersectionPoint(line1.P1, line1.P2, line2.P1, line2.P2));
 }
コード例 #11
0
 //===============================================================================================
 //DoLineSegmentsIntersect(XYLine line1, XYLine line2) : bool
 //===============================================================================================
 /// <summary>
 /// OverLoad of DoLineSegmentsIntersect(x1, y1, x2, y2, x3, y3, x4, y4)
 /// </summary>
 /// <param name="line1">First line</param>
 /// <param name="line2">Second line</param>
 /// <returns>true if the line segmenst intersects otherwise false</returns>
 public static bool DoLineSegmentsIntersect(XYLine line1, XYLine line2)
 {
     return
         (DoLineSegmentsIntersect(line1.P1.X, line1.P1.Y, line1.P2.X, line1.P2.Y, line2.P1.X, line2.P1.Y, line2.P2.X,
                                  line2.P2.Y));
 }