Пример #1
0
        /// <summary>
        /// True if this crosses the straight line.
        /// </summary>
        /// <param name="TestLine">The other line.</param>
        /// <param name="IntersectionPts">The interection point list to recieve the result.</param>
        public bool Crosses(C2DLine TestLine, List <C2DPoint> IntersectionPts)
        {
            List <C2DPoint> IntPtsTemp = new List <C2DPoint>();
            C2DCircle       TestCircle = new C2DCircle(GetCircleCentre(), Radius);

            if (TestCircle.Crosses(TestLine, IntPtsTemp))
            {
                for (int i = IntPtsTemp.Count - 1; i >= 0; i--)
                {
                    if (Line.IsOnRight(IntPtsTemp[i]) ^ ArcOnRight ||
                        IntPtsTemp[i].PointEqualTo(Line.point) ||
                        IntPtsTemp[i].PointEqualTo(Line.GetPointTo()))
                    {
                        IntPtsTemp.RemoveAt(i);
                    }
                }

                if (IntPtsTemp.Count == 0)
                {
                    return(false);
                }
                else
                {
                    IntersectionPts.InsertRange(0, IntPtsTemp);
                    //    .( IntersectionPts );
                    //      IntersectionPts << IntPtsTemp;
                    return(true);
                }
            }
            else
            {
                return(false);
            }
        }
Пример #2
0
        /// <summary>
        /// Gets the points that are furthest apart.
        /// </summary>
        /// <param name="nIndx1">Ouput. The first index.</param>
        /// <param name="nIndx2">Ouput. The second index.</param>
        /// <param name="dDist">Ouput. The distance.</param>
        public void GetExtremePoints(ref int nIndx1, ref int nIndx2,
                                     ref double dDist)
        {
            // First take a guess at them.
            GetExtremePointsEst(ref nIndx1, ref nIndx2, ref dDist, 0);

            // Set up a circle to bound the 2 guesses.
            C2DVector Vec = new C2DVector(this[nIndx1], this[nIndx2]);

            Vec.Multiply(0.5);
            C2DCircle Circle = new C2DCircle(this[nIndx1] + new C2DPoint(Vec), dDist / 2);

            // Now, if the guess was wrong, there must be a point outside the circle which is part of
            // the right solution. Go through all these, check and reset the result each time.
            for (int i = 0; i < Count; i++)
            {
                if (i != nIndx1 && i != nIndx2)
                {
                    if (!Circle.Contains(this[i]))
                    {
                        double dDistCheck = 0;
                        int    nCheck1    = GetFurthestPoint(i, ref dDistCheck);
                        if (dDistCheck > dDist)
                        {
                            nIndx1 = i;
                            nIndx2 = nCheck1;
                            dDist  = dDistCheck;
                        }
                    }
                }
            }
        }
Пример #3
0
        /// <summary>
        /// Distance between this and the test point.
        /// </summary>
        /// <param name="TestPoint">The test point.</param>
        /// <param name="ptOnThis">The closest point on this to the given point as a returned value.</param>
        public override double Distance(C2DPoint TestPoint, C2DPoint ptOnThis)
        {
            C2DPoint  ptCen       = new C2DPoint(GetCircleCentre());
            C2DCircle Circle      = new C2DCircle(ptCen, Radius);
            C2DPoint  ptOnCircle  = new C2DPoint();
            double    dCircleDist = Circle.Distance(TestPoint, ptOnCircle);

            if (ArcOnRight ^ Line.IsOnRight(ptOnCircle))
            {
                // The closest point on the circle isn't on the curve
                double d1 = TestPoint.Distance(Line.point);
                double d2 = TestPoint.Distance(Line.GetPointTo());

                if (d1 < d2)
                {
                    ptOnThis.Set(Line.point);
                    return(d1);
                }
                else
                {
                    ptOnThis.Set(Line.GetPointTo());
                    return(d2);
                }
            }
            else
            {
                // The closest point on the circle IS on the curve
                ptOnThis.Set(ptOnCircle);
                return(Math.Abs(dCircleDist));
            }
        }
Пример #4
0
        /// <summary>
        /// Draws a circle filled.
        /// </summary>
        public void DrawFilled(C2DCircle Circle, Graphics graphics, Brush brush)
        {
            C2DRect Rect = new C2DRect();

            Circle.GetBoundingRect(Rect);
            this.ScaleAndOffSet(Rect.BottomRight);
            this.ScaleAndOffSet(Rect.TopLeft);

            graphics.FillEllipse(brush, (int)Rect.TopLeft.x, (int)Rect.BottomRight.y, (int)Rect.Width(), (int)Rect.Height());
        }
Пример #5
0
        /// <summary>
        /// Draws a circle
        /// </summary>
        public void Draw(C2DCircle Circle, Graphics graphics, Pen pen)
        {
            C2DRect Rect = new  C2DRect();

            Circle.GetBoundingRect(Rect);
            this.ScaleAndOffSet(Rect.BottomRight);
            this.ScaleAndOffSet(Rect.TopLeft);

            graphics.DrawEllipse(pen, (int)Rect.TopLeft.x, (int)Rect.BottomRight.y, (int)Rect.Width(), (int)Rect.Height());
        }
Пример #6
0
        /// <summary>
        /// Distance between this and another straight line.
        /// </summary>
        /// <param name="TestLine">The test line.</param>
        /// <param name="ptOnThis">The closest point on this to the other as a returned value.</param>
        /// <param name="ptOnOther">The closest point on the other to this as a returned value.</param>
        public double Distance(C2DLine TestLine, C2DPoint ptOnThis, C2DPoint ptOnOther)
        {
            C2DCircle Circle = new C2DCircle(GetCircleCentre(), Radius);

            double dCircDist = Circle.Distance(TestLine, ptOnThis, ptOnOther);
            double dDist     = 0;

            if (TestLine.IsOnRight(ptOnThis) ^ ArcOnRight)
            {
                // The point found isn't on this.
                // This means the 2 closest points cannot be ON both lines, we must have a end point as one.

                ptOnThis.Set(Line.point);
                dDist = TestLine.Distance(ptOnThis, ptOnOther);

                C2DPoint ptThisTemp  = new C2DPoint(Line.GetPointTo());
                C2DPoint ptOtherTemp = new C2DPoint();
                double   d2          = TestLine.Distance(ptThisTemp, ptOtherTemp);
                if (d2 < dDist)
                {
                    dDist = d2;
                    ptOnThis.Set(ptThisTemp);
                    ptOnOther.Set(ptOtherTemp);
                }
                // If the line was outside the circle then stop here as no need to go any further.
                // This is because the closest point on this must be one of the end points.
                if (dCircDist < 0)
                {
                    double d3 = Distance(TestLine.point, ptThisTemp);
                    if (d3 < dDist)
                    {
                        dDist = d3;
                        ptOnThis.Set(ptThisTemp);
                        ptOnOther.Set(Line.point);
                    }
                    double d4 = Distance(TestLine.GetPointTo(), ptThisTemp);
                    if (d4 < dDist)
                    {
                        dDist = d4;
                        ptOnThis.Set(ptThisTemp);
                        ptOnOther.Set(Line.GetPointTo());
                    }
                }
            }
            else
            {
                dDist = Math.Abs(dCircDist);
            }

            //    ptOnThis.Set(ptThis);
            //    ptOnOther.Set(ptOther);

            return(dDist);
        }
Пример #7
0
        /// <summary>
        /// Assignment given a straight line defining the end points and a point on the arc.
        /// </summary>
        /// <param name="ArcLine">The line defining the start and end point of the arc.</param>
        /// <param name="ptOnArc">A point on the arc.</param>
        public void Set(C2DLine ArcLine, C2DPoint ptOnArc)
        {
            Line.Set(ArcLine);
            C2DPoint ptTo = new C2DPoint(Line.GetPointTo());

            C2DCircle Circle = new C2DCircle();

            Circle.SetCircumscribed(Line.point, ptTo, ptOnArc);
            Radius        = Line.point.Distance(Circle.Centre);
            ArcOnRight    = Line.IsOnRight(ptOnArc);
            CentreOnRight = Line.IsOnRight(Circle.Centre);
        }
Пример #8
0
        /// <summary>
        /// True if this crosses the other and returns the intersectin points.
        /// </summary>
        /// <param name="Other">The other circle.</param>
        /// <param name="IntersectionPts">The point set to recieve the result.</param>
        public bool Crosses(C2DCircle Other, List <C2DPoint> IntersectionPts)
        {
            double x1 = _Centre.x;
            double y1 = _Centre.y;
            double R1 = Radius;

            double x2 = Other.Centre.x;
            double y2 = Other.Centre.y;
            double R2 = Other.Radius;

            double D = Other.Centre.Distance(_Centre);

            if (D == 0)
            {
                return(false);
            }

            if (D == (R1 + R2))
            {
                C2DVector V = new C2DVector(_Centre, Other.Centre);
                V.SetLength(R1);
                C2DPoint P = new C2DPoint(_Centre.GetPointTo(V));
                IntersectionPts.Add(P);

                return(true);
            }

            if (D > (R1 + R2) || D < Math.Abs(R1 - R2))
            {
                return(false);
            }

            double A = (D + R1 + R2) * (D + R1 - R2) * (D - R1 + R2) * (-D + R1 + R2);

            A = Math.Sqrt(A) / 4;

            double XE1 = (x1 + x2) / 2 - (x1 - x2) * (R1 * R1 - R2 * R2) / (2 * D * D);
            double XE2 = 2 * (y1 - y2) * A / (D * D);

            double YE1 = (y1 + y2) / 2 - (y1 - y2) * (R1 * R1 - R2 * R2) / (2 * D * D);
            double YE2 = 2 * (x1 - x2) * A / (D * D);

            C2DPoint pt1 = new C2DPoint(XE1 + XE2, YE1 - YE2);
            C2DPoint pt2 = new C2DPoint(XE1 - XE2, YE1 + YE2);

            IntersectionPts.Add(pt1);
            IntersectionPts.Add(pt2);


            return(true);
        }
Пример #9
0
        /// <summary>
        /// True if this crosses a curved line.
        /// </summary>
        /// <param name="Other">The other arc.</param>
        /// <param name="IntersectionPts">The interection point list to recieve the result.</param>
        public bool Crosses(C2DArc Other, List <C2DPoint> IntersectionPts)
        {
            C2DCircle TestCircleThis  = new C2DCircle(GetCircleCentre(), Radius);
            C2DCircle TestCircleOther = new C2DCircle(Other.GetCircleCentre(), Other.Radius);

            List <C2DPoint> IntPtsTemp = new List <C2DPoint>();

            if (TestCircleThis.Crosses(TestCircleOther, IntPtsTemp))
            {
                for (int i = IntPtsTemp.Count - 1; i >= 0; i--)
                {
                    if ((Line.IsOnRight(IntPtsTemp[i]) ^ ArcOnRight) ||
                        Other.Line.IsOnRight(IntPtsTemp[i]) ^ Other.ArcOnRight ||
                        IntPtsTemp[i].PointEqualTo(Line.point) ||
                        IntPtsTemp[i].PointEqualTo(Line.GetPointTo()) ||
                        IntPtsTemp[i].PointEqualTo(Other.GetPointFrom()) ||
                        IntPtsTemp[i].PointEqualTo(Other.GetPointTo()))
                    {
                        IntPtsTemp.RemoveAt(i);
                    }
                }

                if (IntPtsTemp.Count == 0)
                {
                    return(false);
                }
                else
                {
                    IntersectionPts.InsertRange(0, IntPtsTemp);
                    //    IntPtsTemp.CopyTo( IntersectionPts );

                    //        (*IntersectionPts) << IntPtsTemp;
                    return(true);
                }
            }
            else
            {
                return(false);
            }
        }
Пример #10
0
        /// <summary>
        /// Gets the minimum bounding circle.
        /// </summary>
        /// <param name="Circle">Ouput. The Circle.</param>
        public void GetBoundingCircle(C2DCircle Circle)
        {
            if (this.Count < 3)
            {
                if (this.Count == 2)
                {
                    Circle.SetMinimum(this[0], this[1]);
                }
                else if (this.Count == 1)
                {
                    Circle.Set(this[0], 0);
                }
                else
                {
                    Debug.Assert(false, "Point set with no points. Cannot calculate bounding circle.");
                }
                return;
            }

            int    nIndx1 = 0;
            int    nIndx2 = 0;;
            int    nIndx3 = 0;;
            double dDist  = 0;;

            // First get the points that are furthest away from each other.
            GetExtremePoints(ref nIndx1, ref nIndx2, ref dDist);
            // Set the circle to bound these.
            Circle.SetMinimum(this[nIndx1], this[nIndx2]);
            // Set up a flag to show if we are circumscibed. (Once we are, we always will be).
            bool bCircum = false;

            // Cycle through and if any points aren't in the circle, then set the circle to be circumscribed.
            for (int i = 0; i < Count; i++)
            {
                if (i != nIndx1 && i != nIndx2)
                {
                    if (!Circle.Contains(this[i]))
                    {
                        nIndx3 = i;
                        Circle.SetCircumscribed(this[nIndx1], this[nIndx2], this[nIndx3]);
                        bCircum = true;
                        // Break out and try again.
                        break;
                    }
                }
            }

            // If we didn't succeed first time then go through again setting it to be circumscribed every time.
            if (bCircum)
            {
                for (int i = 0; i < Count; i++)
                {
                    if (i != nIndx1 && i != nIndx2 && i != nIndx3)
                    {
                        if (!Circle.Contains(this[i]))
                        {
                            double Dist1 = this[i].Distance(this[nIndx1]);
                            double Dist2 = this[i].Distance(this[nIndx2]);
                            double Dist3 = this[i].Distance(this[nIndx3]);
                            if (Dist1 < Dist2 && Dist1 < Dist3)
                            {
                                // Closest to point 1 so elimitate this
                                nIndx1 = i;
                            }
                            else if (Dist2 < Dist3)
                            {
                                // Closest to point 2 so elimitate this
                                nIndx2 = i;
                            }
                            else
                            {
                                // Closest to point 3 so elimitate this
                                nIndx3 = i;
                            }
                            Circle.SetCircumscribed(this[nIndx1], this[nIndx2], this[nIndx3]);
                        }
                    }
                }
            }
        }
Пример #11
0
        /// <summary>
        /// Assignment given a straight line defining the end points and a point on the arc.
        /// </summary>
        /// <param name="ArcLine">The line defining the start and end point of the arc.</param>
        /// <param name="ptOnArc">A point on the arc.</param>
        public void Set(C2DLine ArcLine, C2DPoint ptOnArc)
        {
            Line.Set(ArcLine);
	        C2DPoint ptTo = new C2DPoint(Line.GetPointTo());

	        C2DCircle Circle = new C2DCircle();
	        Circle.SetCircumscribed( Line.point , ptTo,  ptOnArc) ;
	        Radius = Line.point.Distance( Circle.Centre );
	        ArcOnRight = Line.IsOnRight(ptOnArc);
	        CentreOnRight = Line.IsOnRight(Circle.Centre);
        }
Пример #12
0
        /// <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)
        {
            double dCenCenDist  = _Centre.Distance(Other.Centre);
            double dOtherRadius = Other.Radius;

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

            if (dDist > 0)
            {
                // they do not interect and they are outside each other.
                C2DLine 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
                    C2DVector 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
                    C2DVector 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;
                    List <C2DPoint> 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);
        }
Пример #13
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="Other">The circle to assign this to.</param>
 public C2DCircle(C2DCircle Other)
 {
     _Centre.Set(Other.Centre);
     Radius = Other.Radius;
 }
Пример #14
0
        /// <summary>
        /// Distance between this and the test point.
        /// </summary>
        /// <param name="TestPoint">The test point.</param>
        /// <param name="ptOnThis">The closest point on this to the given point as a returned value.</param>
        public override double Distance(C2DPoint TestPoint,  C2DPoint ptOnThis) 
        {
	        C2DPoint ptCen = new C2DPoint( GetCircleCentre());
	        C2DCircle Circle = new C2DCircle(ptCen, Radius);
	        C2DPoint ptOnCircle = new C2DPoint();
	        double dCircleDist = Circle.Distance(TestPoint,  ptOnCircle);

	        if (ArcOnRight ^ Line.IsOnRight(ptOnCircle))
	        {
		        // The closest point on the circle isn't on the curve
		        double d1 = TestPoint.Distance(Line.point);
		        double d2 = TestPoint.Distance(Line.GetPointTo());
        		
		        if (d1 < d2)
		        {
				    ptOnThis.Set(Line.point);
			        return d1;
		        }
		        else
		        {
			        ptOnThis.Set(Line.GetPointTo());
			        return d2;
		        }
	        }
	        else
	        {
		        // The closest point on the circle IS on the curve
		        ptOnThis.Set(ptOnCircle);
		        return Math.Abs(dCircleDist);
	        }


        }
Пример #15
0
        /// <summary>
        /// True if this crosses the other and returns the intersectin points.
        /// </summary>
        /// <param name="Other">The other circle.</param> 
        /// <param name="IntersectionPts">The point set to recieve the result.</param> 
        public bool Crosses(C2DCircle Other,  List<C2DPoint> IntersectionPts)
        {
            double x1 = _Centre.x;
            double y1 = _Centre.y;
            double R1 = Radius;

            double x2 = Other.Centre.x;
            double y2 = Other.Centre.y;
            double R2 = Other.Radius;

            double D = Other.Centre.Distance(_Centre);

            if (D == 0)
                return false;

            if (D == (R1 + R2) )
            {
                C2DVector V = new C2DVector(_Centre, Other.Centre);
                V.SetLength(R1);
                C2DPoint P = new C2DPoint(_Centre.GetPointTo( V ));
                IntersectionPts.Add(P);

                return true;
            }

            if ( D > (R1 + R2) || D < Math.Abs(R1 - R2))
                return false;

            double A = (D + R1 + R2) * (D + R1 - R2) * (D - R1 + R2) * (-D + R1 + R2);
            A = Math.Sqrt(A) / 4;

            double XE1 = (x1 + x2) / 2 - (x1 - x2) * (R1 * R1 - R2 * R2) / (2 * D * D);
            double XE2 = 2 * (y1 - y2) * A / (D * D);

            double YE1 = (y1 + y2) / 2 - (y1 - y2) * (R1 * R1 - R2 * R2) / (2 * D * D);
            double YE2 = 2 * (x1 - x2) * A / (D * D);

            C2DPoint pt1 = new C2DPoint( XE1 + XE2, YE1 - YE2);
            C2DPoint pt2 = new C2DPoint( XE1 - XE2, YE1 + YE2);

            IntersectionPts.Add(pt1);
            IntersectionPts.Add(pt2);

            return true;
        }
Пример #16
0
 /// <summary>
 /// Sets this to another.
 /// </summary>
 /// <param name="Other">The other circle.</param> 
 public void Set(C2DCircle Other)
 {
     _Centre.Set(Other.Centre);
     Radius = Other.Radius;
 }
Пример #17
0
        /// <summary>
        /// True if this crosses the straight line.
        /// </summary>
        /// <param name="TestLine">The other line.</param>
        /// <param name="IntersectionPts">The interection point list to recieve the result.</param>
        public bool Crosses(C2DLine TestLine,  List<C2DPoint> IntersectionPts)
        {
	        List<C2DPoint> IntPtsTemp = new List<C2DPoint>();
	        C2DCircle TestCircle = new C2DCircle(GetCircleCentre(), Radius);
            if (TestCircle.Crosses(TestLine,  IntPtsTemp))
	        {
		        for (int i = IntPtsTemp.Count - 1 ; i >= 0  ; i--)
		        {
                    if (Line.IsOnRight(IntPtsTemp[i]) ^ ArcOnRight ||
                        IntPtsTemp[i].PointEqualTo( Line.point) ||
                        IntPtsTemp[i].PointEqualTo( Line.GetPointTo()))
			        {
				        IntPtsTemp.RemoveAt(i);
			        }

		        }

		        if (IntPtsTemp.Count == 0)
			        return false;
		        else
		        {
                    IntersectionPts.InsertRange(0,  IntPtsTemp);
                //    .( IntersectionPts );
			  //      IntersectionPts << IntPtsTemp;
			        return true;
		        }
	        }
	        else
	        {
		        return false;
	        }

        }
Пример #18
0
        /// <summary>
        /// Draws a circle filled.
        /// </summary>
        public void DrawFilled(C2DCircle Circle, Graphics graphics, Brush brush)
        {
            C2DRect Rect = new C2DRect();
            Circle.GetBoundingRect(Rect);
            this.ScaleAndOffSet(Rect.BottomRight);
            this.ScaleAndOffSet(Rect.TopLeft);

            graphics.FillEllipse(brush, (int)Rect.TopLeft.x, (int)Rect.BottomRight.y, (int)Rect.Width(), (int)Rect.Height());
        }
Пример #19
0
        /// <summary>
        /// Draws a circle
        /// </summary>
        public void Draw(C2DCircle Circle, Graphics graphics, Pen pen)
        {
            C2DRect Rect = new  C2DRect();
            Circle.GetBoundingRect(Rect);
            this.ScaleAndOffSet(Rect.BottomRight);
            this.ScaleAndOffSet(Rect.TopLeft);

            graphics.DrawEllipse(pen, (int)Rect.TopLeft.x, (int)Rect.BottomRight.y, (int)Rect.Width(), (int)Rect.Height());
        }
Пример #20
0
        /// <summary>
        /// Distance between this and another straight line.
        /// </summary>
        /// <param name="TestLine">The test line.</param>
        /// <param name="ptOnThis">The closest point on this to the other as a returned value.</param>
        /// <param name="ptOnOther">The closest point on the other to this as a returned value.</param>   
        public double Distance(C2DLine TestLine,  C2DPoint ptOnThis,  C2DPoint ptOnOther) 
        {
	        C2DCircle Circle = new C2DCircle( GetCircleCentre(), Radius);

            double dCircDist = Circle.Distance(TestLine,  ptOnThis,  ptOnOther);
	        double dDist = 0;

            if (TestLine.IsOnRight(ptOnThis) ^ ArcOnRight)
	        {
		        // The point found isn't on this. 
		        // This means the 2 closest points cannot be ON both lines, we must have a end point as one.

                ptOnThis.Set(Line.point);
                dDist = TestLine.Distance(ptOnThis,  ptOnOther);

                C2DPoint ptThisTemp = new C2DPoint(Line.GetPointTo());
		        C2DPoint ptOtherTemp = new C2DPoint();
                double d2 = TestLine.Distance(ptThisTemp,  ptOtherTemp);
		        if (d2 < dDist)
		        {
			        dDist = d2;
                    ptOnThis.Set(ptThisTemp);
                    ptOnOther.Set(ptOtherTemp);
		        }
		        // If the line was outside the circle then stop here as no need to go any further.
		        // This is because the closest point on this must be one of the end points.
		        if (dCircDist < 0)
		        {
                    double d3 = Distance(TestLine.point,  ptThisTemp);
			        if (d3 < dDist)
			        {
				        dDist = d3;
                        ptOnThis.Set(ptThisTemp);
                        ptOnOther.Set(Line.point);
			        }
                    double d4 = Distance(TestLine.GetPointTo(),  ptThisTemp);
			        if (d4 < dDist)
			        {
				        dDist = d4;
                        ptOnThis.Set(ptThisTemp);
                        ptOnOther.Set(Line.GetPointTo());
			        }	
		        }
	        }
	        else
	        {
		        dDist = Math.Abs(dCircDist);
	        }

		//    ptOnThis.Set(ptThis);
		//    ptOnOther.Set(ptOther);

	        return dDist;


        }
Пример #21
0
        /// <summary>
        /// The distance between this and another arc.
        /// </summary>
        /// <param name="Other">The test point.</param>
        /// <param name="ptOnThis">The closest point on this to the other as a returned value.</param>
        /// <param name="ptOnOther">The closest point on the other to this as a returned value.</param>     
        public double Distance(C2DArc Other,  C2DPoint ptOnThis,  C2DPoint ptOnOther)
        {
	        List<C2DPoint> IntPts1 = new List<C2DPoint>();
	        List<C2DPoint> IntPts2 = new List<C2DPoint>();

	        C2DPoint ptThisCen = new C2DPoint( GetCircleCentre() );
	        C2DPoint ptOtherCen = new C2DPoint(Other.GetCircleCentre());

	        C2DCircle CircleThis = new C2DCircle( ptThisCen, Radius);
	        C2DCircle CircleOther = new C2DCircle( ptOtherCen, Other.Radius );

	        if (CircleThis.Crosses(  CircleOther ,  IntPts1 ) )
	        {
		        for (int i = 0; i < IntPts1.Count; i++)
		        {
			        if (  (Line.IsOnRight( IntPts1[i] ) == ArcOnRight ) &&
				          (Other.Line.IsOnRight( IntPts1[i] ) == Other.ArcOnRight )     )
			        {
					    ptOnThis.Set(IntPts1[i]);
					    ptOnOther.Set(IntPts1[i]);
				        return 0;
			        }
		        }

		        IntPts1.Clear();
	        }


	        C2DLine LineCenToOther = new C2DLine();
	        LineCenToOther.point = new C2DPoint(ptThisCen);
	        LineCenToOther.vector = new C2DVector(ptThisCen, ptOtherCen);
	        LineCenToOther.GrowFromCentre( Math.Max(Radius, Other.Radius) * 10);

	        double dMinDist = 1.7E308;
	        double dDist = 0;

	        if ( Crosses(LineCenToOther,  IntPts1) && Other.Crosses(LineCenToOther,  IntPts2))
	        {
		        for (int i = 0 ; i < IntPts1.Count; i++)
		        {
			        for (int j = 0 ; j < IntPts2.Count; j++)
			        {
				        dDist = IntPts1[i].Distance(IntPts2[j]);
				        if (dDist < dMinDist)
				        {
						    ptOnThis.Set( IntPts1[i]);
						    ptOnOther.Set( IntPts2[j]);

					        dMinDist = dDist;
				        }
			        }
		        }
	        }

	        C2DPoint ptOnThisTemp = new C2DPoint();
	        dDist = Distance(Other.GetPointFrom(),  ptOnThisTemp);
	        if (dDist < dMinDist)
	        {
			    ptOnThis.Set(ptOnThisTemp);
			    ptOnOther.Set(Other.GetPointFrom());

		        dMinDist = dDist;
	        }

	        dDist = Distance(Other.GetPointTo(),  ptOnThisTemp);
	        if (dDist < dMinDist)
	        {
			    ptOnThis.Set(ptOnThisTemp);
			    ptOnOther.Set(Other.GetPointTo());

		        dMinDist = dDist;
	        }

	        C2DPoint ptOnOtherTemp = new C2DPoint();
	        dDist = Other.Distance(GetPointFrom(),  ptOnOtherTemp);
	        if (dDist < dMinDist)
	        {
			    ptOnThis.Set( GetPointFrom());
			    ptOnOther.Set( ptOnOtherTemp);
		        dMinDist = dDist;
	        }

	        dDist = Other.Distance(GetPointTo(),  ptOnOtherTemp);
	        if (dDist < dMinDist)
	        {
			    ptOnThis.Set( GetPointTo());
			    ptOnOther.Set( ptOnOtherTemp);
		        dMinDist = dDist;
	        }

	        return dMinDist;

        }
Пример #22
0
        /// <summary>
        /// The distance between this and another arc.
        /// </summary>
        /// <param name="Other">The test point.</param>
        /// <param name="ptOnThis">The closest point on this to the other as a returned value.</param>
        /// <param name="ptOnOther">The closest point on the other to this as a returned value.</param>
        public double Distance(C2DArc Other, C2DPoint ptOnThis, C2DPoint ptOnOther)
        {
            List <C2DPoint> IntPts1 = new List <C2DPoint>();
            List <C2DPoint> IntPts2 = new List <C2DPoint>();

            C2DPoint ptThisCen  = new C2DPoint(GetCircleCentre());
            C2DPoint ptOtherCen = new C2DPoint(Other.GetCircleCentre());

            C2DCircle CircleThis  = new C2DCircle(ptThisCen, Radius);
            C2DCircle CircleOther = new C2DCircle(ptOtherCen, Other.Radius);

            if (CircleThis.Crosses(CircleOther, IntPts1))
            {
                for (int i = 0; i < IntPts1.Count; i++)
                {
                    if ((Line.IsOnRight(IntPts1[i]) == ArcOnRight) &&
                        (Other.Line.IsOnRight(IntPts1[i]) == Other.ArcOnRight))
                    {
                        ptOnThis.Set(IntPts1[i]);
                        ptOnOther.Set(IntPts1[i]);
                        return(0);
                    }
                }

                IntPts1.Clear();
            }


            C2DLine LineCenToOther = new C2DLine();

            LineCenToOther.point  = new C2DPoint(ptThisCen);
            LineCenToOther.vector = new C2DVector(ptThisCen, ptOtherCen);
            LineCenToOther.GrowFromCentre(Math.Max(Radius, Other.Radius) * 10);

            double dMinDist = 1.7E308;
            double dDist    = 0;

            if (Crosses(LineCenToOther, IntPts1) && Other.Crosses(LineCenToOther, IntPts2))
            {
                for (int i = 0; i < IntPts1.Count; i++)
                {
                    for (int j = 0; j < IntPts2.Count; j++)
                    {
                        dDist = IntPts1[i].Distance(IntPts2[j]);
                        if (dDist < dMinDist)
                        {
                            ptOnThis.Set(IntPts1[i]);
                            ptOnOther.Set(IntPts2[j]);

                            dMinDist = dDist;
                        }
                    }
                }
            }

            C2DPoint ptOnThisTemp = new C2DPoint();

            dDist = Distance(Other.GetPointFrom(), ptOnThisTemp);
            if (dDist < dMinDist)
            {
                ptOnThis.Set(ptOnThisTemp);
                ptOnOther.Set(Other.GetPointFrom());

                dMinDist = dDist;
            }

            dDist = Distance(Other.GetPointTo(), ptOnThisTemp);
            if (dDist < dMinDist)
            {
                ptOnThis.Set(ptOnThisTemp);
                ptOnOther.Set(Other.GetPointTo());

                dMinDist = dDist;
            }

            C2DPoint ptOnOtherTemp = new C2DPoint();

            dDist = Other.Distance(GetPointFrom(), ptOnOtherTemp);
            if (dDist < dMinDist)
            {
                ptOnThis.Set(GetPointFrom());
                ptOnOther.Set(ptOnOtherTemp);
                dMinDist = dDist;
            }

            dDist = Other.Distance(GetPointTo(), ptOnOtherTemp);
            if (dDist < dMinDist)
            {
                ptOnThis.Set(GetPointTo());
                ptOnOther.Set(ptOnOtherTemp);
                dMinDist = dDist;
            }

            return(dMinDist);
        }
Пример #23
0
        /// <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)
        {
            double dCenCenDist = _Centre.Distance(Other.Centre);
            double dOtherRadius = Other.Radius;

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

            if (dDist > 0 )
            {
                // they do not interect and they are outside each other.
                    C2DLine 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
                        C2DVector 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
                        C2DVector 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;
                    List<C2DPoint> 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;
        }
Пример #24
0
        /// <summary>
        /// True if this crosses a curved line.
        /// </summary>
        /// <param name="Other">The other arc.</param>
        /// <param name="IntersectionPts">The interection point list to recieve the result.</param>
        public bool Crosses(C2DArc Other,   List<C2DPoint> IntersectionPts) 
        {
	        C2DCircle TestCircleThis = new C2DCircle (GetCircleCentre(), Radius);
	        C2DCircle TestCircleOther= new C2DCircle (Other.GetCircleCentre(), Other.Radius);

	        List<C2DPoint> IntPtsTemp = new List<C2DPoint>();

	        if (TestCircleThis.Crosses(TestCircleOther,  IntPtsTemp))
	        {

		        for (int i = IntPtsTemp.Count - 1; i >= 0 ; i--)
		        {
			        if ((Line.IsOnRight(IntPtsTemp[i]) ^ ArcOnRight) ||
				        Other.Line.IsOnRight(IntPtsTemp[i]) ^ Other.ArcOnRight ||
				        IntPtsTemp[i].PointEqualTo( Line.point) ||
				        IntPtsTemp[i].PointEqualTo( Line.GetPointTo()) ||
				        IntPtsTemp[i].PointEqualTo( Other.GetPointFrom()) ||
				        IntPtsTemp[i].PointEqualTo( Other.GetPointTo()))
			        {
				        IntPtsTemp.RemoveAt(i);
			        }
		        }

		        if (IntPtsTemp.Count == 0)
			        return false;
		        else
		        {

                    IntersectionPts.InsertRange(0, IntPtsTemp);
                //    IntPtsTemp.CopyTo( IntersectionPts );

				//        (*IntersectionPts) << IntPtsTemp;
			        return true;
		        }
	        }
	        else
	        {
		        return false;
	        }


        }