예제 #1
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));
        }
예제 #2
0
        /// <summary>
        /// Contructor.
        /// </summary>
        /// <param name="PtFrom">The point the arc is to go from.</param>
        /// <param name="Vector">The vector defining the end point.</param>
        /// <param name="dRadius">The corresponding circles radius.</param>
        /// <param name="bCentreOnRight">Whether the centre is on the right.</param>
        /// <param name="bArcOnRight">Whether the arc is to the right of the line.</param>
	    public C2DArc(C2DPoint PtFrom, C2DVector Vector, double dRadius, 
		    bool bCentreOnRight, bool bArcOnRight)
        {
            Line.Set(PtFrom, Vector);
            Radius = dRadius;
            CentreOnRight = bCentreOnRight;
            ArcOnRight = bArcOnRight;
        }
예제 #3
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)
        {
            var ProjInt = new CInterval();

            Project(Line, ProjInt);

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

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

            var dLength = Line.GetLength();

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

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

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

                return(0);
            }

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

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

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

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

                    ptOnOther.Set(ptOnLine);

                    return(Distance(ptOnLine, ptOnThis));
                }
                else
                {
                    // The centre is projected above the line.
                    var ptClosest = new C2DPoint(Line.GetPointTo());
                    ptOnOther.Set(ptClosest);
                    return(Distance(ptClosest, ptOnThis));
                }
            }
            else
            {
                // This means that the circle projects entirely "below" the line.
                ptOnOther.Set(Line.point);
                return(Distance(Line.point, ptOnThis));
            }
        }
예제 #4
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;
        }
예제 #5
0
        /// <summary>
        /// Returns the distance from this to the point with this as a ray.
        /// </summary>
        /// <param name="TestPoint"></param>
        /// <param name="ptOnThis"></param>
        /// <returns></returns>
        public double DistanceAsRay(C2DPoint TestPoint,  C2DPoint ptOnThis)
        {
	        C2DVector vP1ToPoint = new C2DVector(point, TestPoint);

	        // The projection is on the line
	        double dFactorOnLine = vP1ToPoint.Dot(vector) / (vector.i * vector.i + vector.j * vector.j);

            ptOnThis.Set(point.x + vector.i * dFactorOnLine,
                              point.y + vector.j * dFactorOnLine);
            return TestPoint.Distance(ptOnThis);
        }
예제 #6
0
        /// <summary>
        /// Equality test.
        /// </summary>
        public bool VectorEqualTo(  C2DVector Other)
        {
            bool biClose;
            bool bjClose;

            if (i == 0)
                biClose = Other.i == 0;
            else
                biClose = Math.Abs((Other.i - i) / i) < Constants.conEqualityTolerance;
            if (j == 0)
                bjClose = Other.j == 0;
            else
                bjClose = Math.Abs((Other.j - j) / j) < Constants.conEqualityTolerance;

            return (biClose && bjClose);
        }
예제 #7
0
        /// <summary>
        /// Returns the angle to the right to another vector.
        /// </summary>
        public double AngleToRight(C2DVector Other)
        {
            double Result = Other.AngleFromNorth() - AngleFromNorth();
            if (Result < 0) Result += Constants.conTWOPI;

            return Result;
        }
예제 #8
0
        /// <summary>
        /// Moves this point by the vector given.
        /// </summary>
        /// <param name="Vector">The vector.</param>
	    public override void Move(C2DVector Vector)
        {
            P1.Move(Vector);
            P2.Move(Vector);
            P3.Move(Vector);
        }
예제 #9
0
 /// <summary>
 /// Reflects this through the point given.
 /// </summary>
 /// <param name="Other">The point to reflect this through.</param>
 public override void Reflect(C2DPoint Other)
 {
     // Set up a vector from this to the other
     C2DVector vec = new C2DVector(this, Other);
     // Now use the vector to find the reflection by continuing along it from the point given.
     this.Set(  Other.GetPointTo(vec) );
 }
예제 #10
0
 /// <summary>
 /// Returns the point that the vector supplied would take this point to as a new object.
 /// </summary>
 /// <param name="v1">The vector from this to the new point.</param>
 public C2DPoint GetPointTo(C2DVector v1)
 {
     return(new C2DPoint(x + v1.i, y + v1.j));
 }
예제 #11
0
 /// <summary>
 /// Projects the point on the vector given returning a distance along the vector.
 /// </summary>
 /// <param name="vector">The vector to project this on.</param>
 /// <param name="interval">The interval to recieve the result.
 /// Both the min and max of the interval will be set to the result.</param>
 public override void Project(C2DVector vector, CInterval interval)
 {
     interval.dMax = Project(vector);
     interval.dMin = interval.dMax;
 }
예제 #12
0
 /// <summary>
 /// Construction from a vector which can be thought of as a point (and vice versa).
 /// </summary>
 /// <param name="vector">Vector to assign to.</param>
 public C2DPoint(C2DVector vector)
 {
     x = vector.i;
     y = vector.j;
 }
예제 #13
0
        /// <summary>
        /// Addition.
        /// </summary>
        public static C2DVector operator+(C2DVector V1, C2DVector V2)
        {
            var V3 = new C2DVector(V1.i + V2.i, V1.j + V2.j);

            return(V3);
        }
예제 #14
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)
        {
            var dCenCenDist  = _Centre.Distance(Other.Centre);
            var dOtherRadius = Other.Radius;

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

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

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

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

            return(dDist);
        }
예제 #15
0
        /// <summary>
        /// Projects the point on the line given returning a distance along the line from the start.
        /// </summary>
        /// <param name="Line">The line to project this on.</param>
        public double Project(C2DLine Line)
        {
            C2DVector vecthis = new C2DVector(Line.point, this );

            return (vecthis.Dot(Line.vector)) / Line.vector.GetLength();
        }
예제 #16
0
        /// <summary>
        /// Returns the boolean result (e.g. union) of 2 shapes. Boolean Operation defined by
        /// the inside / outside flags.
        /// </summary>
        /// <param name="Other">Other polygon.</param>
        /// <param name="HoledPolys">Set of polygons to recieve the result.</param>
        /// <param name="bThisInside">Does the operation require elements of this INSIDE the other.</param>
        /// <param name="bOtherInside">Does the operation require elements of the other INSIDE this.</param>
        /// <param name="grid">The grid with the degenerate settings.</param>
        public void GetBoolean(C2DHoledPolyBase Other, List <C2DHoledPolyBase> HoledPolys,
                               bool bThisInside, bool bOtherInside,
                               CGrid grid)
        {
            if (_Rim.Lines.Count == 0 || Other.Rim.Lines.Count == 0)
            {
                return;
            }

            if (_Rim.BoundingRect.Overlaps(Other.Rim.BoundingRect))
            {
                switch (grid.DegenerateHandling)
                {
                case CGrid.eDegenerateHandling.None:
                {
                    var CompleteHoles1 = new List <C2DPolyBase>();
                    var CompleteHoles2 = new List <C2DPolyBase>();
                    var Routes1        = new C2DLineBaseSetSet();
                    var Routes2        = new C2DLineBaseSetSet();
                    GetRoutes(this, bThisInside, Other, bOtherInside, Routes1, Routes2,
                              CompleteHoles1, CompleteHoles2, grid);

                    Routes1.ExtractAllOf(Routes2);

                    if (Routes1.Count > 0)
                    {
                        Routes1.MergeJoining();

                        var Polygons = new List <C2DPolyBase>();

                        for (var i = Routes1.Count - 1; i >= 0; i--)
                        {
                            C2DLineBaseSet pRoute = Routes1[i];
                            if (pRoute.IsClosed(true))
                            {
                                Polygons.Add(new C2DPolyBase());
                                Polygons[Polygons.Count - 1].CreateDirect(pRoute);
                            }
                            else
                            {
                                //   Debug.Assert(false);
                                grid.LogDegenerateError();
                            }
                        }

                        var NewComPolys = new C2DHoledPolyBaseSet();

                        PolygonsToHoledPolygons(NewComPolys, Polygons);

                        NewComPolys.AddKnownHoles(CompleteHoles1);

                        NewComPolys.AddKnownHoles(CompleteHoles2);

                        if (!bThisInside && !bOtherInside && NewComPolys.Count != 1)
                        {
                            //  Debug.Assert(false);
                            grid.LogDegenerateError();
                        }


                        HoledPolys.AddRange(NewComPolys);

                        NewComPolys.Clear();
                    }
                }
                break;

                case CGrid.eDegenerateHandling.RandomPerturbation:
                {
                    var OtherCopy = new C2DHoledPolyBase(Other);
                    OtherCopy.RandomPerturb();
                    grid.DegenerateHandling = CGrid.eDegenerateHandling.None;
                    GetBoolean(OtherCopy, HoledPolys, bThisInside, bOtherInside, grid);
                    grid.DegenerateHandling = CGrid.eDegenerateHandling.RandomPerturbation;
                }
                break;

                case CGrid.eDegenerateHandling.DynamicGrid:
                {
                    var Rect = new C2DRect();
                    if (_Rim.BoundingRect.Overlaps(Other.Rim.BoundingRect, Rect))
                    {
                        //double dOldGrid = CGrid::GetGridSize();
                        grid.SetToMinGridSize(Rect, false);
                        grid.DegenerateHandling = CGrid.eDegenerateHandling.PreDefinedGrid;
                        GetBoolean(Other, HoledPolys, bThisInside, bOtherInside, grid);
                        grid.DegenerateHandling = CGrid.eDegenerateHandling.DynamicGrid;
                    }
                }
                break;

                case CGrid.eDegenerateHandling.PreDefinedGrid:
                {
                    var P1 = new C2DHoledPolyBase(this);
                    var P2 = new C2DHoledPolyBase(Other);
                    P1.SnapToGrid(grid);
                    P2.SnapToGrid(grid);
                    var V1            = new C2DVector(P1.Rim.BoundingRect.TopLeft, P2.Rim.BoundingRect.TopLeft);
                    var dPerturbation = grid.GridSize;                     // ensure it snaps back to original grid positions.
                    if (V1.i > 0)
                    {
                        V1.i = dPerturbation;
                    }
                    else
                    {
                        V1.i = -dPerturbation;          // move away slightly if possible
                    }
                    if (V1.j > 0)
                    {
                        V1.j = dPerturbation;
                    }
                    else
                    {
                        V1.j = -dPerturbation;     // move away slightly if possible
                    }
                    V1.i *= 0.411923;              // ensure it snaps back to original grid positions.
                    V1.j *= 0.313131;              // ensure it snaps back to original grid positions.

                    P2.Move(V1);
                    grid.DegenerateHandling = CGrid.eDegenerateHandling.None;
                    P1.GetBoolean(P2, HoledPolys, bThisInside, bOtherInside, grid);

                    for (var i = 0; i < HoledPolys.Count; i++)
                    {
                        HoledPolys[i].SnapToGrid(grid);
                    }

                    grid.DegenerateHandling = CGrid.eDegenerateHandling.PreDefinedGrid;
                }
                break;

                case CGrid.eDegenerateHandling.PreDefinedGridPreSnapped:
                {
                    var P2            = new C2DHoledPolyBase(Other);
                    var V1            = new C2DVector(_Rim.BoundingRect.TopLeft, P2.Rim.BoundingRect.TopLeft);
                    var dPerturbation = grid.GridSize;
                    if (V1.i > 0)
                    {
                        V1.i = dPerturbation;
                    }
                    else
                    {
                        V1.i = -dPerturbation;     // move away slightly if possible
                    }
                    if (V1.j > 0)
                    {
                        V1.j = dPerturbation;
                    }
                    else
                    {
                        V1.j = -dPerturbation;     // move away slightly if possible
                    }
                    V1.i *= 0.411923;              // ensure it snaps back to original grid positions.
                    V1.j *= 0.313131;              // ensure it snaps back to original grid positions.
                    P2.Move(V1);

                    grid.DegenerateHandling = CGrid.eDegenerateHandling.None;
                    GetBoolean(P2, HoledPolys, bThisInside, bOtherInside, grid);

                    for (var i = 0; i < HoledPolys.Count; i++)
                    {
                        HoledPolys[i].SnapToGrid(grid);
                    }

                    grid.DegenerateHandling = CGrid.eDegenerateHandling.PreDefinedGridPreSnapped;
                }
                break;
                }        // switch
            }
        }
예제 #17
0
        /// <summary>
        /// True if the point projects onto the line given and returns the 
        /// point on the line.
        /// </summary>
        /// <param name="Line"></param>
        public void ProjectOnRay(C2DLine Line)
        {
            C2DVector vecthis = new C2DVector(Line.point, this );
            double dProj = vecthis.Dot(Line.vector);

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

            C2DVector vProj = new C2DVector(Line.vector);
            vProj.i *= dFactor;
            vProj.j *= dFactor;
            this.Set(Line.point.x + vProj.i, Line.point.y + vProj.j);
        }
예제 #18
0
 /// <summary>
 /// Projection onto the vector.
 /// </summary>
 /// <param name="Vector">Vector to project this on.</param>
 /// <param name="Interval">Interval to recieve the result.</param>
 public void Project(C2DVector Vector, CInterval Interval)
 {
     _Rim.Project(Vector, Interval);
 }
예제 #19
0
 /// <summary>
 /// Rotates this to the right about the origin provided.
 /// </summary>
 /// <param name="dAng">The angle through which to rotate.</param>
 /// <param name="Origin">The origin about which to rotate.</param>
 public override void RotateToRight(double dAng, C2DPoint Origin)
 {
     C2DVector vector = new C2DVector(Origin, this);
     vector.TurnRight(dAng);
     x = Origin.x + vector.i;
     y = Origin.y + vector.j;
 }
예제 #20
0
파일: C2DVector.cs 프로젝트: kasznare/DIP1
        /// <summary>
        /// Subtraction.
        /// </summary>
        public static C2DVector operator-(C2DVector V1, C2DVector V2)
        {
            C2DVector V3 = new C2DVector(V1.i - V2.i, V1.j - V2.j);

            return(V3);
        }
예제 #21
0
 /// <summary>
 /// Returns the shortest angle between 2 vectors i.e. the dot product of the norms.
 /// </summary>
 public double AngleBetween(C2DVector Other)
 {
     double dDot = this.Dot(Other);
     dDot /= (this.GetLength() * Other.GetLength());
     return Math.Acos(dDot);
 }
예제 #22
0
파일: C2DVector.cs 프로젝트: kasznare/DIP1
 /// <summary>
 /// Dot product.
 /// </summary>
 public double Dot(C2DVector Other)
 {
     return(i * Other.i + j * Other.j);
 }
예제 #23
0
 /// <summary>
 /// Dot product.
 /// </summary>
 public double Dot(C2DVector Other)
 {
     return i * Other.i + j * Other.j;
 }
예제 #24
0
파일: C2DVector.cs 프로젝트: kasznare/DIP1
 /// <summary>
 /// Cross product.
 /// </summary>
 public double Cross(C2DVector Other)
 {
     return(i * Other.i - j * Other.j);
 }
예제 #25
0
 /// <summary>
 /// Subtraction.
 /// </summary>
 public static C2DVector operator -(C2DVector V1, C2DVector V2)
 {
     C2DVector V3 = new C2DVector(V1.i - V2.i, V1.j - V2.j);
     return V3;
 }
예제 #26
0
파일: C2DVector.cs 프로젝트: kasznare/DIP1
 /// <summary>
 /// Returns the angle to the left to another vector.
 /// </summary>
 public double AngleToLeft(C2DVector Other)
 {
     return(Constants.conTWOPI - AngleToRight(Other));
 }
예제 #27
0
        /// <summary>
        /// Returns the distance from this to the other line.
        /// </summary>
        /// <param name="Other">The Other line.</param>
        /// <param name="ptOnThis">Output. The closest point on this.</param>
        /// <param name="ptOnOther">Output. The closest point on the other line.</param>
	    public double Distance(C2DLine Other,  C2DPoint ptOnThis ,  C2DPoint ptOnOther) 
        {
            // First, project the other line onto this and if it falls entirely below it or
	        // above it then 1. There is no intersection, 2. This is closest to one end on this line.
	        C2DPoint ptOtherP2 = new C2DPoint(Other.GetPointTo());
	        C2DVector vThisP1OtherP1 = new C2DVector(point, Other.point);
	        C2DVector vThisP1OtherP2 = new C2DVector(point, ptOtherP2);
	        C2DPoint ptThisP2 = new C2DPoint(GetPointTo());

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

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

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


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

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

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

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

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

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

			        bSet = true;
		        }

	        }

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

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

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

			        bSet = true;
		        }
	        }

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

        }
예제 #28
0
파일: C2DVector.cs 프로젝트: kasznare/DIP1
 /// <summary>
 /// Constructor with assignment.
 /// </summary>
 /// <param name="Other">other vector.</param>
 public C2DVector(C2DVector Other)
 {
     i = Other.i;
     j = Other.j;
 }
예제 #29
0
        /// <summary>
        /// Projection onto a vector.
        /// </summary>
        /// <param name="Vector">The vector to project this on.</param>
        /// <param name="Interval">Output. The interval.</param>
        public override void Project(C2DVector Vector,  CInterval Interval) 
        {
	        double dP1 = point.Project(Vector);
	        Interval.dMax = dP1;
	        Interval.dMin = dP1;
	        Interval.ExpandToInclude( GetPointTo().Project( Vector) );
        }
예제 #30
0
파일: C2DVector.cs 프로젝트: kasznare/DIP1
 /// <summary>
 /// Assignment.
 /// </summary>
 /// <param name="Other">Other vector.</param>
 public void Set(C2DVector Other)
 {
     i = Other.i;
     j = Other.j;
 }
예제 #31
0
 /// <summary>
 /// Moves this point by the vector given.
 /// </summary>
 /// <param name="Vector">The vector.</param>
 public override void Move(C2DVector Vector)
 {
     P1.Move(Vector);
     P2.Move(Vector);
     P3.Move(Vector);
 }
예제 #32
0
 /// <summary>
 /// This simply moves the real world rectangle.
 /// </summary>
 /// <param name="Vector">Vector to move / scroll by</param>
 public void ScrollReal(C2DVector Vector)
 {
     RealRect.Move(Vector);
 }
예제 #33
0
 /// <summary>
 /// Projects the point on the vector given returning a distance along the vector.
 /// </summary>
 /// <param name="Vector">The vector to project this on.</param>
 /// <param name="Interval">The interval to recieve the result. 
 /// Both the min and max of the interval will be set to the result.</param>
 public override void Project(C2DVector Vector,  CInterval Interval)
 {
     Interval.dMax = Project(Vector);
     Interval.dMin = Interval.dMax;
 }
예제 #34
0
 /// <summary>
 /// This simply moves the real world rectangle but by a scaled, screen based
 /// value e.g. 10 pixels to the right. The image is shown in the same place on
 /// the screen but the image scrolls.
 /// </summary>
 /// <param name="Vector">Vector to scroll / move by.</param>
 public void ScrollScreen(C2DVector Vector)
 {
     RealRect.Move(new C2DVector(Vector.i / Scale.x, Vector.j / Scale.y));
 }
예제 #35
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;
        }
예제 #36
0
파일: C2DPoint.cs 프로젝트: kasznare/DIP1
        /// <summary>
        /// Projects the point on the line given returning a distance along the line from the start.
        /// </summary>
        /// <param name="Line">The line to project this on.</param>
        public double Project(C2DLine Line)
        {
            C2DVector vecthis = new C2DVector(Line.point, this);

            return((vecthis.Dot(Line.vector)) / Line.vector.GetLength());
        }
예제 #37
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);
 }
예제 #38
0
파일: C2DPoint.cs 프로젝트: kasznare/DIP1
 /// <summary>
 /// Projects the point on the vector given returning a distance along the vector.
 /// </summary>
 /// <param name="Vector">The vector to project this on.</param>
 /// <param name="Interval">The interval to recieve the result.
 /// Both the min and max of the interval will be set to the result.</param>
 public override void Project(C2DVector Vector, CInterval Interval)
 {
     Interval.dMax = Project(Vector);
     Interval.dMin = Interval.dMax;
 }
예제 #39
0
 /// <summary>
 /// Construction from a vector which can be thought of as a point (and vice versa).
 /// </summary>
 /// <param name="Vector">Vector to assign to.</param>
 public C2DPoint( C2DVector Vector)
 {
     x = Vector.i;
     y = Vector.j;
 }
예제 #40
0
파일: C2DPoint.cs 프로젝트: kasznare/DIP1
 /// <summary>
 /// Returns the point that the vector supplied would take this point to as a new object.
 /// </summary>
 /// <param name="V1">The vector from this to the new point.</param>
 public C2DPoint GetPointTo(C2DVector V1)
 {
     return(new C2DPoint(x + V1.i, y + V1.j));
 }
예제 #41
0
 /// <summary>
 /// Projection onto the Vector.
 /// </summary>
 /// <param name="Vector">Vector to project on.</param> 
 /// <param name="Interval">Ouput. Projection.</param> 
 public override void Project(C2DVector Vector, CInterval Interval)
 {
     P1.Project(Vector,  Interval);
     Interval.ExpandToInclude(P2.Project(Vector));
     Interval.ExpandToInclude(P3.Project(Vector));
 }
예제 #42
0
파일: C2DPoint.cs 프로젝트: kasznare/DIP1
 /// <summary>
 /// Moves this point by the vector given.
 /// </summary>
 /// <param name="vector">The vector.</param>
 public override void Move(C2DVector vector)
 {
     x += vector.i;
     y += vector.j;
 }
예제 #43
0
 /// <summary>
 /// Returns the angle to the left to another vector.
 /// </summary>
 public double AngleToLeft(C2DVector Other)
 {
     return (Constants.conTWOPI - AngleToRight(Other));
 }
예제 #44
0
파일: C2DPoint.cs 프로젝트: kasznare/DIP1
 /// <summary>
 /// Construction from a vector which can be thought of as a point (and vice versa).
 /// </summary>
 /// <param name="Vector">Vector to assign to.</param>
 public C2DPoint(C2DVector Vector)
 {
     x = Vector.i;
     y = Vector.j;
 }
예제 #45
0
 /// <summary>
 /// Cross product.
 /// </summary>
 public double Cross(C2DVector Other)
 {
     return i * Other.j - j * Other.i;
 }
예제 #46
0
파일: C2DPoint.cs 프로젝트: kasznare/DIP1
        /// <summary>
        /// Projects the point on the vector given returning a distance along the vector.
        /// </summary>
        /// <param name="Vector">The vector to project this on.</param>
        public double Project(C2DVector Vector)
        {
            C2DVector vecthis = new C2DVector(x, y);

            return((vecthis.Dot(Vector)) / Vector.GetLength());
        }
예제 #47
0
 /// <summary>
 /// Assignment.
 /// </summary>
 /// <param name="Other">Other vector.</param>
 public void Set(C2DVector Other)
 {
     i = Other.i;
     j = Other.j;
 }
예제 #48
0
파일: C2DBase.cs 프로젝트: kasznare/DIP1
 /// <summary>
 /// Moves the entity by the vector provided.
 /// </summary>
 public abstract void Move(C2DVector Vector);
예제 #49
0
 /// <summary>
 /// Constructor with assignment.
 /// </summary>
 /// <param name="Other">other vector.</param>
 public C2DVector(C2DVector Other)
 {
     i = Other.i;
     j = Other.j;
 }
예제 #50
0
파일: C2DBase.cs 프로젝트: kasznare/DIP1
 /// <summary>
 /// Projects this onto the vector provided with the interval on the line returned.
 /// </summary>
 public abstract void Project(C2DVector Vector, CInterval Interval);
        /// <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;
        }
예제 #52
0
        /// <summary>
        /// Returns the distance from this to the other line.
        /// </summary>
        /// <param name="Other">The Other line.</param>
        /// <param name="ptOnThis">Output. The closest point on this.</param>
        /// <param name="ptOnOther">Output. The closest point on the other line.</param>
        public double Distance(C2DLine Other, C2DPoint ptOnThis, C2DPoint ptOnOther)
        {
            // First, project the other line onto this and if it falls entirely below it or
            // above it then 1. There is no intersection, 2. This is closest to one end on this line.
            var ptOtherP2      = new C2DPoint(Other.GetPointTo());
            var vThisP1OtherP1 = new C2DVector(point, Other.point);
            var vThisP1OtherP2 = new C2DVector(point, ptOtherP2);
            var ptThisP2       = new C2DPoint(GetPointTo());

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

                    bSet = true;
                }
            }

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

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

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

                    bSet = true;
                }
            }

            Debug.Assert(bSet);
            // Now return the minimum distance
            return(dMinDist);
        }
예제 #53
0
        /// <summary>
        /// Returns the distance from this to the point. 
        /// </summary>
        /// <param name="TestPoint">The test pointt.</param>
        /// <param name="ptOnThis">Output. The closest point on this.</param>
        public override double Distance(C2DPoint TestPoint,  C2DPoint ptOnThis)
        {
	        C2DVector vP1ToPoint = new C2DVector(point, TestPoint);
	        double dLength = GetLength();
	        double dProjLength = vP1ToPoint.Dot(vector);

	        if (dProjLength < 0)
	        {
			    ptOnThis.Set(point);

		        return TestPoint.Distance(point);
	        }
	        else
	        {
		        dProjLength = dProjLength / dLength;
		        if (dProjLength < dLength)
		        {
			        // The projection is on the line
			        double dFactorOnLine = dProjLength / dLength;
			        C2DPoint PtOnLine = new C2DPoint(point.x + vector.i * dFactorOnLine, 
							          point.y + vector.j * dFactorOnLine);
			        ptOnThis.Set(PtOnLine);
			        return TestPoint.Distance(PtOnLine);
		        }
		        else
		        {
			        ptOnThis .Set(GetPointTo());

			        return TestPoint.Distance( GetPointTo() );
		        }
	        }
        }
예제 #54
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="PointFrom">The point from.</param>
 /// <param name="VectorTo">The vector defining the second point.</param>
 public C2DLine(C2DPoint PointFrom, C2DVector VectorTo)
 {
     point.Set(PointFrom);
     vector.Set(VectorTo);
 }
예제 #55
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="PointFrom">The point from.</param>
        /// <param name="VectorTo">The vector defining the second point.</param>
	    public C2DLine(C2DPoint PointFrom, C2DVector VectorTo)
        {
            point.Set(PointFrom);
            vector.Set(VectorTo);
        }
예제 #56
0
 /// <summary>
 /// Moves this point by the vector given.
 /// </summary>
 /// <param name="vector">The vector.</param>
 public override void Move(C2DVector vector)
 {
     point.Move(vector);
 }
예제 #57
0
 /// <summary>
 /// Moves this point by the vector given.
 /// </summary>
 /// <param name="vector">The vector.</param>
 public override void Move(C2DVector vector) 
 {
     point.Move(vector);
 }
예제 #58
0
 /// <summary>
 /// Assignment.
 /// </summary>
 /// <param name="PointFrom">The point from.</param>
 /// <param name="VectorTo">The vector defining the second point.</param>
 public void Set(C2DPoint PointFrom, C2DVector VectorTo)
 {
     point.Set(PointFrom);
     vector.Set(VectorTo);
 }
예제 #59
0
        /// <summary>
        /// Assignment.
        /// </summary>
        /// <param name="PointFrom">The point from.</param>
        /// <param name="VectorTo">The vector defining the second point.</param>
	    public void Set(C2DPoint PointFrom, C2DVector VectorTo)
        {
            point.Set(PointFrom);
            vector.Set(VectorTo);
        }
예제 #60
0
 /// <summary>
 /// Moves this point by the vector given.
 /// </summary>
 /// <param name="Vector">The vector.</param>
 public override void Move(C2DVector Vector)
 {
     _Centre.Move(Vector);
 }