// Checks to see if this line intersects with "line2". True is returned // if they do intersect. The "ISectPt" is optional and can be NULL, but, if // provided, it is filled with the point of intersection. // IMPORTANT: If the two lines are equal then false is returned, not true. // Do not call for degenerate lines (check with IsDegenerate). public bool Intersects(NormalizedGeneralLine2D line2, ref EOFC.Vector2D ISectPt) { // If the two lines are parallel then they won't intersect if (IsParallel(line2)) { return(false); } float x, y; // Handle special case if (m_a == 0.0f) { y = -m_c / m_b; x = (-line2.m_b * y - line2.m_c) / line2.m_a; ISectPt = new EOFC.Vector2D(x, y); return(true); } // else float val1 = (-line2.m_a * m_b) / m_a + line2.m_b; y = ((line2.m_a * m_c / m_a) - line2.m_c) / val1; x = (-m_b * y - m_c) / m_a; ISectPt = new EOFC.Vector2D(x, y); return(true); }
// ProjectPoint // Returns the point on the line that has the shortest distance to the // specified point. This equivalent to visually bringing the point "straight // down" onto the line, somewhat like "projecting" it onto the line. public EOFC.Vector2D ProjectPoint(EOFC.Vector2D point) { float distance = m_a * point.X + m_b * point.Y + m_c; EOFC.Vector2D Norm = new EOFC.Vector2D(m_a, m_b); return(point + Norm * (-distance)); }
public bool Intersects(GeneralLine2D line2, ref EOFC.Vector2D intersectionPt) { // If the two lines are parallel then they won't intersect if (IsParallel(line2)) { return(false); } float x, y; // Handle special case if (0.0f == A) { y = -C / B; x = (-line2.B * y - line2.C) / line2.A; intersectionPt = new EOFC.Vector2D(x, y); return(true); } float val1 = (-line2.A * B) / A + line2.B; y = ((line2.A * C / A) - line2.C) / val1; x = (-B * y - C) / A; intersectionPt = new EOFC.Vector2D(x, y); return(true); }
/// <summary> /// Constructs a line instance from 2 different points that lie on the line. /// </summary> public GeneralLine2D(Vector2D point1, Vector2D point2) { EOFC.Vector2D LV = (point2 - point1); LV.Normalize(); A = -LV.Y; B = LV.X; C = -(A * point1.X + B * point1.Y); }
/// <summary> /// Constructs a line instance from 2 different points that lie on the line. /// </summary> public NormalizedGeneralLine2D(EOFC.Vector2D point1, EOFC.Vector2D point2) { EOFC.Vector2D LV = (point2 - point1); LV.Normalize(); m_a = -LV.Y; m_b = LV.X; m_c = -(m_a * point1.X + m_b * point1.Y); }
public NormalizedGeneralLine2D(float x1, float y1, float x2, float y2) { EOFC.Vector2D LV = new EOFC.Vector2D(x2 - x1, y2 - y1); LV.Normalize(); m_a = -LV.Y; m_b = LV.X; m_c = -(m_a * x1 + m_b * y1); }
public EOFC.Vector2D ReflectPoint(EOFC.Vector2D pt) { float[] M = new float[9]; GetReflectionMatrix(M); EOFC.Vector2D output = new EOFC.Vector2D( M[0] * pt.X + M[1] * pt.Y + M[2], M[3] * pt.X + M[4] * pt.Y + M[5]); return(output); }
/// <summary> /// Tests if a point, WHICH IS ALREADY KNOWN TO BE ON THE INFINITE LINE, is on this segment. /// </summary> private bool IsPointOnSegment(EOFC.Vector2D pt) { // If distance (squared) from p1 to pt and distance (squared) from p2 to pt are // both less than the distance (squared) from p1 to p2, then it's on the segment. float lsqrd = m_l * m_l; float l1 = (pt.X - m_p1.X) * (pt.X - m_p1.X) + (pt.Y - m_p1.Y) * (pt.Y - m_p1.Y); float l2 = (pt.X - m_p2.X) * (pt.X - m_p2.X) + (pt.Y - m_p2.Y) * (pt.Y - m_p2.Y); return(l1 <= lsqrd && l2 <= lsqrd); }
/// <summary> /// Returns the signed distance from the specified point to this line segment. /// This will be the distance from the point to the closet point on the segment. /// The sign is with respect to an arbitrary, but consistent, normal vector which /// can be retrieved from the "GetUnitNormal" function. /// </summary> public float Distance(EOFC.Vector2D point) { if (DoesPointProjectOnto(point)) { EOFC.Vector2D unorm = GetUnitNormal(); return((point - m_p1).DotProduct(unorm)); } // If the point doesn't project onto the segment, then the smallest distance // will be from one of the endpoints. return(Math.Min((point - m_p1).Length, (point - m_p2).Length)); }
public bool IsParallel(LineSegment2D seg2) { // The two segments will be parallel if their line vectors are the same // or one is the negative of the other. EOFC.Vector2D v1 = GetVector(); EOFC.Vector2D v2 = seg2.GetVector(); v1.Normalize(); v2.Normalize(); if (v1.DotProduct(v2) == 1.0f) { return(true); } return(false); }
public bool Intersects(LineSegment2D segment2, ref EOFC.Vector2D outISectPt) { float t = 0.0f; if (!Intersects(segment2, ref t)) { return(false); } // Fill the intersection point float dx1 = m_p2.X - m_p1.X; float dy1 = m_p2.Y - m_p1.Y; outISectPt.Set(m_p1.X + t * dx1, m_p1.Y + t * dy1); return(true); }
/// <summary> /// Returns the shortest unsigned distance from the specified point to this arc. /// </summary> public float DistanceU(EOFC.Vector2D point) { // Start by getting the angle of the point with respect to the circle center double angle = (point - m_circle.Center).GetCCWAngle(); // If the angle is in the angle range for this arc then the shortest distance will // be from the point to the edge of the circle. if (IsAngleInRange(angle, m_startAngle, m_sweepAngle)) { return(Math.Abs(m_circle.Radius - (point - m_circle.Center).Length)); } // Otherwise the distance is the smaller of the two distances between the point and the // arc endpoints. return(Math.Min( (point - m_circle.GetPointOnPerimeter(m_startAngle)).Length, (point - m_circle.GetPointOnPerimeter(m_startAngle + m_sweepAngle)).Length)); }
public bool Intersects(NormalizedGeneralLine2D line, ref EOFC.Vector2D outISectPt) { NormalizedGeneralLine2D thisInfLine = GetInfiniteLine(); EOFC.Vector2D temp = new Vector2D(); if (!thisInfLine.Intersects(line, ref temp)) { return(false); } // The two infinite lines intersect, now see if the intersection point // is on this segment if (this.IsPointOnSegment(temp)) { outISectPt = temp; return(true); } return(false); }
/// <summary> /// Gets the point on this line segment with the specified y-value. If no such point /// exists on the segment then false is returned. Note that if the segment is horizontal, /// even if it has a y-value of "y", then false is returned. /// </summary> public bool GetPointWithYValue(float y, ref EOFC.Vector2D outPt) { // If this segment is horizontal, return false. if (m_p1.Y == m_p2.Y) { return(false); } NormalizedGeneralLine2D infLine = GetInfiniteLine(); float x = infLine.GetXCoord(y); EOFC.Vector2D pt = new EOFC.Vector2D(x, y); if (IsPointOnSegment(pt)) { outPt.Set(pt); return(true); } return(false); }
/// <summary> /// Gets the point on this line segment with the specified x-value. If no such point /// exists on the segment then false is returned. Note that if the segment is vertical, /// even if it has a x-value of "x", then false is returned. /// </summary> public bool GetPointWithXValue(float x, ref EOFC.Vector2D outPt) { // If this segment is vertical, return false. if (m_p1.X == m_p2.X) { return(false); } NormalizedGeneralLine2D infLine = GetInfiniteLine(); float y = infLine.GetYCoord(x); EOFC.Vector2D pt = new EOFC.Vector2D(x, y); if (IsPointOnSegment(pt)) { outPt.Set(pt); return(true); } return(false); }
/// <summary> /// Returns the unsigned distance from the specified point to this line segment /// </summary> public float DistanceU(Vector2D point) { EOFC.Vector2D pointMinusP1 = (point - m_p1); float p = pointMinusP1.ScalarProjectOnto(m_p2 - m_p1); if (p >= 0.0f && p <= m_l) { float s = pointMinusP1.LengthSquared - (p * p); if (s <= 0.0f) { // This should only ever occur because of rounding errors return(0.0f); } return((float)Math.Sqrt(s)); } float d1 = pointMinusP1.Length; float d2 = (point - m_p2).Length; return((d1 < d2) ? d1 : d2); }
public bool Contains(EOFC.Vector2D point) { return((point - m_center).Length <= m_radius); }
public bool IsPointOnLine(EOFC.Vector2D pt) { return(0.0f == (m_a * pt.X + m_b * pt.Y + m_c)); }
public LineSegment2D(EOFC.Vector2D point1, EOFC.Vector2D point2) { m_p1 = point1; m_p2 = point2; m_l = (m_p2 - m_p1).Length; }
/// <summary> /// Returns the signed point distance from the specified point to this line. /// </summary> public float PointDistance(EOFC.Vector2D pt) { return(m_a * pt.X + m_b * pt.Y + m_c); }
public float PointDistanceUnsigned(EOFC.Vector2D pt) { return(Math.Abs(A * pt.X + B * pt.Y + C) / NormalLength); }
/// <summary> /// Gets the point on this line segment with the specified y-value. If no such point /// exists on the segment then false is returned. Note that if the segment is horizontal, /// even if it has a y-value of "y", then false is returned. /// </summary> public bool GetPointWithYValue(float y, ref EOFC.Vector2D outPt) { // If this segment is horizontal, return false. if (m_p1.Y == m_p2.Y) { return false; } NormalizedGeneralLine2D infLine = GetInfiniteLine(); float x = infLine.GetXCoord(y); EOFC.Vector2D pt = new EOFC.Vector2D(x, y); if (IsPointOnSegment(pt)) { outPt.Set(pt); return true; } return false; }
public bool Intersects(GeneralLine2D line2, ref EOFC.Vector2D intersectionPt) { // If the two lines are parallel then they won't intersect if (IsParallel(line2)) { return false; } float x, y; // Handle special case if (0.0f == A) { y = -C / B; x = (-line2.B * y - line2.C) / line2.A; intersectionPt = new EOFC.Vector2D(x, y); return true; } float val1 = (-line2.A * B) / A + line2.B; y = ((line2.A * C / A) - line2.C) / val1; x = (-B * y - C) / A; intersectionPt = new EOFC.Vector2D(x, y); return true; }
public bool DoesPointProjectOnto(EOFC.Vector2D pt) { float p = (pt - m_p1).ScalarProjectOnto(m_p2 - m_p1); return(p >= 0.0f && p <= m_l); }
/// <summary> /// Gets the point on this line segment with the specified x-value. If no such point /// exists on the segment then false is returned. Note that if the segment is vertical, /// even if it has a x-value of "x", then false is returned. /// </summary> public bool GetPointWithXValue(float x, ref EOFC.Vector2D outPt) { // If this segment is vertical, return false. if (m_p1.X == m_p2.X) { return false; } NormalizedGeneralLine2D infLine = GetInfiniteLine(); float y = infLine.GetYCoord(x); EOFC.Vector2D pt = new EOFC.Vector2D(x, y); if (IsPointOnSegment(pt)) { outPt.Set(pt); return true; } return false; }