// https://stackoverflow.com/a/18543221 for line-plane intersection. /// <summary> /// Returns true if the line segment intersects with the plane, or false otherwise. /// /// Specify output parameters to receive more detailed information about the /// intersection, such as the point at which it occurs and whether the line lies on /// the plane. /// </summary> public static bool Intersect(LocalPlane plane, LocalSegment3 line) { Vector3 pointOnPlane_unused; float amountAlongSegment_unused; bool isLineCoplanar_unused; return(Intersect(plane, line, out pointOnPlane_unused, out amountAlongSegment_unused, out isLineCoplanar_unused)); }
/// <summary> /// Returns true if the line segment intersects with the plane, or false otherwise. /// /// If intersectInfiniteLine is specified, returns true if the line defined by the /// line segment intersects with the plane, or false otherwise. /// /// If this method returns true, no out parameters are set to NaN, and reasonable /// defaults are chosen in edge-cases (such as a coplanar line). If this method /// returns false, some or all output parameters may have no reasonable value and /// are set to NaN. /// /// pointOnPlane is the point along the line defined by the segment that intersects /// with the plane. If the line segment is parallel to the plane and _on_ the plane, /// pointOnPlane will be set to the center of the line segment as a convenience. /// Otherwise, it will be set to a Vector3 containing all NaNs. /// /// amountAlongSegment is the normalized amount from A to B along the line segment /// that intersects with the plane. The line segment intersects with the plane only /// if this value is between 0 and 1 (inclusive). If the line segment is parallel to /// the plane and _on_ the plane, amountAlongSegment will be set to 0.5f. Otherwise, /// amountAlongSegment will be set to NaN. /// /// isLineCoplanar is true if the line defined by the line segment is wholly on /// the plane, or false otherwise. /// </summary> public static bool Intersect(LocalPlane plane, LocalSegment3 line, out Vector3 pointOnPlane, out float amountAlongSegment, out bool isLineCoplanar, bool intersectInfiniteLine = false) { var planePosition = plane.position; var planeNormal = plane.normal; var a = line.a; var b = line.b; var u = b - a; var uDotN = planeNormal.Dot(u); if (uDotN.Abs() > float.Epsilon) { isLineCoplanar = false; var w = a - planePosition; amountAlongSegment = -(planeNormal.Dot(w)) / uDotN; pointOnPlane = a + u * amountAlongSegment; return(intersectInfiniteLine || (amountAlongSegment >= 0f && amountAlongSegment <= 1f)); } else { var pa = a - planePosition; if (planeNormal.Dot(pa).Abs() < float.Epsilon) { isLineCoplanar = true; } else { isLineCoplanar = false; } if (isLineCoplanar) { pointOnPlane = (a + b) / 2f; amountAlongSegment = 0.5f; return(true); } else { pointOnPlane = new Vector3(float.NaN, float.NaN, float.NaN); amountAlongSegment = float.NaN; return(false); } } }