示例#1
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)
        {
            var p1 = point;
            var p2 = GetPointTo();

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

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

            var 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;

            var 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);
        }
示例#2
0
文件: C2DArc.cs 项目: kasznare/DIP1
        /// <summary>
        /// Gets the point half way along the curve as a new object.
        /// </summary>
        public C2DPoint GetMidPoint()
        {
            Debug.Assert(IsValid(), "Invalid arc defined, cannot calculate midpoint");
            // Make a line from the circle centre to the middle of the line
            C2DPoint ptCentre = new C2DPoint(GetCircleCentre());

            C2DPoint ptLineCentre = new C2DPoint(Line.GetMidPoint());

            C2DLine CenToMid = new C2DLine(ptCentre, ptLineCentre);

            if (CenToMid.vector.i == 0 && CenToMid.vector.j == 0)
            {
                // The centre of the line is the same as the centre of the circle
                // i.e. this arc is 180 degrees or half a circle.
                CenToMid.Set(Line);
                CenToMid.SetPointFrom(ptLineCentre);
                if (ArcOnRight)
                {
                    CenToMid.vector.TurnRight();
                }
                else
                {
                    CenToMid.vector.TurnLeft();
                }
            }
            else
            {
                // extend it to the edge of the arc
                CenToMid.SetLength(Radius);
                // if the arc on the opposite side to the centre then reverse the line.
                if (ArcOnRight == CentreOnRight)
                {
                    CenToMid.vector.Reverse();
                }
            }

            return(CenToMid.GetPointTo());
        }
示例#3
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;
        }
示例#4
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);
        }
示例#5
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);
        }
        /// <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;
        }
示例#7
0
        /// <summary>
        /// Gets the point half way along the curve as a new object.
        /// </summary>
        public C2DPoint GetMidPoint() 
        {
	        Debug.Assert(IsValid(), "Invalid arc defined, cannot calculate midpoint");
	        // Make a line from the circle centre to the middle of the line
	        C2DPoint ptCentre = new C2DPoint(GetCircleCentre());

	        C2DPoint ptLineCentre = new C2DPoint(Line.GetMidPoint());

	        C2DLine CenToMid = new C2DLine(ptCentre, ptLineCentre);

	        if ( CenToMid.vector.i == 0 && CenToMid.vector.j == 0)
	        {
		        // The centre of the line is the same as the centre of the circle
		        // i.e. this arc is 180 degrees or half a circle.
		        CenToMid.Set(Line);
		        CenToMid.SetPointFrom( ptLineCentre );
		        if ( ArcOnRight )
			        CenToMid.vector.TurnRight();
		        else
			        CenToMid.vector.TurnLeft();
	        }
	        else
	        {
		        // extend it to the edge of the arc
		        CenToMid.SetLength( Radius );
		        // if the arc on the opposite side to the centre then reverse the line.
		        if ( ArcOnRight == CentreOnRight)
		        {
			        CenToMid.vector.Reverse();
		        }
	        }

	        return CenToMid.GetPointTo();

        }