/// <summary> /// Static version of InCentre function. /// </summary> public static C2DPoint GetInCentre(C2DPoint pt1, C2DPoint pt2, C2DPoint pt3) { // Set up a line to bisect the lines from 1 to 2 and 1 to 3 var Line1 = new C2DLine(pt1, pt2); var Line2 = new C2DLine(pt1, pt3); Line1.SetLength(Line2.GetLength()); var Line12Bisect = new C2DLine(pt1, pt3.GetMidPoint(Line1.GetPointTo())); // Set up a line to bisect the lines from 2 to 1 and 2 to 3 var Line3 = new C2DLine(pt2, pt1); var Line4 = new C2DLine(pt2, pt3); Line3.SetLength(Line4.GetLength()); var Line34Bisect = new C2DLine(pt2, pt3.GetMidPoint(Line3.GetPointTo())); // Now intersect the 2 lines and find the point. var Int = new List <C2DPoint>(); // Add the intersection even if there isn't one (i.e. infinite lines) bool B1 = true, B2 = true; Line12Bisect.Crosses(Line34Bisect, Int, ref B1, ref B2, true); Debug.Assert(Int.Count == 1); return(Int[0]); }
/// <summary> /// Static version of circumcentre function. /// </summary> public static C2DPoint GetCircumCentre(C2DPoint pt1, C2DPoint pt2, C2DPoint pt3) { var Line12 = new C2DLine(pt1, pt2); var Line23 = new C2DLine(pt2, pt3); // Move the lines to start from the midpoint on them Line12.point.Set(Line12.GetMidPoint()); Line23.point.Set(Line23.GetMidPoint()); // Turn them right (left would work as well) Line12.vector.TurnRight(); Line23.vector.TurnRight(); // Find the intersection between them taking the intersect point even if they don't // intersect directly (i.e. where they would intersect because we may have turned them // the wrong way). var IntPt = new List <C2DPoint>(); bool B1 = true, B2 = true; Line12.Crosses(Line23, IntPt, ref B1, ref B2, true); var ptResult = new C2DPoint(0, 0); if (IntPt.Count == 1) { ptResult = IntPt[0]; } else { // co-linear so fail. Debug.Assert(false, "Colinnear triangle. Cannot calculate Circum Centre"); } return(ptResult); }
/// <summary> /// Static version of Fermat point function. /// </summary> public static C2DPoint GetFermatPoint(C2DPoint pt1, C2DPoint pt2, C2DPoint pt3) { var Line12 = new C2DLine(pt1, pt2); var Line23 = new C2DLine(pt2, pt3); var Line31 = new C2DLine(pt3, pt1); var dAng2 = Constants.conPI - Line12.vector.AngleBetween(Line23.vector); if (dAng2 >= Constants.conTWOTHIRDPI) // greater than 120 degrees { return(new C2DPoint(pt2)); } else if (dAng2 < Constants.conTHIRDPI) // if less than 60 then 1 of the other 2 could be greater than 120 { var dAng3 = Constants.conPI - Line23.vector.AngleBetween(Line31.vector); if (dAng3 >= Constants.conTWOTHIRDPI) // greater than 120 degrees { return(new C2DPoint(pt3)); } else if ((Constants.conPI - dAng2 - dAng3) >= Constants.conTWOTHIRDPI) // if least angle is greater than 120 { return(new C2DPoint(pt1)); } } var bClockwise = Line12.IsOnRight(pt3); if (bClockwise) { Line12.vector.TurnLeft(Constants.conTHIRDPI); // 60 degrees Line23.vector.TurnLeft(Constants.conTHIRDPI); // 60 degrees } else { Line12.vector.TurnRight(Constants.conTHIRDPI); // 60 degrees Line23.vector.TurnRight(Constants.conTHIRDPI); // 60 degrees } Line12.SetPointFrom(pt3); Line23.SetPointFrom(pt1); var IntPt = new List <C2DPoint>(); bool B1 = true, B2 = true; if (Line12.Crosses(Line23, IntPt, ref B1, ref B2, false)) { return(IntPt[0]); } else { Debug.Assert(false); } return(new C2DPoint(0, 0)); }
/// <summary> /// Static version of InCentre function. /// </summary> public static C2DPoint GetInCentre(C2DPoint pt1, C2DPoint pt2, C2DPoint pt3) { // Set up a line to bisect the lines from 1 to 2 and 1 to 3 C2DLine Line1 = new C2DLine(pt1, pt2); C2DLine Line2 = new C2DLine(pt1, pt3); Line1.SetLength( Line2.GetLength() ); C2DLine Line12Bisect = new C2DLine( pt1, pt3.GetMidPoint( Line1.GetPointTo())); // Set up a line to bisect the lines from 2 to 1 and 2 to 3 C2DLine Line3 = new C2DLine(pt2, pt1); C2DLine Line4 = new C2DLine(pt2, pt3); Line3.SetLength( Line4.GetLength() ); C2DLine Line34Bisect = new C2DLine(pt2, pt3.GetMidPoint(Line3.GetPointTo())); // Now intersect the 2 lines and find the point. List<C2DPoint> Int = new List<C2DPoint>(); // Add the intersection even if there isn't one (i.e. infinite lines) bool B1 = true, B2 = true; Line12Bisect.Crosses(Line34Bisect, Int, ref B1, ref B2, true); Debug.Assert (Int.Count == 1); return Int[0]; }
/// <summary> /// Static version of Fermat point function. /// </summary> public static C2DPoint GetFermatPoint(C2DPoint pt1, C2DPoint pt2, C2DPoint pt3) { C2DLine Line12 = new C2DLine(pt1, pt2); C2DLine Line23 = new C2DLine(pt2, pt3); C2DLine Line31 = new C2DLine(pt3, pt1); double dAng2 = Constants.conPI - Line12.vector.AngleBetween(Line23.vector); if (dAng2 >= Constants.conTWOTHIRDPI) // greater than 120 degrees { return new C2DPoint(pt2); } else if (dAng2 < Constants.conTHIRDPI) // if less than 60 then 1 of the other 2 could be greater than 120 { double dAng3 = Constants.conPI - Line23.vector.AngleBetween(Line31.vector); if (dAng3 >= Constants.conTWOTHIRDPI) // greater than 120 degrees { return new C2DPoint(pt3); } else if ((Constants.conPI - dAng2 - dAng3) >= Constants.conTWOTHIRDPI) // if least angle is greater than 120 { return new C2DPoint(pt1); } } bool bClockwise = Line12.IsOnRight(pt3); if (bClockwise) { Line12.vector.TurnLeft(Constants.conTHIRDPI); // 60 degrees Line23.vector.TurnLeft(Constants.conTHIRDPI); // 60 degrees } else { Line12.vector.TurnRight(Constants.conTHIRDPI); // 60 degrees Line23.vector.TurnRight(Constants.conTHIRDPI); // 60 degrees } Line12.SetPointFrom(pt3); Line23.SetPointFrom(pt1); List<C2DPoint> IntPt = new List<C2DPoint>(); bool B1 = true, B2 = true; if (Line12.Crosses(Line23, IntPt, ref B1, ref B2, false)) { return IntPt[0]; } else { Debug.Assert(false); } return new C2DPoint(0, 0); }
/// <summary> /// Static version of circumcentre function. /// </summary> public static C2DPoint GetCircumCentre(C2DPoint pt1, C2DPoint pt2, C2DPoint pt3) { C2DLine Line12 = new C2DLine (pt1, pt2); C2DLine Line23 = new C2DLine (pt2, pt3); // Move the lines to start from the midpoint on them Line12.point.Set( Line12.GetMidPoint()); Line23.point.Set( Line23.GetMidPoint()); // Turn them right (left would work as well) Line12.vector.TurnRight(); Line23.vector.TurnRight(); // Find the intersection between them taking the intersect point even if they don't // intersect directly (i.e. where they would intersect because we may have turned them // the wrong way). List<C2DPoint> IntPt = new List<C2DPoint>(); bool B1 = true , B2 = true; Line12.Crosses(Line23, IntPt,ref B1, ref B2, true); C2DPoint ptResult = new C2DPoint(0, 0); if (IntPt.Count == 1) { ptResult = IntPt[0]; } else { // co-linear so fail. Debug.Assert(false, "Colinnear triangle. Cannot calculate Circum Centre"); } return ptResult; }
/// <summary> /// Splits an edge on a convex polygon into two edges by adding a vertex on a random position /// While keeping the Convex constraint. /// </summary> /// <param name="gm"></param> /// <param name="e"></param> /// <param name="maxOffset"></param> /// <param name="index"></param> /// <returns></returns> public static List<Edge> SplitConvexEdge(GraphManager gm, Edge e, int maxOffset, int index) { var edgeLine = e.CreateLine(); List<Edge> result = new List<Edge>(); //Create random point on the edge var offset = Convert.ToDouble(RandomGenerator.Next(0, 100)) / 122 + 0.1; var point = edgeLine.GetPointOn(offset); //Calculate offsets var dx = e.v2.Point.x - e.v1.Point.x; var dy = e.v2.Point.y - e.v1.Point.y; //Note swapping offsets for X and Y. var offsetX = Math.Abs(dx) / (dy); var offsetY = Math.Abs(dy) / (dx * -1); //Calculate the maximum endpoint for the new node. var endPoint = new C2DPoint(offsetX * maxOffset + point.x, offsetY * maxOffset + point.y); var newLine = new C2DLine(point, endPoint); var otherVertex1 = e.v1; var otherVertex2 = e.v2; var otherEdge1 = otherVertex1.GetOther(e).CreateLine(); var otherEdge2 = otherVertex2.GetOther(e).CreateLine(); //Compare with both other edges, to check if the new vertex would still result in a convex polygon. //If not, update the maximum offset for the new vertex if (otherVertex1.GetOther(e) != otherVertex2.GetOther(e)) { var intersections = new List<C2DPoint>(); otherEdge1.GrowFromCentre(100000000);//Hack: to check if they intersect. The library does not support rays in this case if (newLine.Crosses(otherEdge1, intersections)) { var newEndpoint = intersections.Single(); newLine = new C2DLine(point, newEndpoint); } intersections = new List<C2DPoint>(); otherEdge2.GrowFromCentre(100000000); //Hack: to check if they intersect. The library does not support rays in this case if (newLine.Crosses(otherEdge2, intersections)) { var newEndpoint = intersections.Single(); newLine = new C2DLine(point, newEndpoint); } } //Select a random point on the line (which is bound) var newlineOffset = Convert.ToDouble(RandomGenerator.Next(0, 100)) / 122+0.1; var newPoint = newLine.GetPointOn(offset); var newVertex = new Vertex() { Point = newPoint }; //Indexof might be very slow? Note this is just used for the creation of a testvertex gm.AddVertexAt(newVertex, gm.Vertices.IndexOf(otherVertex2)); gm.DestroyEdge(e);//Unregister the old edge result.Add(gm.CreateEdge(otherVertex1, newVertex)); //Add the two new ones result.Add(gm.CreateEdge(newVertex, otherVertex2)); // :) return result; }