/// <summary> /// Intersects a line segment with the shape and returns the intersection point closest to the beginning of the segment. /// </summary> /// <param name="segment">The line segment to intersect.</param> /// <param name="scalar">A value between 0 and 1 indicating how far along the segment the intersection occurs.</param> /// <param name="p">The point of the intersection closest to the beginning of the line segment.</param> /// <returns>Returns a value indicating whether there is an intersection.</returns> public bool Intersect(ref Segment segment, out float scalar, out Vector3 p) { Vector3 d, m, n; float md, nd, dd; Vector3.Subtract(ref P2, ref P1, out d); Vector3.Subtract(ref segment.P1, ref P1, out m); Vector3.Subtract(ref segment.P2, ref segment.P1, out n); Vector3.Dot(ref d, ref m, out md); Vector3.Dot(ref d, ref n, out nd); Vector3.Dot(ref d, ref d, out dd); if (!(md < 0f && md + nd < 0f) && !(md > dd && md + nd > dd)) { float nn, mn, k; Vector3.Dot(ref n, ref n, out nn); Vector3.Dot(ref m, ref n, out mn); float a = dd * nn - nd * nd; Vector3.Dot(ref m, ref m, out k); k -= Radius * Radius; float c = dd * k - md * md; if (Math.Abs(a) >= Constants.Epsilon) { float b = dd * mn - nd * md; float discr = b * b - a * c; if (discr >= 0f) { float t = (-b - (float)Math.Sqrt(discr)) / a; if (t >= 0f && t <= 1f && md + t * nd >= 0f && md + t * nd <= dd) { scalar = t; Vector3.Multiply(ref n, t, out p); Vector3.Add(ref segment.P1, ref p, out p); return true; } } } } var cap = new Sphere(P1, Radius); float s; scalar = float.MaxValue; p = Vector3.Zero; Vector3 v; if (cap.Intersect(ref segment, out s, out v)) { scalar = s; p = v; } cap.Center = P2; if (cap.Intersect(ref segment, out s, out v) && s < scalar) { scalar = s; p = v; } return scalar >= 0f && scalar <= 1f; }
/// <summary> /// Intersects a line segment with the shape and returns the intersection point closest to the beginning of the segment. /// </summary> /// <param name="segment">The line segment to intersect.</param> /// <param name="scalar">A value between 0 and 1 indicating how far along the segment the intersection occurs.</param> /// <param name="p">The point of the intersection closest to the beginning of the line segment.</param> /// <returns>Returns a value indicating whether there is an intersection.</returns> public bool Intersect(ref Segment segment, out float scalar, out Vector3 p) { Vector3 d, m, n; float md, nd, dd; Vector3.Subtract(ref P2, ref P1, out d); Vector3.Subtract(ref segment.P1, ref P1, out m); Vector3.Subtract(ref segment.P2, ref segment.P1, out n); Vector3.Dot(ref d, ref m, out md); Vector3.Dot(ref d, ref n, out nd); Vector3.Dot(ref d, ref d, out dd); if (!(md < 0f && md + nd < 0f) && !(md > dd && md + nd > dd)) { float nn, mn, k; Vector3.Dot(ref n, ref n, out nn); Vector3.Dot(ref m, ref n, out mn); float a = dd * nn - nd * nd; Vector3.Dot(ref m, ref m, out k); k -= Radius * Radius; float c = dd * k - md * md; if (Math.Abs(a) >= Constants.Epsilon) { float b = dd * mn - nd * md; float discr = b * b - a * c; if (discr >= 0f) { float t = (-b - (float)Math.Sqrt(discr)) / a; if (t >= 0f && t <= 1f && md + t * nd >= 0f && md + t * nd <= dd) { scalar = t; Vector3.Multiply(ref n, t, out p); Vector3.Add(ref segment.P1, ref p, out p); return(true); } } } } var cap = new Sphere(P1, Radius); float s; scalar = float.MaxValue; p = Vector3.Zero; Vector3 v; if (cap.Intersect(ref segment, out s, out v)) { scalar = s; p = v; } cap.Center = P2; if (cap.Intersect(ref segment, out s, out v) && s < scalar) { scalar = s; p = v; } return(scalar >= 0f && scalar <= 1f); }
/// <summary> /// Intersects a segment with this collision skin part and returns the intersection point that is nearest to the /// beginning of the segment. /// </summary> /// <param name="segment">The segment to intersect with.</param> /// <param name="scalar">Returns a value between 0 and 1 indicating where on the segment the first intersection occurs.</param> /// <param name="point">Returns the point of the first intersection.</param> /// <returns>Returns a value indicating whether the segment intersects with the part.</returns> public override bool Intersect(ref Segment segment, out float scalar, out Vector3 point) { return(World.Intersect(ref segment, out scalar, out point)); }