/// <summary>
 /// Draws a line.
 /// </summary>
 public void Draw(C2DLine Line, Graphics graphics, Pen pen)
 {
     C2DPoint pt1 = Line.GetPointFrom();
     C2DPoint pt2 = Line.GetPointTo();
     this.ScaleAndOffSet(pt1);
     this.ScaleAndOffSet(pt2);
     graphics.DrawLine(pen, (int)pt1.x, (int)pt1.y, (int)pt2.x, (int)pt2.y);
 }
Beispiel #2
0
        /// <summary>
        /// Contructor.
        /// </summary>
        /// <param name="ArcLine">The line defining the start and end point of the arc.</param>
        /// <param name="dRadius">The corresponding circles radius.</param>
        /// <param name="bCentreOnRight">Whether the centre is on the right.</param>
        /// <param name="bArcOnRight">Whether the arc is to the right of the line.</param>
        public C2DArc(C2DLine ArcLine, double dRadius, 
		    bool bCentreOnRight, bool bArcOnRight)
        {
            Line.Set(ArcLine);
            Radius = dRadius;
            CentreOnRight = bCentreOnRight;
            ArcOnRight = bArcOnRight;

        }
Beispiel #3
0
        /// <summary>
        /// Adds a point which is a striaght line from the previous.
        /// </summary>
        /// <param name="Point">The point to go to.</param> 
	    public void LineTo(C2DPoint Point)
        {
	        if (Lines.Count == 0)
		        return;

	        C2DLine pLine = new C2DLine( Lines[Lines.Count - 1].GetPointTo(), Point );

	        if (Lines.Count == 1 && Lines[0] is C2DLine &&
                Lines[0].GetPointTo().PointEqualTo(Lines[0].GetPointFrom()))  // CR 19-1-09
	        {
                Lines[0] = pLine;
	        }
	        else
	        {
                Lines.Add(pLine);
	        }
        }
        /// <summary>
        /// Distance to a point.
        /// </summary>
        /// <param name="ptTest">The test point.</param>
        /// <param name="ptOnThis">Output. The closest point on the triangle.</param>
	    public double Distance(C2DPoint ptTest,  C2DPoint ptOnThis)
        {
	        double dArea = GetAreaSigned();
            bool BTemp = true;
	        // Construct the lines.
	        C2DLine Line12 = new C2DLine(P1, P2);
	        C2DLine Line23 = new C2DLine(P2, P3);
            C2DLine Line31 = new C2DLine(P3, P1);

	        if (dArea == 0)
	        {
		        // Colinear so find the biggest line and return the distance from that
		        double d1 = Line12.GetLength();
		        double d2 = Line23.GetLength();
		        double d3 = Line31.GetLength();
		        if (d1 > d2 && d1 > d3)
			        return Line12.Distance(ptTest,  ptOnThis);
		        else if (d2 > d3)
			        return Line23.Distance(ptTest,  ptOnThis);
		        else
			        return Line31.Distance(ptTest,  ptOnThis);
	        }
	        // Find out it the triangle is clockwise or not.
	        bool bClockwise = dArea < 0;

	        // Set up some pointers to record the lines that the point is "above", "above" meaning that the
	        // point is on the opposite side of the line to the rest of the triangle
	        C2DLine LineAbove1 = null;
            C2DLine LineAbove2 = null;

	        // Find out which Lines have the point above.
	        if (  Line12.IsOnRight( ptTest ) ^ bClockwise  )  // if the pt is on the opposite side to the triangle
		        LineAbove1 = Line12;
	        if ( Line23.IsOnRight( ptTest ) ^ bClockwise)
	        {
		        if (LineAbove1 != null)
			        LineAbove2 = Line23;
		        else
			        LineAbove1 = Line23;
	        }
	        if ( Line31.IsOnRight( ptTest ) ^ bClockwise)
	        {
		        if (LineAbove1 != null)
		        {
			        // We can't have all the lines with the point above.
			        Debug.Assert(LineAbove2 != null);
			        LineAbove2 = Line31;
		        }
		        else
			        LineAbove1 = Line31;
	        }

	        // Check for containment (if there isn't a single line that its above then it must be inside)
	        if (LineAbove1 == null)
	        {
		        // Pt inside so project onto all the lines and find the closest projection (there must be one).
        	
		        // Set up a record of the point projection on the lines.
		        C2DPoint ptOnLine = new C2DPoint();
		        bool bSet = false;
		        double dMinDist = 0;

                if (ptTest.ProjectsOnLine(Line12,  ptOnLine,  ref BTemp))
		        {
			        dMinDist = ptTest.Distance(ptOnLine);
				    ptOnThis.Set(ptOnLine);
			        bSet = true;
		        }
                if (ptTest.ProjectsOnLine(Line23,  ptOnLine, ref BTemp))
		        {
			        double dDist = ptTest.Distance(ptOnLine);
			        if (!bSet || dDist < dMinDist)
			        {
				        dMinDist = dDist;
					    ptOnThis.Set(ptOnLine);
				        bSet = true;
			        }
		        }
                if (ptTest.ProjectsOnLine(Line31,  ptOnLine, ref BTemp))
		        {
			        double dDist = ptTest.Distance(ptOnLine);
			        if (!bSet || dDist < dMinDist)
			        {
				        dMinDist = dDist;
					    ptOnThis.Set(ptOnLine);
				        bSet = true;
			        }
		        }
		        Debug.Assert(bSet);
		        return -dMinDist; //-ve if inside
	        }
	        else if (LineAbove2 == null)
	        {
		        // it is only above 1 of the lines so simply return the distance to that line
		        return LineAbove1.Distance(ptTest,  ptOnThis);
	        }
	        else
	        {
		        // It's above 2 lines so first check them both for projection. Can only be projected on 1.
		        // If the point can be projected onto the line then that's the closest point.
		        C2DPoint ptOnLine = new C2DPoint();
                if (ptTest.ProjectsOnLine(LineAbove1,  ptOnLine, ref BTemp))
		        {
			        ptOnThis = ptOnLine;
			        return ptOnLine.Distance(ptTest);
		        }
                else if (ptTest.ProjectsOnLine(LineAbove2,  ptOnLine, ref BTemp))
		        {
				    ptOnThis = ptOnLine;
			        return ptOnLine.Distance(ptTest);
		        }
		        else
		        {
			        // The point doesn't project onto either line so find the closest point
			        if (LineAbove1 == Line12)
			        {
				        if (LineAbove2 == Line23)
				        {
					        ptOnThis = P2;
					        return ptTest.Distance(P2);
				        }
				        else
				        {
						    ptOnThis = P1;
					        return ptTest.Distance(P1);
				        }
			        }
			        else
			        {
					    ptOnThis = P3;
				        return ptTest.Distance(P3);
			        }
		        }
	        }
        }
 /// <summary>
 /// Reflects this through the line given.
 /// </summary>
 /// <param name="Line">The line to reflect this through.</param>
 public override void Reflect(C2DLine Line)
 {
     // First find the point along the line that this projects onto.
     // Make a vector from the point on the line given to this point.
     C2DVector vecthis = new C2DVector(Line.point, this );
     // Find the length of the line given.
     double dLength = Line.vector.GetLength();
     // Now make the projection of this point on the line.
     double dProj = vecthis.Dot(Line.vector);
     dProj /= dLength;
     // Find the factor along the line that the projection is.
     double dFactor = dProj / dLength;
     // Now set up a copy of the vector of the line given.
     C2DVector vProj = new C2DVector(Line.vector);
     // Multiply that by that factor calculated.
     vProj.Multiply(dFactor);
     // Use the vector to find the point on the line.
     C2DPoint ptOnLine = new C2DPoint(Line.point.GetPointTo(vProj) );
     // Noe simply reflect this in the point.
     this.Reflect(ptOnLine);
 }
        /// <summary>
        /// True if the point projects onto the line given and returns the 
        /// point on the line.
        /// </summary>
        /// <param name="Line"></param>
        public void ProjectOnRay(C2DLine Line)
        {
            C2DVector vecthis = new C2DVector(Line.point, this );
            double dProj = vecthis.Dot(Line.vector);

            double dFactor = dProj / (Line.vector.i * Line.vector.i + Line.vector.j * Line.vector.j );

            C2DVector vProj = new C2DVector(Line.vector);
            vProj.i *= dFactor;
            vProj.j *= dFactor;
            this.Set(Line.point.x + vProj.i, Line.point.y + vProj.j);
        }
        /// <summary>
        /// Projects the point on the line given returning a distance along the line from the start.
        /// </summary>
        /// <param name="Line">The line to project this on.</param>
        public double Project(C2DLine Line)
        {
            C2DVector vecthis = new C2DVector(Line.point, this );

            return (vecthis.Dot(Line.vector)) / Line.vector.GetLength();
        }
Beispiel #8
0
 /// <summary>
 /// Assignment.
 /// </summary>
 /// <param name="Other">The other line.</param>
 public void Set(C2DLine Other)
 {
     point.Set(Other.point);
     vector.Set(Other.vector);
 }
Beispiel #9
0
        /// <summary>
        /// True if the ray provided (infinite line starting from the first point) crosses this. 
        /// </summary>
        /// <param name="Ray">The other line to test.</param>
        /// <param name="IntersectionPts">Output. The intersection points.</param>
	    public bool CrossesRay(C2DLine Ray,  List<C2DPoint> IntersectionPts)
        {
	        C2DPoint p1 = point;
	        C2DPoint p2 = GetPointTo();

	        C2DPoint p3 = Ray.point;
	        C2DPoint p4 = Ray.GetPointTo();

	        double Ua = (p4.x - p3.x)*(p1.y - p3.y) - (p4.y - p3.y) * (p1.x - p3.x);
	        double Ub = (p2.x - p1.x)*(p1.y - p3.y) - (p2.y - p1.y) * (p1.x - p3.x);

	        double dDenominator = (p4.y - p3.y)*(p2.x - p1.x) - (p4.x - p3.x) * (p2.y - p1.y);

	        if (dDenominator == 0) 
                return false;

	        Ua = Ua / dDenominator;
	        Ub = Ub / dDenominator;

	        bool bResult = (Ua >= 0 && Ua <= 1) && (Ub >= 0);

	        if (bResult)
	        {
		        IntersectionPts.Add(new C2DPoint(p1.x + Ua*(p2.x - p1.x) , p1.y + Ua*(p2.y - p1.y)));
	        }

	        return bResult;
        }
Beispiel #10
0
        /// <summary>
        /// True if this line would cross the other if this were infinite.
        /// </summary>
        /// <param name="Other">The other line to test.</param>
	    public bool WouldCross(C2DLine Other)
        {
	        bool bPointOnRight = IsOnRight(Other.point);
	        bool bPointToOnRight = IsOnRight(Other.GetPointTo());

	        return (bPointOnRight^bPointToOnRight);
        }
        /// <summary>
        /// Distance to a circle, returns the closest point on both circles.
        /// </summary>
        /// <param name="Other">Circle to calculate the distance to.</param>
        /// <param name="ptOnThis">Closest point on this circle to recieve the result.</param>
        /// <param name="ptOnOther">Closest point on the other circle to recieve the result.</param>
        public double Distance(C2DCircle Other, C2DPoint ptOnThis, C2DPoint ptOnOther)
        {
            var dCenCenDist  = _Centre.Distance(Other.Centre);
            var dOtherRadius = Other.Radius;

            //    C2DPoint ptThis;
            //   C2DPoint ptOther;
            var dDist = dCenCenDist - Radius - dOtherRadius;

            if (dDist > 0)
            {
                // they do not interect and they are outside each other.
                var Line = new C2DLine(_Centre, Other.Centre);
                Line.vector.SetLength(Radius);
                ptOnThis.Set(Line.GetPointTo());

                Line.vector.Reverse();
                Line.SetPointFrom(Other.Centre);
                Line.vector.SetLength(Other.Radius);
                ptOnOther.Set(Line.GetPointTo());
            }
            else
            {
                if ((dCenCenDist + Radius) < dOtherRadius)
                {
                    // This is inside the other
                    dDist = dCenCenDist + Radius - dOtherRadius;            // -ve if inside
                    var vec = new C2DVector(Other.Centre, Centre);
                    vec.Multiply(Radius / dCenCenDist);                     // set the vector to be the length of my radius.
                    ptOnThis.Set(_Centre.GetPointTo(vec));
                    vec.Multiply(dDist / Radius);                           // set the vector to be the distance.
                    ptOnOther.Set(ptOnThis.GetPointTo(vec));
                }
                else if ((dCenCenDist + dOtherRadius) < Radius)
                {
                    // The other is inside this.
                    dDist = dCenCenDist + dOtherRadius - Radius;              // -ve if inside
                    var vec = new C2DVector(_Centre, Other.Centre);
                    vec.Multiply(dOtherRadius / dCenCenDist);                 // set the vector to be the length of my radius.
                    ptOnOther.Set(Other.Centre.GetPointTo(vec));
                    vec.Multiply(dDist / dOtherRadius);                       // set the vector to be the distance.
                    ptOnThis.Set(ptOnOther.GetPointTo(vec));
                }
                else
                {
                    // there is an intersection
                    dDist = 0;
                    var Ints = new List <C2DPoint>();
                    if (Crosses(Other, Ints))
                    {
                        ptOnThis.Set(Ints[0]);
                        ptOnOther.Set(ptOnThis);
                    }
                    else
                    {
                        Debug.Assert(false);
                        return(0);
                    }
                }
            }

            //      if (ptOnThis)
            //        *ptOnThis = ptThis;
            //      if (ptOnOther)
            //        *ptOnOther = ptOther;

            return(dDist);
        }
        /// <summary>
        /// Distance to a line, returns the closest point on the circle and the line.
        /// </summary>
        /// <param name="Line">Line to calculate the distance to.</param>
        /// <param name="ptOnThis">Closest point on the circle to recieve the result.</param>
        /// <param name="ptOnOther">Closest point on the line to recieve the result.</param>
        public double Distance(C2DLine Line, C2DPoint ptOnThis, C2DPoint ptOnOther)
        {
            var ProjInt = new CInterval();

            Project(Line, ProjInt);

            if (ProjInt.dMax < 0)
            {
                // This means that the circle projects entirely "below" the line so the nearest point
                // To this is the first point on the line and there are no interections.
                ptOnOther.Set(Line.point);

                return(Distance(Line.point, ptOnThis));
            }

            var dLength = Line.GetLength();

            if (ProjInt.dMin > dLength)
            {
                // This means that the circle projects entirely "above" the line so the nearest point
                // To this is the second point on the line and there are no interections.
                var ptClosest = new C2DPoint(Line.GetPointTo());
                ptOnOther.Set(ptClosest);
                return(Distance(ptClosest, ptOnThis));
            }

            // Now find out if there's an intersection.
            var IntPts = new List <C2DPoint>();

            if (Crosses(Line, IntPts))
            {
                ptOnThis.Set(IntPts[0]);
                ptOnOther.Set(IntPts[0]);

                return(0);
            }

            // Now find out if the line is entirely inside
            if (ProjInt.dMin > 0 && ProjInt.dMax < dLength && this.Contains(Line.point))
            {
                var d1         = Distance(Line.point, ptOnThis);
                var ptThisTemp = new C2DPoint();
                var d2         = Distance(Line.GetPointTo(), ptThisTemp);
                Debug.Assert(d1 < 0 && d2 < 0);
                if (d2 > d1) // NOTE USE OF > AS d2 and d1 are -ve.
                {
                    ptOnThis.Set(ptThisTemp);
                    ptOnOther.Set(Line.GetPointTo());
                    return(d2);
                }
                else
                {
                    ptOnOther.Set(Line.point);
                    return(d1);
                }
            }

            // We now know the line is entirely outside.
            // Now find out if this is closest to a point on the line.
            var dCenOnLine = (ProjInt.dMax + ProjInt.dMin) / 2.0;

            if (dCenOnLine > 0)
            {
                if (dCenOnLine < dLength)
                {
                    // The centre is projected on the line
                    var dFactor = dCenOnLine / dLength;

                    var vProj = new C2DVector(Line.vector);
                    vProj.Multiply(dFactor);
                    var ptOnLine = new C2DPoint(Line.point.GetPointTo(vProj));

                    ptOnOther.Set(ptOnLine);

                    return(Distance(ptOnLine, ptOnThis));
                }
                else
                {
                    // The centre is projected above the line.
                    var ptClosest = new C2DPoint(Line.GetPointTo());
                    ptOnOther.Set(ptClosest);
                    return(Distance(ptClosest, ptOnThis));
                }
            }
            else
            {
                // This means that the circle projects entirely "below" the line.
                ptOnOther.Set(Line.point);
                return(Distance(Line.point, ptOnThis));
            }
        }
 /// <summary>
 /// Reflection trhough a line.
 /// </summary>
 /// <param name="Line">The line to reflect this through.</param>
 public override void Reflect(C2DLine Line)
 {
     _Centre.Reflect(Line);
 }
        /// <summary>
        /// True if this crosses the line and returns the intersectin points.
        /// </summary>
        /// <param name="Line">The line.</param>
        /// <param name="IntersectionPts">The point set to recieve the result.</param>
        public bool Crosses(C2DLine Line, List <C2DPoint> IntersectionPts)
        {
            var x1 = Line.point.x;
            var x2 = Line.point.x + Line.vector.i;
            var x3 = _Centre.x;

            var y1 = Line.point.y;
            var y2 = Line.point.y + Line.vector.j;
            var y3 = _Centre.y;

            var r = Radius;

            var a = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);

            var b = 2 * ((x2 - x1) * (x1 - x3) + (y2 - y1) * (y1 - y3));

            var c = x3 * x3 + y3 * y3 + x1 * x1 + y1 * y1 - 2 * (x3 * x1 + y3 * y1) - r * r;

            var u = -b / (2 * a);

            var ptClosestToCen = new C2DPoint();

            if (u < 0)
            {
                ptClosestToCen.Set(Line.point);
            }
            else if (u > 1)
            {
                ptClosestToCen.Set(Line.GetPointTo());
            }
            else
            {
                var V1 = new C2DVector(Line.vector);
                V1.Multiply(u);
                ptClosestToCen = Line.point.GetPointTo(V1);
            }

            var dDist = ptClosestToCen.Distance(_Centre);

            if (dDist > Radius)
            {
                return(false);
            }
            else
            {
                // Calculate the points.
                var d1 = b * b - 4 * a * c;
                Debug.Assert(d1 >= 0);

                if (d1 < 0)
                {
                    return(false);
                }
                else if (d1 == 0)
                {
                    var p1 = -b / (2 * a);
                    IntersectionPts.Add(Line.GetPointOn(p1));
                    return(true);
                }
                else
                {
                    d1 = Math.Sqrt(d1);
                    var p1 = (-b + d1) / (2 * a);
                    var p2 = (-b - d1) / (2 * a);

                    var bResult = false;
                    if (p2 >= 0 && p2 <= 1)
                    {
                        bResult = true;
                        IntersectionPts.Add(Line.GetPointOn(p2));
                    }

                    if (p1 >= 0 && p1 <= 1)
                    {
                        bResult = true;
                        IntersectionPts.Add(Line.GetPointOn(p1));
                    }

                    return(bResult);
                }
            }
        }
Beispiel #15
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);
        }
Beispiel #16
0
 /// <summary>
 /// Projects this onto the line given.
 /// </summary>
 /// <param name="Line">Line to project on.</param> 
 /// <param name="Interval">Ouput. Projection.</param> 
 public override void Project(C2DLine Line, CInterval Interval)
 {
     P1.Project(Line,  Interval);
     Interval.ExpandToInclude(P2.Project(Line));
     Interval.ExpandToInclude(P3.Project(Line));
 }
 /// <summary>
 /// Projects the point on the vector given returning a distance along the vector.
 /// </summary>
 /// <param name="line">The vector to project this on.</param>
 /// <param name="interval">The interval to recieve the result.
 /// Both the min and max of the interval will be set to the result.</param>
 public override void Project(C2DLine line, CInterval interval)
 {
     interval.dMax = Project(line);
     interval.dMin = interval.dMax;
 }
Beispiel #18
0
        /// <summary>
        /// True if this line crosses the other. Returns the point is a collection is provided.
        /// Returns whether it would cross on this or on the other. Can opt to get the point 
        /// where the cross would occur (if not parallel) even if they don't cross.
        /// </summary>
        /// <param name="Other">The other line</param>
        /// <param name="IntersectionPts">To recieve the result</param>
        /// <param name="bOnThis">Output. True is the intersection would be on this line.</param>
        /// <param name="bOnOther">Output. True is the intersection would be on the other line.</param>
        /// <param name="bAddPtIfFalse">Input. True to add the intersection point even if there is no intersection.</param>
        /// <returns></returns>
        public bool Crosses(C2DLine Other,  List<C2DPoint> IntersectionPts , 
		    ref bool bOnThis, ref bool bOnOther, bool bAddPtIfFalse)
        {
	        bOnThis = false;
	        bOnOther = false;

	        C2DPoint p1 = point;
	        C2DPoint p2 = GetPointTo();

	        C2DPoint p3 = Other.point;
	        C2DPoint p4 = Other.GetPointTo();

	        double Ua = (p4.x - p3.x)*(p1.y - p3.y) - (p4.y - p3.y) * (p1.x - p3.x);
	        double Ub = (p2.x - p1.x)*(p1.y - p3.y) - (p2.y - p1.y) * (p1.x - p3.x);

	        double dDenominator = (p4.y - p3.y)*(p2.x - p1.x) - (p4.x - p3.x) * (p2.y - p1.y);

	        if (dDenominator == 0) 
                return false;

	        Ua = Ua / dDenominator;
	        Ub = Ub / dDenominator;

	        bOnThis = (Ua >= 0 && Ua < 1);		// For ints we need the line to be the point set [a,b);
	        bOnOther = (Ub >= 0 && Ub < 1);		// For ints we need the line to be the point set [a,b);
	        bool bResult  = bOnThis && bOnOther;

	        if (bAddPtIfFalse || bResult)
	        {
		        IntersectionPts.Add(new C2DPoint(p1.x + Ua*(p2.x - p1.x) , p1.y + Ua*(p2.y - p1.y)));
	        }

	        return (bResult); 

        }
Beispiel #19
0
 /// <summary>
 /// Projection onto the line.
 /// </summary>
 /// <param name="Line">Line to project this on.</param>
 /// <param name="Interval">Interval to recieve the result.</param>
 public void Project(C2DLine Line, CInterval Interval)
 {
     _Rim.Project(Line, Interval);
 }
Beispiel #20
0
        /// <summary>
        /// Point reflection.
        /// </summary>
        /// <param name="Line">The line through which to reflect this.</param>
        public override void Reflect(C2DLine Line)
        {
	        C2DPoint pointTo = new C2DPoint(GetPointTo());
	        point.Reflect(Line);
	        pointTo.Reflect(Line);
	        SetPointTo(pointTo);
        }
Beispiel #21
0
        /// <summary>
        /// True if part of this line is above the other. Returns the point
        /// on this and on the other.
        /// </summary>
        /// <param name="Other"></param>
        /// <param name="dVerticalDistance"></param>
        /// <param name="ptOnThis"></param>
        /// <param name="ptOnOther"></param>
        /// <returns></returns>
        public bool OverlapsAbove(C2DLine Other, ref double dVerticalDistance,
                                  C2DPoint ptOnThis, C2DPoint ptOnOther)
        {
            // Get the 2 points for both lines
            C2DPoint OtherTo = new C2DPoint(Other.point.x + Other.vector.i, Other.point.y + Other.vector.j);
            C2DPoint ThisTo  = new C2DPoint(point.x + vector.i, point.y + vector.j);
            // Make an interval for both in the x plane
            CInterval iThis = new CInterval(point.x, point.x);

            iThis.ExpandToInclude(ThisTo.x);

            CInterval iOther = new CInterval(Other.point.x, Other.point.x);

            iOther.ExpandToInclude(OtherTo.x);
            // This is an interval for the overlap between the 2
            CInterval iOverlap = new CInterval();

            // If there is an overlap...
            if (iThis.Overlaps(iOther, iOverlap))
            {
                double dThisYMin;
                double dThisYMax;

                double dOtherYMin;
                double dOtherYMax;
                // If the line is vertical then y at the x min / max can be set to the ends of the line.
                if (vector.i == 0)
                {
                    dThisYMin = point.y;
                    dThisYMax = ThisTo.y;
                }
                else            // otherwise, caluclate the y values at the interval ends
                {
                    dThisYMin = GetY(iOverlap.dMin);
                    dThisYMax = GetY(iOverlap.dMax);
                }
                // Now do the same for the other line
                if (Other.vector.i == 0)
                {
                    dOtherYMin = Other.point.y;
                    dOtherYMax = OtherTo.y;
                }
                else
                {
                    dOtherYMin = Other.GetY(iOverlap.dMin);
                    dOtherYMax = Other.GetY(iOverlap.dMax);
                }

                // Now find the distance between the 2 at the ends
                double dDistMin = dThisYMin - dOtherYMin;
                double dDistMax = dThisYMax - dOtherYMax;
                // If they are both > 0 then no intersection
                if ((dDistMin > 0) && (dDistMax > 0))
                {
                    dDistMin = Math.Abs(dDistMin);
                    dDistMax = Math.Abs(dDistMax);
                    // find which one is smallest
                    if (dDistMin > dDistMax)
                    {
                        dVerticalDistance = dDistMax;                   // distance at the max is smallest
                        ptOnThis.x        = iOverlap.dMax;
                        ptOnThis.y        = dThisYMax;
                        ptOnOther.x       = iOverlap.dMax;
                        ptOnOther.y       = dOtherYMax;
                    }
                    else
                    {
                        dVerticalDistance = dDistMin;                  // distance at the min is smallest
                        ptOnThis.x        = iOverlap.dMin;
                        ptOnThis.y        = dThisYMin;
                        ptOnOther.x       = iOverlap.dMin;
                        ptOnOther.y       = dOtherYMin;
                    }

                    return(true);
                }
                else if ((dDistMin < 0) && (dDistMax < 0))          // This is below.
                {
                    return(false);
                }
                else
                {
                    // find the intersection.
                    dVerticalDistance = 0;
                    C2DPointSet pts = new C2DPointSet();
                    if (this.Crosses(Other, pts))
                    {
                        ptOnThis  = pts[0];
                        ptOnOther = ptOnThis;
                    }
                    else
                    {
                        Debug.Assert(false);
                    }
                }

                return(true);
            }
            else
            {
                return(false);
            }
        }
Beispiel #22
0
 /// <summary>
 /// Contructor.
 /// </summary>
 /// <param name="Line">The line defining the start and end point of the arc.</param>
 /// <param name="dRadius">The corresponding circles radius.</param>
 /// <param name="bCentreOnRight">Whether the centre is on the right.</param>
 /// <param name="bArcOnRight">Whether the arc is to the right of the line.</param>
 public C2DSegment(C2DLine Line, double dRadius,
                   bool bCentreOnRight, bool bArcOnRight)
 {
     Arc.Set(Line, dRadius, bCentreOnRight, bArcOnRight);
 }
Beispiel #23
0
        /// <summary>
        /// Projects the point on the line given returning a distance along the line from the start.
        /// </summary>
        /// <param name="Line">The line to project this on.</param>
        public double Project(C2DLine Line)
        {
            C2DVector vecthis = new C2DVector(Line.point, this);

            return((vecthis.Dot(Line.vector)) / Line.vector.GetLength());
        }
 /// <summary>
 /// Projects the point on the vector given returning a distance along the vector.
 /// </summary>
 /// <param name="Line">The vector to project this on.</param>
 /// <param name="Interval">The interval to recieve the result. 
 /// Both the min and max of the interval will be set to the result.</param>
 public override void Project(C2DLine Line,  CInterval Interval)
 {
     Interval.dMax = Project(Line);
     Interval.dMin = Interval.dMax;
 }
Beispiel #25
0
 /// <summary>
 /// Projects the point on the vector given returning a distance along the vector.
 /// </summary>
 /// <param name="Line">The vector to project this on.</param>
 /// <param name="Interval">The interval to recieve the result.
 /// Both the min and max of the interval will be set to the result.</param>
 public override void Project(C2DLine Line, CInterval Interval)
 {
     Interval.dMax = Project(Line);
     Interval.dMin = Interval.dMax;
 }
        /// <summary>
        /// True if the point projects onto the line given and returns the point on the line.
        /// Also returns whether the line projects above or below the line if relevant.
        /// </summary>
        /// <param name="Line">The line to project this on.</param>
        /// <param name="ptOnLine">The point to recieve the result.</param>
        /// <param name="bAbove">The flag to indicate whether it projects above or below.</param>
        public bool ProjectsOnLine(C2DLine Line,  C2DPoint ptOnLine , 
		    ref bool bAbove)
        {
            C2DVector vecthis = new C2DVector(x - Line.point.x, y - Line.point.y);
            double dProj = vecthis.Dot(Line.vector);

            if (dProj < 0)
            {
                bAbove = false;
                return false;
            }

            double dLength = Line.vector.GetLength();

            dProj /= dLength;

            if (dProj > dLength)
            {
                bAbove = true;
                return false;
            }

            double dFactor = dProj / dLength;

            C2DVector vProj = new C2DVector(Line.vector);
            vProj.Multiply(dFactor);
            ptOnLine.Set(Line.point.x + vProj.i, Line.point.y + vProj.j);
            return true;
        }
Beispiel #27
0
 /// <summary>
 /// Reflection in a line
 /// </summary>
 public abstract void Reflect(C2DLine Line);
Beispiel #28
0
        /// <summary>
        /// Reflects the in the line given.
        /// </summary>
        /// <param name="Line">The line to reflect through.</param>
        public override void Reflect(C2DLine Line)
        {
    	    P1.Reflect(Line);
	        P2.Reflect(Line);
    	    P3.Reflect(Line);
        }
Beispiel #29
0
 /// <summary>
 /// Projects this onto the line provided with the interval on the line returned.
 /// </summary>
 public abstract void Project(C2DLine Line, CInterval Interval);
Beispiel #30
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>
        /// Returns the distance from this to the other line.
        /// </summary>
        /// <param name="Other">The Other line.</param>
        /// <param name="ptOnThis">Output. The closest point on this.</param>
        /// <param name="ptOnOther">Output. The closest point on the other line.</param>
        public double Distance(C2DLine Other, C2DPoint ptOnThis, C2DPoint ptOnOther)
        {
            // First, project the other line onto this and if it falls entirely below it or
            // above it then 1. There is no intersection, 2. This is closest to one end on this line.
            var ptOtherP2      = new C2DPoint(Other.GetPointTo());
            var vThisP1OtherP1 = new C2DVector(point, Other.point);
            var vThisP1OtherP2 = new C2DVector(point, ptOtherP2);
            var ptThisP2       = new C2DPoint(GetPointTo());

            var dOtherP1Proj = vThisP1OtherP1.Dot(vector);
            var dOtherP2Proj = vThisP1OtherP2.Dot(vector);

            // If they are both less than 0 then the projection falls below the line.
            if (dOtherP1Proj <= 0 && dOtherP2Proj <= 0)
            {
                ptOnThis.Set(point);
                return(Other.Distance(point, ptOnOther));
            }
            // Now modify the projection so it is the length along this line.
            var dThisLength = GetLength();

            dOtherP1Proj = dOtherP1Proj / dThisLength;
            dOtherP2Proj = dOtherP2Proj / dThisLength;
            // If the projections are both above the line then the second point is closest
            if (dOtherP1Proj >= dThisLength && dOtherP2Proj >= dThisLength)
            {
                ptOnThis.Set(ptThisP2);
                return(Other.Distance(ptThisP2, ptOnOther));
            }

            // This hasn't worked so try the same on the other line.
            var vOtherP1ThisP1 = new C2DVector(Other.point, point);
            var vOtherP1ThisP2 = new C2DVector(Other.point, ptThisP2);

            var dThisP1Proj = vOtherP1ThisP1.Dot(Other.vector);
            var dThisP2Proj = vOtherP1ThisP2.Dot(Other.vector);

            // If they are both less than 0 then the projection falls below the line.
            if (dThisP1Proj <= 0 && dThisP2Proj <= 0)
            {
                ptOnOther.Set(Other.point);
                return(Distance(Other.point, ptOnThis));
            }
            // Now modify the projection so it is the length along this line.
            var dOtherLength = Other.GetLength();

            dThisP1Proj = dThisP1Proj / dOtherLength;
            dThisP2Proj = dThisP2Proj / dOtherLength;
            // If the projections are both above the line then the second point is closest
            if (dThisP1Proj >= dOtherLength && dThisP2Proj >= dOtherLength)
            {
                ptOnOther.Set(ptOtherP2);
                return(Distance(ptOtherP2, ptOnThis));
            }
            // Now test for an intersection.
            var  IntPoint = new List <C2DPoint>();
            bool B1 = true, B2 = true;

            if (this.Crosses(Other, IntPoint, ref B1, ref B2, false))
            {
                ptOnOther.Set(IntPoint[0]);
                ptOnThis.Set(IntPoint[0]);
                return(0);
            }
            // Otherwise, there MUST be a point projection on one of the lines otherwise both
            // lines project on either side of each other which is impossible.
            // So find the distances to all these projections and take the minimum.
            double dDist    = 0;
            double dMinDist = 0;
            var    bSet     = false;


            var ptOnThisTemp  = new C2DPoint();
            var ptOnOtherTemp = new C2DPoint();

            // Is the other lines first point projected on this?
            if (dOtherP1Proj >= 0 && dOtherP1Proj <= dThisLength)
            {
                // If so find the point on this line and get distance to it.
                var dFactor = dOtherP1Proj / dThisLength;
                ptOnThisTemp.Set(new C2DPoint(point.x + vector.i * dFactor,
                                              point.y + vector.j * dFactor));

                dMinDist = Other.point.Distance(ptOnThisTemp);
                bSet     = true;

                ptOnOther.Set(Other.point);
                ptOnThis.Set(ptOnThisTemp);
            }
            // Is the other lines second point projected onto this?
            if (dOtherP2Proj >= 0 && dOtherP2Proj <= dThisLength)
            {
                // If so find the point on this and then the distance. Is it less?
                var dFactor = dOtherP2Proj / dThisLength;
                ptOnThisTemp.Set(new C2DPoint(point.x + vector.i * dFactor,
                                              point.y + vector.j * dFactor));

                dDist = ptOtherP2.Distance(ptOnThisTemp);
                if (!bSet || dDist < dMinDist)
                {
                    ptOnOther.Set(ptOtherP2);
                    ptOnThis.Set(ptOnThisTemp);
                    dMinDist = dDist;

                    bSet = true;
                }
            }
            // Is the first point on this projected onto the other line?
            if (dThisP1Proj >= 0 && dThisP1Proj <= dOtherLength)
            {
                // If so find the point and the distance. Is it less?
                var dFactor = dThisP1Proj / dOtherLength;
                ptOnOtherTemp.Set(new C2DPoint(Other.point.x + Other.vector.i * dFactor,
                                               Other.point.y + Other.vector.j * dFactor));

                dDist = point.Distance(ptOnOtherTemp);
                if (!bSet || dDist < dMinDist)
                {
                    ptOnThis.Set(point);
                    ptOnOther.Set(ptOnOtherTemp);
                    dMinDist = dDist;

                    bSet = true;
                }
            }

            // Is the second point on this projected onto the other line?
            if (dThisP2Proj >= 0 && dThisP2Proj <= dOtherLength)
            {
                // If so find the point and the distance. Is it less?
                var dFactor = dThisP2Proj / dOtherLength;

                ptOnOtherTemp.Set(new C2DPoint(Other.point.x + Other.vector.i * dFactor,
                                               Other.point.y + Other.vector.j * dFactor));

                dDist = ptThisP2.Distance(ptOnOtherTemp);
                if (!bSet || dDist < dMinDist)
                {
                    ptOnThis.Set(ptThisP2);
                    ptOnOther.Set(ptOnOtherTemp);
                    dMinDist = dDist;

                    bSet = true;
                }
            }

            Debug.Assert(bSet);
            // Now return the minimum distance
            return(dMinDist);
        }
Beispiel #32
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>
 /// Constructor.
 /// </summary>
 /// <param name="Other">The other line.</param>
 public C2DLine(C2DLine Other)
 {
     point.Set(Other.point);
     vector.Set(Other.vector);
 }
        /// <summary>
        /// Own cross creation. Line-line intersection Wikipedia
        /// </summary>
        /// <param name="Other"></param>
        /// <returns></returns>
        public bool Crosses(C2DLine Other)
        {
            C2DPoint p1 = point;
            C2DPoint p2 = GetPointTo();

            C2DPoint p3 = Other.point;
            C2DPoint p4 = Other.GetPointTo();

            double Ua = (p1.x * p2.y - p1.y * p2.x) * (p3.x - p4.x) - (p1.x - p2.x) * (p3.x * p4.y - p3.y * p4.x);
            double Ub = (p1.x * p2.y - p1.y * p2.x) * (p3.y - p4.y) - (p1.y - p2.y) * (p3.x * p4.y - p3.y * p4.x);

            double dDenominator = (p1.x - p2.x) * (p3.y - p4.y) - (p1.y - p2.y) * (p3.x - p4.x);

            if (dDenominator == 0)
                return false;

            Ua = Ua / dDenominator;
            Ub = Ub / dDenominator;

            bool result = (Ua >= 0 && Ua < 1) && (Ub >= 0 && Ub < 1);

            return result;
        }
 /// <summary>
 /// Reflects the in the line given.
 /// </summary>
 /// <param name="Line">The line to reflect through.</param>
 public override void Reflect(C2DLine Line)
 {
     Arc.Reflect( Line);
 }
Beispiel #36
0
        /// <summary>
        /// True if this line crosses the other line, returns the intersection pt.
        /// </summary>
        /// <param name="Other">The other line to test.</param>
        /// <param name="IntersectionPts">Output. The intersection points.</param>
        public bool Crosses(C2DLine Other,  List<C2DPoint> IntersectionPts)
        {
            bool bOnThis = true;
            bool bOnOther = true;

            return Crosses(Other,  IntersectionPts, ref bOnThis, ref bOnOther, false);
        }
        /// <summary>
        /// Contructor.
        /// </summary>
        /// <param name="Line">The line defining the start and end point of the arc.</param>
        /// <param name="dRadius">The corresponding circles radius.</param>
        /// <param name="bCentreOnRight">Whether the centre is on the right.</param>
        /// <param name="bArcOnRight">Whether the arc is to the right of the line.</param>
        public C2DSegment(C2DLine Line, double dRadius, 
		    bool bCentreOnRight, bool bArcOnRight)
        {
            Arc.Set( Line, dRadius, bCentreOnRight, bArcOnRight);
        }
Beispiel #38
0
        /// <summary>
        /// Function to join the 2 lines at the point where they do / would intersect. If they do then
        /// the lines are clipped to remove the smallest part of the line. Returns false if they
        /// cannot be joined.
        /// </summary>
        /// <param name="Other">The other line</param>
        public bool Join(C2DLine Other)
        {
            C2DPoint p1 = point;
            C2DPoint p2 = GetPointTo();

            C2DPoint p3 = Other.point;
            C2DPoint p4 = Other.GetPointTo();

            double Ua = (p4.x - p3.x) * (p1.y - p3.y) - (p4.y - p3.y) * (p1.x - p3.x);
            double Ub = (p2.x - p1.x) * (p1.y - p3.y) - (p2.y - p1.y) * (p1.x - p3.x);

            double dDenominator = (p4.y - p3.y) * (p2.x - p1.x) - (p4.x - p3.x) * (p2.y - p1.y);

            if (dDenominator == 0)
                return false;

            Ua = Ua / dDenominator;
            Ub = Ub / dDenominator;

            C2DPoint IntPt = new C2DPoint(p1.x + Ua * (p2.x - p1.x), p1.y + Ua * (p2.y - p1.y));
            if ( Ua >=0.5)
                this.SetPointTo( IntPt );
            else
                this.SetPointFrom( IntPt );

            if ( Ub >=0.5)
                Other.SetPointTo( IntPt );
            else
                Other.SetPointFrom( IntPt );

            return true;
        }
        /// <summary>
        /// Reflects throught the line provided.
        /// </summary>
        /// <param name="Line">Line through which to reflect this.</param> 
        public void Reflect(C2DLine Line)
        {
            _Rim.Reflect(Line);

	        for (int i = 0 ; i < _Holes.Count; i++)
	        {
		        _Holes[i].Reflect(Line);
	        }
        }
Beispiel #40
0
        /// <summary>
        /// Returns the distance from this to the other line.
        /// </summary>
        /// <param name="Other">The Other line.</param>
        /// <param name="ptOnThis">Output. The closest point on this.</param>
        /// <param name="ptOnOther">Output. The closest point on the other line.</param>
	    public double Distance(C2DLine Other,  C2DPoint ptOnThis ,  C2DPoint ptOnOther) 
        {
            // First, project the other line onto this and if it falls entirely below it or
	        // above it then 1. There is no intersection, 2. This is closest to one end on this line.
	        C2DPoint ptOtherP2 = new C2DPoint(Other.GetPointTo());
	        C2DVector vThisP1OtherP1 = new C2DVector(point, Other.point);
	        C2DVector vThisP1OtherP2 = new C2DVector(point, ptOtherP2);
	        C2DPoint ptThisP2 = new C2DPoint(GetPointTo());

	        double dOtherP1Proj = vThisP1OtherP1.Dot(vector);
	        double dOtherP2Proj = vThisP1OtherP2.Dot(vector);
	        // If they are both less than 0 then the projection falls below the line.
	        if (dOtherP1Proj <= 0 && dOtherP2Proj <= 0)
	        {
			    ptOnThis.Set(point);
		        return Other.Distance(point,  ptOnOther);
	        }
	        // Now modify the projection so it is the length along this line.
	        double dThisLength = GetLength();
	        dOtherP1Proj = dOtherP1Proj / dThisLength;
	        dOtherP2Proj = dOtherP2Proj / dThisLength;
	        // If the projections are both above the line then the second point is closest
	        if (dOtherP1Proj >= dThisLength && dOtherP2Proj >= dThisLength)
	        {
		        ptOnThis.Set(ptThisP2);
		        return Other.Distance( ptThisP2,   ptOnOther);
	        }

	        // This hasn't worked so try the same on the other line.
	        C2DVector vOtherP1ThisP1 = new C2DVector (Other.point, point);
	        C2DVector vOtherP1ThisP2 = new C2DVector(Other.point, ptThisP2);

	        double dThisP1Proj = vOtherP1ThisP1.Dot(Other.vector);
	        double dThisP2Proj = vOtherP1ThisP2.Dot(Other.vector);
	        // If they are both less than 0 then the projection falls below the line.
	        if (dThisP1Proj <= 0 && dThisP2Proj <= 0)
	        {
			    ptOnOther.Set( Other.point);
		        return Distance(Other.point,  ptOnThis);
	        }
	        // Now modify the projection so it is the length along this line.
	        double dOtherLength = Other.GetLength();
	        dThisP1Proj = dThisP1Proj / dOtherLength;
	        dThisP2Proj = dThisP2Proj / dOtherLength;
	        // If the projections are both above the line then the second point is closest
	        if (dThisP1Proj >= dOtherLength && dThisP2Proj >= dOtherLength)
	        {
			    ptOnOther.Set(ptOtherP2);
		        return Distance( ptOtherP2,   ptOnThis);
	        }
	        // Now test for an intersection.
            List<C2DPoint> IntPoint = new List<C2DPoint>();
            bool B1 = true, B2 = true;
            if (this.Crosses(Other,  IntPoint,ref  B1, ref B2, false))
	        {
			    ptOnOther.Set(IntPoint[0]);
			    ptOnThis.Set(IntPoint[0]);
		        return 0;
	        }
	        // Otherwise, there MUST be a point projection on one of the lines otherwise both
	        // lines project on either side of each other which is impossible. 
	        // So find the distances to all these projections and take the minimum.
	        double dDist = 0;
	        double dMinDist = 0;
	        bool bSet = false;


            C2DPoint ptOnThisTemp = new C2DPoint();
            C2DPoint ptOnOtherTemp = new C2DPoint(); 
	        // Is the other lines first point projected on this?
	        if (dOtherP1Proj >= 0 && dOtherP1Proj <= dThisLength)
	        {
		        // If so find the point on this line and get distance to it.
		        double dFactor = dOtherP1Proj / dThisLength;
                ptOnThisTemp.Set(new C2DPoint(point.x + vector.i * dFactor,
								           point.y + vector.j * dFactor) );

                dMinDist = Other.point.Distance(ptOnThisTemp);
		        bSet = true;

			    ptOnOther.Set(Other.point);
                ptOnThis.Set(ptOnThisTemp);
	        }
            // Is the other lines second point projected onto this?
	        if (dOtherP2Proj >= 0 && dOtherP2Proj <= dThisLength)
	        {
		        // If so find the point on this and then the distance. Is it less?
		        double dFactor = dOtherP2Proj / dThisLength;
		        ptOnThisTemp.Set( new C2DPoint(point.x + vector.i * dFactor,
											           point.y + vector.j * dFactor) );

                dDist = ptOtherP2.Distance(ptOnThisTemp);
		        if (!bSet || dDist < dMinDist)
		        {
				    ptOnOther.Set(ptOtherP2);
                    ptOnThis.Set(ptOnThisTemp);
			        dMinDist = dDist;

			        bSet = true;
		        }
	        }
	        // Is the first point on this projected onto the other line?
	        if (dThisP1Proj >= 0 && dThisP1Proj <= dOtherLength)
	        {
		        // If so find the point and the distance. Is it less?
		        double dFactor = dThisP1Proj / dOtherLength;
		        ptOnOtherTemp.Set( new C2DPoint(Other.point.x + Other.vector.i * dFactor,
								         Other.point.y + Other.vector.j * dFactor));

                dDist = point.Distance(ptOnOtherTemp);
		        if (!bSet || dDist < dMinDist)
		        {
				    ptOnThis.Set(point);
                    ptOnOther.Set(ptOnOtherTemp);
			        dMinDist = dDist;

			        bSet = true;
		        }

	        }

	        // Is the second point on this projected onto the other line?
	        if (dThisP2Proj >= 0 && dThisP2Proj <= dOtherLength)
	        {
		        // If so find the point and the distance. Is it less?
		        double dFactor = dThisP2Proj / dOtherLength;

		        ptOnOtherTemp.Set( new C2DPoint(Other.point.x + Other.vector.i * dFactor,
											         Other.point.y + Other.vector.j * dFactor));

                dDist = ptThisP2.Distance(ptOnOtherTemp);
		        if (!bSet || dDist < dMinDist)
		        {
				    ptOnThis.Set(ptThisP2);
                    ptOnOther.Set(ptOnOtherTemp);
			        dMinDist = dDist;

			        bSet = true;
		        }
	        }

	        Debug.Assert( bSet );
	        // Now return the minimum distance
	        return dMinDist;

        }
 /// <summary>
 /// Projection onto the line.
 /// </summary>
 /// <param name="Line">Line to project this on.</param> 
 /// <param name="Interval">Interval to recieve the result.</param> 
 public void Project(C2DLine Line, CInterval Interval) 
 {
     _Rim.Project(Line, Interval);
 }
Beispiel #42
0
        /// <summary>
        /// Projection onto a line.
        /// </summary>
        /// <param name="TestLine">The line to project this on.</param>
        /// <param name="Interval">Output. The interval.</param>
        public override void Project(C2DLine TestLine,  CInterval Interval)
        {
            double dP1 = point.Project(TestLine);
	        Interval.dMax = dP1;
	        Interval.dMin = dP1;
            Interval.ExpandToInclude(GetPointTo().Project(TestLine));
        }
        /// <summary>
        /// True if this crosses the ray, returns the intersection points.
        /// </summary>
        /// <param name="Ray">Ray to test for.</param> 
        /// <param name="IntersectionPts">Intersection points.</param> 
        public bool CrossesRay(C2DLine Ray, C2DPointSet IntersectionPts) 
        {
	        C2DPointSet IntPts = new C2DPointSet();

            _Rim.CrossesRay(Ray, IntPts);

	        IntersectionPts.ExtractAllOf(IntPts);

	        for (int i = 0 ; i < _Holes.Count; i++)
	        {
		        if (_Holes[i].CrossesRay(Ray, IntPts))
		        {
			        double dDist = Ray.point.Distance(IntPts[0]);
			        int nInsert = 0;

			        while (nInsert < IntersectionPts.Count && 
				        Ray.point.Distance( IntersectionPts[nInsert]) < dDist )
			        {
				        nInsert++;
			        }

			        IntersectionPts.InsertRange(nInsert, IntPts);
		        }
	        }

	        return (IntersectionPts.Count > 0);

        }
Beispiel #44
0
        /// <summary>
        /// True if part of this line is above the other. Returns the point 
        /// on this and on the other.
        /// </summary>
        /// <param name="Other"></param>
        /// <param name="dVerticalDistance"></param>
        /// <param name="ptOnThis"></param>
        /// <param name="ptOnOther"></param>
        /// <returns></returns>
        public bool OverlapsAbove(C2DLine Other, ref double dVerticalDistance, 
									        C2DPoint ptOnThis, C2DPoint ptOnOther)
        {
	        // Get the 2 points for both lines
	        C2DPoint OtherTo = new C2DPoint(Other.point.x + Other.vector.i, Other.point.y + Other.vector.j);
	        C2DPoint ThisTo = new C2DPoint(point.x + vector.i, point.y + vector.j);
	        // Make an interval for both in the x plane
	        CInterval iThis = new CInterval( point.x, point.x);
	        iThis.ExpandToInclude( ThisTo.x );

	        CInterval iOther = new CInterval( Other.point.x, Other.point.x);
	        iOther.ExpandToInclude( OtherTo.x );
	        // This is an interval for the overlap between the 2
	        CInterval iOverlap = new CInterval();
	        // If there is an overlap...
	        if (iThis.Overlaps(iOther, iOverlap))
	        {
		        double dThisYMin;
		        double dThisYMax;

		        double dOtherYMin;
		        double dOtherYMax;
		        // If the line is vertical then y at the x min / max can be set to the ends of the line.
		        if (vector.i == 0)
		        {
			        dThisYMin = point.y;
			        dThisYMax = ThisTo.y;
		        }
		        else	// otherwise, caluclate the y values at the interval ends
		        {
			        dThisYMin = GetY(iOverlap.dMin);
			        dThisYMax = GetY(iOverlap.dMax);
		        }
		        // Now do the same for the other line
		        if (Other.vector.i == 0)
		        {
			        dOtherYMin = Other.point.y;
			        dOtherYMax = OtherTo.y;
		        }
		        else
		        {
			        dOtherYMin = Other.GetY(iOverlap.dMin);
			        dOtherYMax = Other.GetY(iOverlap.dMax);
		        }
        		
		        // Now find the distance between the 2 at the ends
		        double dDistMin = dThisYMin - dOtherYMin;
		        double dDistMax = dThisYMax - dOtherYMax;
		        // If they are both > 0 then no intersection
		        if ( (dDistMin > 0) && (dDistMax > 0))
		        {
			        dDistMin = Math.Abs( dDistMin);
                    dDistMax = Math.Abs(dDistMax);
			        // find which one is smallest
			        if ( dDistMin > dDistMax)
			        {	
				        dVerticalDistance = dDistMax;	// distance at the max is smallest
				        ptOnThis.x = iOverlap.dMax;
				        ptOnThis.y = dThisYMax;
				        ptOnOther.x = iOverlap.dMax;
				        ptOnOther.y = dOtherYMax;
			        }
			        else
			        {
				        dVerticalDistance = dDistMin;  // distance at the min is smallest
				        ptOnThis.x = iOverlap.dMin;
				        ptOnThis.y = dThisYMin;
				        ptOnOther.x = iOverlap.dMin;
				        ptOnOther.y = dOtherYMin;
			        }

			        return true;
		        }	
		        else if ( (dDistMin < 0) && (dDistMax < 0)) // This is below.
		        {
			        return false;
		        }
		        else
		        {
			        // find the intersection.
			        dVerticalDistance = 0;
			        C2DPointSet pts = new C2DPointSet();
			        if(this.Crosses(Other, pts))
			        {
				        ptOnThis = pts[0];
				        ptOnOther = ptOnThis;
			        }
			        else
			        {
				        Debug.Assert(false);
			        }
		        }
        	
		        return true;
	        }
	        else
	        {
		        return false;
	        }

        }
Beispiel #45
0
 /// <summary>
 /// Reflects the in the line given.
 /// </summary>
 /// <param name="Line">The line to reflect through.</param>
 public override void Reflect(C2DLine Line)
 {
     Arc.Reflect(Line);
 }