Ejemplo n.º 1
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
            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]);
        }
Ejemplo n.º 2
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);
        }
Ejemplo n.º 3
0
        /// <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));
        }
Ejemplo n.º 4
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];
        }
Ejemplo n.º 5
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);
        }
Ejemplo n.º 6
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;
        }