123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- #if UNITY_EDITOR
- using UnityEngine;
- namespace O3DWB
- {
- public struct Segment3D
- {
- #region Private Variables
- private Vector3 _startPoint;
- private Vector3 _normalizedDirection;
- private Vector3 _direction;
- private float _length;
- private float _sqrLength;
- #endregion
- #region Public Properties
- public Vector3 StartPoint { get { return _startPoint; } }
- public Vector3 EndPoint { get { return _startPoint + _normalizedDirection * _length; } }
- public Vector3 NormalizedDirection { get { return _normalizedDirection; } }
- public Vector3 Direction { get { return _direction; } }
- public float Length { get { return _length; } }
- public float SqrLength { get { return _sqrLength; } }
- public float HalfLength { get { return _length * 0.5f; } }
- #endregion
- #region Constructors
- public Segment3D(Vector3 startPoint, Vector3 endPoint)
- {
- _startPoint = startPoint;
- _direction = endPoint - _startPoint;
- _length = _direction.magnitude;
- _sqrLength = _direction.sqrMagnitude;
- _normalizedDirection = _direction;
- _normalizedDirection.Normalize();
- }
- public Segment3D(Ray3D ray)
- {
- _startPoint = ray.Origin;
- _direction = ray.Direction;
- _length = _direction.magnitude;
- _sqrLength = _direction.sqrMagnitude;
- _normalizedDirection = _direction;
- _normalizedDirection.Normalize();
- }
- #endregion
- #region Public Methods
- public Vector3 GetRandomPoint()
- {
- float randomT = UnityEngine.Random.Range(0.0f, 1.0f);
- return _startPoint + randomT * _direction;
- }
- public Vector3 GetPoint(float t)
- {
- return _startPoint + t * _direction;
- }
- public bool IsPerpendicualrTo(Segment3D segment)
- {
- return Direction.IsPerpendicularTo(segment.Direction);
- }
- public bool IntersectsWith(Segment3D segment)
- {
- float t1, t2;
- return IntersectsWith(segment, out t1, out t2);
- }
- public bool IntersectsWith(Segment3D segment, out float t1, out float t2)
- {
- t1 = t2 = 0.0f;
- if (_length == 0.0f || segment.Length == 0.0f) return false;
- // If the segments are parallel, they don't intersect
- if (segment.NormalizedDirection.IsAlignedWith(_normalizedDirection)) return false;
- // Check if the 2 segments are coplanar
- Vector3 segmentPlaneNormal = Vector3.Cross(segment.NormalizedDirection, _normalizedDirection);
- Vector3 fromThisSegmentStartToOtherSegmentStart = segment.StartPoint - _startPoint;
- if (!fromThisSegmentStartToOtherSegmentStart.IsPerpendicularTo(segmentPlaneNormal)) return false;
- // Build a plane which slices thorough the segment
- Vector3 slicingPlaneNormal = Vector3.Cross(segmentPlaneNormal, _normalizedDirection);
- slicingPlaneNormal.Normalize();
- Plane slicingPlane = new Plane(slicingPlaneNormal, _startPoint);
-
- // Check if the query segment intersects the plane
- float t;
- Ray3D querySegmentRay = new Ray3D(segment.StartPoint, segment.Direction);
- if (querySegmentRay.IntersectsPlane(slicingPlane, out t))
- {
- // The segment intersect the plane, but we have to ensure that the intersection point lies somewehre along 'this' segment.
- Vector3 intersectionPoint = querySegmentRay.Origin + t * querySegmentRay.Direction;
- Vector3 toIntersectionPoint = intersectionPoint - _startPoint;
- if (Vector3.Dot(toIntersectionPoint, _normalizedDirection) < 0.0f) return false;
- if (toIntersectionPoint.sqrMagnitude > _sqrLength) return false;
- t1 = toIntersectionPoint.magnitude / _length;
- t2 = t;
- return true;
- }
- return false;
- }
- #endregion
- }
- }
- #endif
|