Пример #1
0
        // 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));
        }
Пример #2
0
        /// <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);
                }
            }
        }