/// <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) { var vP1ToPoint = new C2DVector(point, TestPoint); var dLength = GetLength(); var 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 var dFactorOnLine = dProjLength / dLength; var 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())); } } }
/// <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> /// 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> /// 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) { var vP1ToPoint = new C2DVector(point, TestPoint); // The projection is on the line var 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)); }
/// <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) { var vecthis = new C2DVector(line.point, this); var dProj = vecthis.Dot(line.vector); var dFactor = dProj / (line.vector.i * line.vector.i + line.vector.j * line.vector.j); var vProj = new C2DVector(line.vector); vProj.i *= dFactor; vProj.j *= dFactor; this.Set(line.point.x + vProj.i, line.point.y + vProj.j); }
/// <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); }
/// <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> /// 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> /// 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); }
/// <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> /// 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); }
/// <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(); }
/// <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(); }
/// <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() ); } } }
/// <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()); }
/// <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()); }
/// <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> /// 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; }
/// <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); }