private ICoordinate getCircleCenter(ICoordinate p1, ICoordinate p2, ICoordinate p3) { if (p1.ExactEquals(p2) || p1.ExactEquals(p3) || p2.ExactEquals(p3)) { return(null); } // get rid of the vertical lines if (p1.X == p2.X) { ICoordinate temp = p1; p1 = p3; p3 = temp; } if (p2.X == p3.X) { ICoordinate temp = p2; p2 = p1; p1 = temp; } double ma = (p2.Y - p1.Y) / (p2.X - p1.X); double mb = (p3.Y - p2.Y) / (p3.X - p2.X); // collinear lines, circles do not if (mb == ma || (double.IsInfinity(ma) && double.IsInfinity(mb))) { return(null); } //coordinates of the center of the circle double x = 0.5 * (ma * mb * (p1.Y - p3.Y) + mb * (p1.X + p2.X) - ma * (p2.X + p3.X)) / (mb - ma); double y = double.NaN; if (ma != 0 && !double.IsInfinity(ma)) { y = -1 / ma * (x - 0.5 * (p1.X + p2.X)) + 0.5 * (p1.Y + p2.Y); } else { y = -1 / mb * (x - 0.5 * (p2.X + p3.X)) + 0.5 * (p2.Y + p3.Y); } return(PlanimetryEnvironment.NewCoordinate(x, y)); }
private bool checkWeightedVertex(Polyline polyline, KDTree vertexIndex, SDMinVertex currentVertex, KDTree crossPointIndex) { // probably not an internal vertex if (currentVertex.Previous == null || currentVertex.Next == null) { return(true); } // top with infinite weight ("do not remove") if (double.IsPositiveInfinity(currentVertex.Weight)) { return(true); } SDMinVertex previous = currentVertex.Previous; SDMinVertex next = currentVertex.Next; // One of the segments formed by the vertex in question may be one of the intersection points. // If so, you can not remove the top, as point of self-intersection, it may be removed. Segment s1 = new Segment(pointOfWeightedVertex(polyline, currentVertex), pointOfWeightedVertex(polyline, previous)); Segment s2 = new Segment(pointOfWeightedVertex(polyline, currentVertex), pointOfWeightedVertex(polyline, next)); List <SDMinCrossPoint> crossPoints = new List <SDMinCrossPoint>(); crossPointIndex.QueryObjectsInRectangle(s1.GetBoundingRectangle(), crossPoints); crossPointIndex.QueryObjectsInRectangle(s2.GetBoundingRectangle(), crossPoints); foreach (SDMinCrossPoint point in crossPoints) { if (PlanimetryAlgorithms.LiesOnSegment(point.Point, s1)) { currentVertex.IsCrossSegmentVertex = true; currentVertex.Previous.IsCrossSegmentVertex = true; return(false); } if (PlanimetryAlgorithms.LiesOnSegment(point.Point, s2)) { currentVertex.IsCrossSegmentVertex = true; currentVertex.Next.IsCrossSegmentVertex = true; return(false); } } //One of the polyline vertices can belong to a triangle, //the apex of which is considered the top. In this case, //the top can not be deleted because will be a new point of self-intersection. Polygon triangle = new Polygon(new ICoordinate[] { pointOfWeightedVertex(polyline, previous), pointOfWeightedVertex(polyline, currentVertex), pointOfWeightedVertex(polyline, next) }); List <SDMinVertex> vertices = new List <SDMinVertex>(); vertexIndex.QueryObjectsInRectangle <SDMinVertex>(triangle.GetBoundingRectangle(), vertices); foreach (SDMinVertex vertex in vertices) { ICoordinate p = pointOfWeightedVertex(polyline, vertex); //point should not be the top of the triangle if (p.ExactEquals(triangle.Contours[0].Vertices[0]) || p.ExactEquals(triangle.Contours[0].Vertices[1]) || p.ExactEquals(triangle.Contours[0].Vertices[2])) { continue; } if (triangle.ContainsPoint(p)) { return(false); } } return(true); }