/// <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> /// 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)); }
/// <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)); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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> /// 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); } }
/// <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)); } }
/// <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); }
/// <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; }