Exemple #1
0
        /// <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);
        }
Exemple #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;
                        }
                    }
                }
            }
        }
        /// <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)
        {
            var vecthis = new C2DVector(x - line.point.x, y - line.point.y);
            var dProj   = vecthis.Dot(line.vector);

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

            var dLength = line.vector.GetLength();

            dProj /= dLength;

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

            var dFactor = dProj / dLength;

            var vProj = new C2DVector(line.vector);

            vProj.Multiply(dFactor);
            ptOnLine.Set(line.point.x + vProj.i, line.point.y + vProj.j);
            return(true);
        }
        /// <summary>
        /// Set to be the minimum bounding circle for the 2 points.
        /// </summary>
        /// <param name="Point1">The first point to include.</param> 
        /// <param name="Point2">The second point to include.</param> 
	    public void SetMinimum(C2DPoint Point1, C2DPoint Point2)
        {
	        C2DVector Vec = new C2DVector(Point1, Point2);
	        Vec.Multiply( 0.5);
	        Radius = Vec.GetLength();
	        _Centre.Set(Point1.GetPointTo(Vec));
        }
Exemple #5
0
        /// <summary>
        /// Set to be the minimum bounding circle for the 2 points.
        /// </summary>
        /// <param name="Point1">The first point to include.</param>
        /// <param name="Point2">The second point to include.</param>
        public void SetMinimum(C2DPoint Point1, C2DPoint Point2)
        {
            C2DVector Vec = new C2DVector(Point1, Point2);

            Vec.Multiply(0.5);
            Radius = Vec.GetLength();
            _Centre.Set(Point1.GetPointTo(Vec));
        }
Exemple #6
0
        /// <summary>
        /// Grows this about the origin provided.
        /// In the case of a point this will just move it away (or closer)
        /// to the origin as there is no shape to grow.
        /// </summary>
        /// <param name="dFactor">The factor to grow this by.</param>
        /// <param name="Origin">The origin about which to rotate.</param>
        public override void Grow(double dFactor, C2DPoint Origin)
        {
            C2DVector vector = new C2DVector(Origin, this);

            vector.Multiply(dFactor);
            x = Origin.x + vector.i;
            y = Origin.y + vector.j;
        }
        /// <summary>
        /// Gets the point on the line given by the factor. e.g. 0.5 = mid point.
        /// </summary>
        /// <param name="dFactorFromStart">The factor from the start.</param>
        public C2DPoint GetPointOn(double dFactorFromStart)
        {
            var vNew = new C2DVector(vector);

            vNew.Multiply(dFactorFromStart);

            var Result = new C2DPoint(point.x + vNew.i, point.y + vNew.j);

            return(Result);
        }
Exemple #8
0
        /// <summary>
        /// Projection onto the vector as distance along the line from the start of the vector.
        /// Result is stored as an CInterval Min and Max,
        /// </summary>
        /// <param name="Vector">Vector to project this onto.</param>
        /// <param name="Interval">Interval to recieve the result.</param>
        public override void Project(C2DVector Vector, CInterval Interval)
        {
            // Create a line that goes through the circle from edge to edge and with the same vector.
            C2DLine Line = new C2DLine(_Centre, Vector);

            Line.vector.SetLength(Radius * 2);

            C2DVector V2 = new C2DVector(Vector);

            V2.Multiply(-0.5);
            Line.Move(V2);

            // Now just project the line onto the interval.
            Line.Project(Vector, Interval);
        }
        /// <summary>
        /// Projection onto the line as distance along the line from the start of the line.
        /// Result is stored as an CInterval Min and Max,
        /// </summary>
        /// <param name="Line">Line to project this onto.</param>
        /// <param name="Interval">Interval to recieve the result.</param>
        public override void Project(C2DLine Line, CInterval Interval)
        {
            // Create a line that goes through the circle from edge to edge and with the same vector as the
            // Line to project on.
            var LineCopy = new C2DLine(_Centre, Line.vector);

            LineCopy.vector.SetLength(Radius * 2);

            var V2 = new C2DVector(LineCopy.vector);

            V2.Multiply(-0.5);

            LineCopy.Move(V2);

            // Now just project the line onto the interval.
            LineCopy.Project(Line, Interval);
        }
Exemple #10
0
        /// <summary>
        /// Calculates the centroid of the polygon by moving it according to each holes
        /// weighted centroid.
        /// </summary>
        public C2DPoint GetCentroid()
        {
            var HoleCen = new C2DPoint(0, 0);

            if (_Holes.Count == 0)
            {
                return(Rim.GetCentroid());
            }


            var PolyCen = Rim.GetCentroid();

            var    dPolyArea = Rim.GetArea();
            double dHoleArea = 0;

            for (var i = 0; i < _Holes.Count; i++)
            {
                dHoleArea += GetHole(i).GetArea();
            }


            if (dHoleArea == 0 || dHoleArea == dPolyArea)
            {
                return(Rim.GetCentroid());
            }
            else
            {
                for (var i = 0; i < _Holes.Count; i++)
                {
                    var pt = GetHole(i).GetCentroid();
                    pt.Multiply(GetHole(i).GetArea() / dHoleArea);
                    HoleCen += pt;
                }
            }

            var Vec = new C2DVector(HoleCen, PolyCen);

            Vec.Multiply(dHoleArea / (dPolyArea - dHoleArea));

            PolyCen.Move(Vec);

            return(PolyCen);
        }
Exemple #11
0
        /// <summary>
        /// Sets the circle to be the maximum contained circle within the triangle.
        /// </summary>
        /// <param name="Triangle">The triangle to bound the circle.</param>
        public void SetInscribed(C2DTriangle Triangle)
        {
            C2DPoint InCen = Triangle.GetInCentre();

            C2DLine Line = new C2DLine(Triangle.P1, Triangle.P2);

            C2DVector vec     = new C2DVector(Line.point, InCen);
            double    dProj   = vec.Dot(Line.vector);
            double    dLength = Line.vector.GetLength();

            dProj /= dLength;

            double dFactor = dProj / dLength;

            C2DVector vProj = new C2DVector(Line.vector);

            vProj.Multiply(dFactor);
            C2DPoint ptOnLine = new C2DPoint(Line.point.x + vProj.i, Line.point.y + vProj.j);

            Set(InCen, InCen.Distance(ptOnLine));
        }
Exemple #12
0
        /// <summary>
        /// Gets the centroid.
        /// </summary>
        C2DPoint GetCentroid()
        {
            C2DPoint Centroid = Rim.GetCentroid();
            double   dArea    = Rim.GetArea();

            for (int i = 0; i < _Holes.Count; i++)
            {
                C2DVector vec = new C2DVector(Centroid, GetHole(i).GetCentroid());

                double dHoleArea = GetHole(i).GetArea();

                double dFactor = dHoleArea / (dHoleArea + dArea);

                vec.Multiply(dFactor);
                Centroid.x += vec.i;
                Centroid.y += vec.j;
                dArea      += dHoleArea;
            }


            return(Centroid);
        }
Exemple #13
0
        /// <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);
        }
Exemple #14
0
        /// <summary>
        /// Gets the point on the line given by the factor. e.g. 0.5 = mid point.
        /// </summary>
        /// <param name="dFactorFromStart">The factor from the start.</param>
	    public C2DPoint GetPointOn(double dFactorFromStart)
        {
	        C2DVector vNew = new C2DVector(vector);
            vNew.Multiply( dFactorFromStart);

	        C2DPoint Result = new C2DPoint(point.x + vNew.i, point.y + vNew.j );
	        return Result;
        }
        /// <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)
        {
            double x1 = Line.point.x;
            double x2 = Line.point.x + Line.vector.i;
            double x3 = _Centre.x;

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

            double r = Radius;

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

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

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

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

            C2DPoint ptClosestToCen = new C2DPoint();

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

            double dDist = ptClosestToCen.Distance(_Centre);

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

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

                    bool 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;
                }
            }
        }
        /// <summary>
        /// Calculates the centroid of the polygon by moving it according to each holes
        /// weighted centroid.
        /// </summary>
        public C2DPoint GetCentroid()
        {
            C2DPoint HoleCen = new C2DPoint(0, 0);

            if (_Holes.Count == 0)
                return Rim.GetCentroid();

            C2DPoint PolyCen = Rim.GetCentroid();

            double dPolyArea = Rim.GetArea();
            double dHoleArea = 0;

            for ( int i = 0 ; i < _Holes.Count; i++)
            {
                dHoleArea += GetHole(i).GetArea();
            }

            if (dHoleArea == 0 || dHoleArea == dPolyArea)
                return Rim.GetCentroid();
            else
            {
                for (int i = 0 ; i < _Holes.Count; i++)
                {
                    C2DPoint pt = GetHole(i).GetCentroid();
                    pt.Multiply(GetHole(i).GetArea() / dHoleArea);
                    HoleCen += pt;
                }
            }

            C2DVector Vec = new C2DVector(HoleCen, PolyCen);

            Vec.Multiply( dHoleArea / (dPolyArea - dHoleArea));

            PolyCen.Move(Vec);

            return PolyCen;
        }
        /// <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 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)
        {
            CInterval 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);
            }

            double 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.
                C2DPoint ptClosest = new C2DPoint(Line.GetPointTo());
                ptOnOther.Set( ptClosest );
                return Distance(ptClosest,  ptOnThis);
            }

            // Now find out if there's an intersection.
            List<C2DPoint> 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))
            {
                double d1 = Distance(Line.point,  ptOnThis);
                C2DPoint ptThisTemp = new C2DPoint();
                double 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.
            double dCenOnLine = (ProjInt.dMax + ProjInt.dMin) / 2.0;

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

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

                    ptOnOther.Set( ptOnLine );

                    return Distance(ptOnLine,  ptOnThis);
                }
                else
                {
                    // The centre is projected above the line.
                    C2DPoint 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);
            }
        }
Exemple #19
0
        /// <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)
        {
            CInterval 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));
            }

            double 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.
                C2DPoint ptClosest = new C2DPoint(Line.GetPointTo());
                ptOnOther.Set(ptClosest);
                return(Distance(ptClosest, ptOnThis));
            }

            // Now find out if there's an intersection.
            List <C2DPoint> 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))
            {
                double   d1         = Distance(Line.point, ptOnThis);
                C2DPoint ptThisTemp = new C2DPoint();
                double   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.
            double dCenOnLine = (ProjInt.dMax + ProjInt.dMin) / 2.0;

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

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

                    ptOnOther.Set(ptOnLine);

                    return(Distance(ptOnLine, ptOnThis));
                }
                else
                {
                    // The centre is projected above the line.
                    C2DPoint 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));
            }
        }
Exemple #20
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>
        /// Projection onto the vector as distance along the line from the start of the vector.
        /// Result is stored as an CInterval Min and Max,
        /// </summary>
        /// <param name="Vector">Vector to project this onto.</param> 
        /// <param name="Interval">Interval to recieve the result.</param> 
        public override void Project(C2DVector Vector,  CInterval Interval)
        {
            // Create a line that goes through the circle from edge to edge and with the same vector.
            C2DLine Line = new C2DLine (_Centre, Vector);

            Line.vector.SetLength( Radius * 2 );

            C2DVector V2 = new C2DVector(Vector);
            V2.Multiply(-0.5);
            Line.Move(V2);

            // Now just project the line onto the interval.
            Line.Project(Vector,  Interval);
        }
Exemple #22
0
        /// <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)
        {
            double x1 = Line.point.x;
            double x2 = Line.point.x + Line.vector.i;
            double x3 = _Centre.x;

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

            double r = Radius;

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

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

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

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

            C2DPoint ptClosestToCen = new C2DPoint();

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

            double dDist = ptClosestToCen.Distance(_Centre);

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

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

                    bool 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);
                }
            }
        }
 /// <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.
        /// 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;
        }
 /// <summary>
 /// Grows this about the origin provided. 
 /// In the case of a point this will just move it away (or closer) 
 /// to the origin as there is no shape to grow.
 /// </summary>
 /// <param name="dFactor">The factor to grow this by.</param>
 /// <param name="Origin">The origin about which to rotate.</param>
 public override void Grow(double dFactor, C2DPoint Origin)
 {
     C2DVector vector = new C2DVector(Origin, this);
     vector.Multiply(dFactor);
     x = Origin.x + vector.i;
     y = Origin.y + vector.j;
 }
        /// <summary>
        /// Sets the circle to be the maximum contained circle within the triangle.
        /// </summary>
        /// <param name="Triangle">The triangle to bound the circle.</param> 
        public void SetInscribed(C2DTriangle Triangle)
        {
            C2DPoint InCen = Triangle.GetInCentre();

            C2DLine Line = new C2DLine( Triangle.P1, Triangle.P2  );

            C2DVector vec = new C2DVector(Line.point, InCen );
            double dProj = vec.Dot(Line.vector);
            double dLength = Line.vector.GetLength();
            dProj /= dLength;

            double dFactor = dProj / dLength;

            C2DVector vProj = new C2DVector(Line.vector);
            vProj.Multiply(dFactor);
            C2DPoint ptOnLine = new C2DPoint(Line.point.x + vProj.i,Line.point.y + vProj.j) ;

            Set(InCen, InCen.Distance( ptOnLine));
        }
        /// <summary>
        /// Gets the centroid.
        /// </summary>
        C2DPoint GetCentroid()
        {
            C2DPoint Centroid = Rim.GetCentroid();
            double dArea = Rim.GetArea();

	        for (int i = 0; i < _Holes.Count; i++)
	        {
			        C2DVector vec = new C2DVector( Centroid, GetHole(i).GetCentroid());

			        double dHoleArea = GetHole(i).GetArea();

			        double dFactor =  dHoleArea / (dHoleArea + dArea);	

			        vec.Multiply( dFactor);
			        Centroid.x += vec.i;
                    Centroid.y += vec.j;
			        dArea += dHoleArea;
	        }


	        return Centroid;

        }