/// <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); }
/// <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); }
/// <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 IXYPoint intersectionPoint) { //Jag: this should be call TryGetValue and ref should be out 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); }
/// <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, IXYPoint point) { double dist = 0; double a = Math.Sqrt((line.P2.X - point.X) * (line.P2.X - point.X) + (line.P2.Y - point.Y) * (line.P2.Y - point.Y)); double b = Math.Sqrt((line.P2.X - line.P1.X) * (line.P2.X - line.P1.X) + (line.P2.Y - line.P1.Y) * (line.P2.Y - line.P1.Y)); double c = Math.Sqrt((line.P1.X - point.X) * (line.P1.X - point.X) + (line.P1.Y - point.Y) * (line.P1.Y - point.Y)); if ((a == 0) || (c == 0)) { dist = 0; } else if (b == 0) { dist = a; } else { double alpha = Math.Acos((b * b + c * c - a * a) / (2 * b * c)); double beta = Math.Acos((a * a + b * b - c * c) / (2 * a * b)); if (Math.Max(alpha, beta) < Math.PI / 2) { dist = Math.Abs((line.P2.X - line.P1.X) * (line.P1.Y - point.Y) - (line.P1.X - point.X) * (line.P2.Y - line.P1.Y)) / b; } else { dist = Math.Min(a, c); } } return(dist); }
/// <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; }
public void GetProjectedPoint() { var line = new XYLine(0.000000001, 0, 0, 1); var projected = line.GetProjectedPoint(new XYPoint(2, 0.8)); Assert.AreEqual(0.8, projected.Y, 1e-6); Assert.AreEqual(0, projected.X, 1e-6); projected = line.GetProjectedPoint(new XYPoint(2, 2)); }
public void Equals() { XYPoint p1 = new XYPoint(2,3); XYPoint p2 = new XYPoint(2,3); XYPoint p3 = new XYPoint(2,-3); XYLine l1 = new XYLine(2,3,3,4); Assert.AreEqual(true, p1.Equals(p1),"Test1"); Assert.AreEqual(true, p1.Equals(p2),"Test2"); Assert.AreEqual(false, p1.Equals(p3),"Test3"); Assert.AreEqual(false, p1.Equals(l1),"Test4"); }
/// <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); }
public void Equals() { XYLine l1 = new XYLine(0, 3, 3, 0); XYLine l2 = new XYLine(0, 3, 3, 0); XYLine l3 = new XYLine(3, 3, 3, 0); XYPolyline pl1 = new XYPolyline(); pl1.Points.Add(new XYPoint(0, 3)); pl1.Points.Add(new XYPoint(3, 0)); Assert.AreEqual(true, l1.Equals(l1),"Test1"); Assert.AreEqual(true, l1.Equals(l2),"Test2"); Assert.AreEqual(false, l1.Equals(l3),"Test3"); Assert.AreEqual(false, l1.Equals(pl1),"Test4"); }
public void ConstructionTest() { XYLine xyLine1 = new XYLine(1,2,3,4); Assert.AreEqual((double) 1, xyLine1.P1.X); Assert.AreEqual((double) 2, xyLine1.P1.Y); Assert.AreEqual((double) 3, xyLine1.P2.X); Assert.AreEqual((double) 4, xyLine1.P2.Y); XYLine xyLine2 = new XYLine(xyLine1); Assert.AreEqual(xyLine1.P1.X, xyLine2.P1.X); Assert.AreEqual(xyLine1.P1.Y, xyLine2.P1.Y); Assert.AreEqual(xyLine1.P2.X, xyLine2.P2.X); Assert.AreEqual(xyLine1.P2.Y, xyLine2.P2.Y); XYLine xyLine3 = new XYLine(new XYPoint(1,2),new XYPoint(3,4)); Assert.AreEqual((double) 1, xyLine3.P1.X); Assert.AreEqual((double) 2, xyLine3.P1.Y); Assert.AreEqual((double) 3, xyLine3.P2.X); Assert.AreEqual((double) 4, xyLine3.P2.Y); }
/// <summary> /// Checks if the lines lineA and lineB shares a point either as a real /// crossing point or as a shared end point or a end point of the one /// line being in the other line. /// </summary> /// <param name="Linea">Line.</param> /// <param name="Lineb">Line.</param> /// <param name="intersectionPoint">Point.</param> /// <returns> /// <p>True if lineA and lineB has shared point. False otherwise</p> /// <p>The shared point if any is returned in the intersectionPoint /// parameter that is called by reference</p> /// </returns> protected static bool IntersectionPoint(XYLine Linea, XYLine Lineb, ref IXYPoint intersectionPoint) { //Jag: this should be call TryGetValue and ref should be out 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; }
/// <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 { IXYPoint P1A = new XYPoint(); IXYPoint P2A = new XYPoint(); if (lineA.P1.X < lineA.P2.X) { P1A = lineA.P1; P2A = lineA.P2; } else { P1A = lineA.P2; P2A = lineA.P1; } IXYPoint P1B = new XYPoint(); IXYPoint P2B = new XYPoint(); if (lineB.P1.X < lineB.P2.X) { P1B = lineB.P1; P2B = lineB.P2; } else { P1B = lineB.P2; P2B = lineB.P1; } double alphaA = (P2A.Y - P1A.Y)/(P2A.X - P1A.X); double betaA = -alphaA*P2A.X + P2A.Y; double alphaB = (P2B.Y - P1B.Y)/(P2B.X - P1B.X); double betaB = -alphaA*P2B.X + P2B.Y; if (Math.Abs(alphaA-alphaB)<EPSILON && Math.Abs(betaA-betaB)<EPSILON) { double x1 = Math.Max(P1A.X, P1B.X); double x2 = Math.Min(P2A.X, P2B.X); if (x1 < x2) { XYLine line = new XYLine(x1, alphaA*x1+betaA, x2, alphaA*x2+betaA); return line.GetLength(); } else { return 0; } } else { return 0; } } }
/// <summary> /// Calculates length of line inside polygon. Parts of the line that is on the edge of /// the polygon only counts with half their length. /// </summary> /// <param name="line">Line</param> /// <param name="polygon">Polygon</param> /// <returns> /// Length of line inside polygon. /// </returns> protected static double CalculateLengthOfLineInsidePolygon(XYLine line, XYPolygon polygon) { ArrayList lineList = new ArrayList(); lineList.Add(new XYLine(line)); for (int i = 0; i < polygon.Points.Count; i++) // For all lines in the polygon { for (int n = 0; n < lineList.Count; n++) { if (lineList.Count > 1000) { throw new Exception("Problems in ElementMapper, line has been cut in more than 1000 pieces !!!"); } if (DoLineSegmentsIntersect((XYLine)lineList[n], polygon.GetLine(i))) { // Split the intersecting line into two lines XYPoint IntersectionPoint = new XYPoint(CalculateIntersectionPoint((XYLine)lineList[n], polygon.GetLine(i))); lineList.Add(new XYLine(IntersectionPoint, ((XYLine) lineList[n]).P2)); ((XYLine) lineList[n]).P2.X = IntersectionPoint.X; ((XYLine) lineList[n]).P2.Y = IntersectionPoint.Y; break; } } } for (int i = 0; i < lineList.Count; i++) { if (lineList.Count > 1000) { throw new Exception("Problems in ElementMapper, line has been cuttes in more than 100 pieces !!!"); } for (int j = 0; j < polygon.Points.Count; j++) { if (IsPointInLineInterior( polygon.GetLine(j).P1, ((XYLine) lineList[i]))) { lineList.Add(new XYLine(polygon.GetLine(j).P1, ((XYLine) lineList[i]).P2)); ((XYLine) lineList[i]).P2.X = polygon.GetLine(j).P1.X; ((XYLine) lineList[i]).P2.Y = polygon.GetLine(j).P1.Y; } } } double lengthInside = 0; for (int i = 0; i < lineList.Count; i++) { double sharedLength = 0; for (int j = 0; j < polygon.Points.Count; j++) { sharedLength += CalculateSharedLength(((XYLine) lineList[i]), polygon.GetLine(j)); } if (sharedLength > EPSILON) { lengthInside += sharedLength/2; } else if (IsPointInPolygon(((XYLine) lineList[i]).GetMidpoint(), polygon)) { lengthInside += ((XYLine) lineList[i]).GetLength(); } } return lengthInside; }
/// <summary> /// OverLoad of 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); }
/// <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> /// 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(IXYPoint point, XYLine line) { return IsPointInLineInterior( point.X, point.Y, line); }
/// <summary> /// Calculates length of line inside polygon. Parts of the line that is on the edge of /// the polygon only counts with half their length. /// </summary> /// <param name="line">Line</param> /// <param name="polygon">Polygon</param> /// <returns> /// Length of line inside polygon. /// </returns> protected static double CalculateLengthOfLineInsidePolygon(XYLine line, XYPolygon polygon) { ArrayList lineList = new ArrayList(); lineList.Add(new XYLine(line)); for (int i = 0; i < polygon.Points.Count; i++) // For all lines in the polygon { for (int n = 0; n < lineList.Count; n++) { if (lineList.Count > 1000) { throw new Exception("Problems in ElementMapper, line has been cut in more than 1000 pieces !!!"); } if (DoLineSegmentsIntersect((XYLine)lineList[n], polygon.GetLine(i))) { // Split the intersecting line into two lines XYPoint IntersectionPoint = new XYPoint(CalculateIntersectionPoint((XYLine)lineList[n], polygon.GetLine(i))); lineList.Add(new XYLine(IntersectionPoint, ((XYLine)lineList[n]).P2)); ((XYLine)lineList[n]).P2.X = IntersectionPoint.X; ((XYLine)lineList[n]).P2.Y = IntersectionPoint.Y; break; } } } for (int i = 0; i < lineList.Count; i++) { if (lineList.Count > 1000) { throw new Exception("Problems in ElementMapper, line has been cuttes in more than 100 pieces !!!"); } for (int j = 0; j < polygon.Points.Count; j++) { if (IsPointInLineInterior(polygon.GetLine(j).P1, ((XYLine)lineList[i]))) { lineList.Add(new XYLine(polygon.GetLine(j).P1, ((XYLine)lineList[i]).P2)); ((XYLine)lineList[i]).P2.X = polygon.GetLine(j).P1.X; ((XYLine)lineList[i]).P2.Y = polygon.GetLine(j).P1.Y; } } } double lengthInside = 0; for (int i = 0; i < lineList.Count; i++) { double sharedLength = 0; for (int j = 0; j < polygon.Points.Count; j++) { sharedLength += CalculateSharedLength(((XYLine)lineList[i]), polygon.GetLine(j)); } if (sharedLength > EPSILON) { lengthInside += sharedLength / 2; } else if (IsPointInPolygon(((XYLine)lineList[i]).GetMidpoint(), polygon)) { lengthInside += ((XYLine)lineList[i]).GetLength(); } } return(lengthInside); }
/// <summary> /// OverLoad of 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)); }
/// <summary> /// Returns unityvector holding the direction /// </summary> /// <param name="p1"></param> /// <param name="p2"></param> /// <returns></returns> public static XYPoint GetDirection(XYLine line) { return GetDirection(line.P1, line.P2); }
/// <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(IXYPoint point, XYLine line) { return(IsPointInLineInterior(point.X, point.Y, line)); }
public static double ACalculateLengthOfLineInsidePolygon(XYLine line, XYPolygon polygon) { return CalculateLengthOfLineInsidePolygon(line, polygon); }
public static double ACalculateLineToPointDistance(XYLine line, XYPoint point) { return CalculateLineToPointDistance(line, point); }
public static double ACalculateSharedLength(XYLine lineA, XYLine lineB) { return CalculateSharedLength(lineA, lineB); }
public static bool AIntersectionPoint(XYLine lineA, XYLine lineB, ref IXYPoint intersectionPoint) { return IntersectionPoint(lineA, lineB, ref intersectionPoint); }
/// <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; }
/// <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)); }
/// <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; }
/// <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); }
/// <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, IXYPoint point) { double dist = 0; double a = Math.Sqrt((line.P2.X-point.X)*(line.P2.X-point.X) + (line.P2.Y-point.Y)*(line.P2.Y-point.Y)); double b = Math.Sqrt((line.P2.X-line.P1.X)*(line.P2.X-line.P1.X)+(line.P2.Y-line.P1.Y)*(line.P2.Y-line.P1.Y)); double c = Math.Sqrt((line.P1.X-point.X)*(line.P1.X-point.X)+(line.P1.Y-point.Y)*(line.P1.Y-point.Y)); if ((a == 0) || (c == 0)) { dist = 0; } else if (b == 0) { dist = a; } else { double alpha = Math.Acos((b*b+c*c-a*a)/(2*b*c)); double beta = Math.Acos((a*a+b*b-c*c)/(2*a*b)); if (Math.Max(alpha,beta)<Math.PI/2) { dist = Math.Abs((line.P2.X-line.P1.X)*(line.P1.Y-point.Y)-(line.P1.X-point.X)*(line.P2.Y-line.P1.Y))/b; } else { dist = Math.Min(a, c); } } return dist; }
/// <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 { IXYPoint P1A = new XYPoint(); IXYPoint P2A = new XYPoint(); if (lineA.P1.X < lineA.P2.X) { P1A = lineA.P1; P2A = lineA.P2; } else { P1A = lineA.P2; P2A = lineA.P1; } IXYPoint P1B = new XYPoint(); IXYPoint P2B = new XYPoint(); if (lineB.P1.X < lineB.P2.X) { P1B = lineB.P1; P2B = lineB.P2; } else { P1B = lineB.P2; P2B = lineB.P1; } double alphaA = (P2A.Y - P1A.Y) / (P2A.X - P1A.X); double betaA = -alphaA * P2A.X + P2A.Y; double alphaB = (P2B.Y - P1B.Y) / (P2B.X - P1B.X); double betaB = -alphaA * P2B.X + P2B.Y; if (Math.Abs(alphaA - alphaB) < EPSILON && Math.Abs(betaA - betaB) < EPSILON) { double x1 = Math.Max(P1A.X, P1B.X); double x2 = Math.Min(P2A.X, P2B.X); if (x1 < x2) { XYLine line = new XYLine(x1, alphaA * x1 + betaA, x2, alphaA * x2 + betaA); return(line.GetLength()); } else { return(0); } } else { return(0); } } }
public static bool AIsPointInLineInterior(XYPoint point, XYLine line) { return IsPointInLineInterior(point, line); }