LineLineIntersection() публичный статический Метод

public static LineLineIntersection ( Vector3 &intersection, Vector3 linePoint1, Vector3 lineVec1, Vector3 linePoint2, Vector3 lineVec2 ) : bool
intersection Vector3
linePoint1 Vector3
lineVec1 Vector3
linePoint2 Vector3
lineVec2 Vector3
Результат bool
Пример #1
0
        private Vector3 SegmentIntersection(Vector3 subpoint1Ab, Vector3 subpoint2Cd, Vector3 subpoint1Bc,
                                            Vector3 subpoint2Da)
        {
            Vector3 intesection;

            Math3D.LineLineIntersection(out intesection, subpoint1Ab, subpoint1Ab - subpoint2Cd, subpoint1Bc,
                                        subpoint1Bc - subpoint2Da);
            return(intesection);
        }
Пример #2
0
        private Vector3 GetIntesectionsBetweenHalfsWithBisector(Vector3 halfSegment1, Vector3 halfSegment2,
                                                                Vector3 punt1, Vector3 punt2)
        {
            Vector3 intesection;

            Math3D.LineLineIntersection(out intesection, halfSegment1, halfSegment1 - halfSegment2, punt1,
                                        punt1 - punt2);
            return(intesection);
        }
Пример #3
0
        /// <summary>
        /// Draws the directions of the bezier curve
        /// </summary>
        private void ShowDirections()
        {
            for (int i = 0; i < spline.CurveCount; i++)
            {
                if (Settings.ShowSteps)
                {
                    for (int s = 0; s < Settings.StepsPerCurve; s++)
                    {
                        Vector3 _point = handleTransform.TransformPoint(Bezier.BezierMath.CubicGetPoint(
                                                                            spline[i * 3],
                                                                            spline[i * 3 + 1],
                                                                            spline[i * 3 + 2],
                                                                            spline[i * 3 + 3], (float)s / Settings.StepsPerCurve));
                        Vector3 _pointDerivative = handleTransform.TransformDirection(Bezier.BezierMath.CubicGetFirstDerivative(
                                                                                          spline[i * 3],
                                                                                          spline[i * 3 + 1],
                                                                                          spline[i * 3 + 2],
                                                                                          spline[i * 3 + 3], (float)s / Settings.StepsPerCurve));

                        // which way is the middle point's right
                        Vector3 _pointRight = (Quaternion.LookRotation(Vector3.right) * _pointDerivative).normalized;
                        // which way is the middle point's left
                        Vector3 _pointLeft = (Quaternion.LookRotation(Vector3.left) * _pointDerivative).normalized;
                        // which way is up
                        Vector3 _pointUp = Vector3.Cross(_pointLeft, _pointDerivative).normalized;

                        Handles.color = Color.blue;
                        Handles.DrawLine(_point, _point + _pointUp * Settings.DirectionScale);
                        Handles.color = Color.green;
                        Handles.DrawLine(_point, _point + _pointLeft * Settings.DirectionScale);
                        Handles.color = Color.red;
                        Handles.DrawLine(_point, _point + _pointRight * Settings.DirectionScale);
                    }
                }

                if (Settings.ShowPivots)
                {
                    Vector3 _pivot;
                    // get pivot -> the intersection of the point normals at the start and end points
                    Math3D.LineLineIntersection(
                        out _pivot,
                        spline[i * 3],
                        (Quaternion.LookRotation(Vector3.right) * Bezier.BezierMath.CubicGetFirstDerivative(spline[i * 3], spline[i * 3 + 1], spline[i * 3 + 2], spline[i * 3 + 3], 0.01f)).normalized,
                        spline[i * 3 + 3],
                        (Quaternion.LookRotation(Vector3.right) * Bezier.BezierMath.CubicGetFirstDerivative(spline[i * 3], spline[i * 3 + 1], spline[i * 3 + 2], spline[i * 3 + 3], 0.99f)).normalized
                        );
                    _pivot = handleTransform.TransformPoint(_pivot);

                    Handles.color = spline.color;

                    Handles.DrawLine(spline[i * 3], _pivot);
                    Handles.DrawLine(spline[i * 3 + 3], _pivot);
                    Handles.DrawWireCube(_pivot, new Vector3(1, 1, 1));
                }
            }
        }
Пример #4
0
        protected override void SetExtentPoints()
        {
            if (setAnchorsCount > 0 &&
                PlayAreaState == EPlayAreaState.SETTING_ANCHORS &&
                ARE_EQUAL(PlayAreaBAnchors.Count, 2))
            {
                //Vector3 firstAnchorPosition = BUtils.Get3DPlanearVector(playAreaBAnchors[0].GetPosition());
                Vector3 firstAnchorPosition = PlayAreaBAnchors[0].GetPosition();
                Vector3 firstAnchorForward  = PlayAreaBAnchors[0].transform.forward;
                Vector3 firstAnchorRight    = PlayAreaBAnchors[0].transform.right;

                //Vector3 SecondAnchorPosition = BUtils.Get3DPlanearVector(playAreaBAnchors[1].GetPosition());
                Vector3 SecondAnchorPosition = PlayAreaBAnchors[1].GetPosition();
                SecondAnchorPosition = new Vector3(SecondAnchorPosition.x, firstAnchorPosition.y, SecondAnchorPosition.z);
                Vector3 SecondAnchorForward = PlayAreaBAnchors[1].transform.forward;
                Vector3 SecondAnchorRight   = PlayAreaBAnchors[1].transform.right;

                Vector3 firstIntersectionPoint;
                Math3D.LineLineIntersection(out firstIntersectionPoint, firstAnchorPosition, firstAnchorForward, SecondAnchorPosition, SecondAnchorRight);
                //if (Math3D.LineLineIntersection(out firstIntersectionPoint, firstAnchorPosition, firstAnchorForward, SecondAnchorPosition, SecondAnchorRight) == false)
                //{
                //    Vector3 closestPoint1;
                //    Vector3 closestPoint2;
                //    Math3D.ClosestPointsOnTwoLines(out closestPoint1, )
                //}

                Vector3 secondIntersectionPoint;
                Math3D.LineLineIntersection(out secondIntersectionPoint, firstAnchorPosition, firstAnchorRight, SecondAnchorPosition, SecondAnchorForward);

                ExtentPoints.Clear();
                ExtentPoints.Add(firstAnchorPosition);
                ExtentPoints.Add(firstIntersectionPoint);
                ExtentPoints.Add(SecondAnchorPosition);
                ExtentPoints.Add(secondIntersectionPoint);
            }
        }
Пример #5
0
 public static bool LineLineIntersection(out Vector3 intersection, Line line1, Line line2)
 {
     return(Math3D.LineLineIntersection(out intersection, line1.point, line1.direction, line2.point, line2.direction));
 }
Пример #6
0
        /// <summary>
        /// Shifts the spline with <paramref name="amount"/> distance and returns a new spline
        /// </summary>
        /// <param name="safeDist">
        /// The max distance between the middle of the curves and their extreme points.
        /// If your shifted curve has too many sharp edges try pumping this number up.
        /// But beware because it causes it to have more points and thus decreasing performance.
        /// </param>
        /// <param name="newSpline">If you want the returned spline to be put into an already existing spline assign this parameter.</param>
        public BezierSpline GetShiftedSpline(float amount, float safeDist = 0.3f, BezierSpline newSpline = null)
        {
            BezierSpline _shiftedSpline;

            if (newSpline != null)
            {
                _shiftedSpline = newSpline;
            }
            else
            {
                _shiftedSpline = new GameObject().AddComponent <BezierSpline>();
            }
            _shiftedSpline.Clear();
            _shiftedSpline.name = "Lane" + amount;

            // So, you cannot offset a Bézier curve perfectly with another Bézier curve, no matter how high-order you make that
            // other Bézier curve. However, we can chop up a curve into "safe" sub-curves (where safe means that all the control
            // points are always on a single side of the baseline, and the midpoint of the curve at t=0.5 is roughly in the centre
            // of the polygon defined by the curve coordinates) and then point-scale each sub-curve with respect to its scaling
            // origin (which is the intersection of the point normals at the start and end points).

            // A good way to do this reduction is to first find the curve's extreme points, and use these as initial splitting points.
            // After this initial split, we can check each individual segment to see if it's "safe enough" based on where the
            // center of the curve is.If the on-curve point for t = 0.5 is too far off from the center, we simply split the
            // segment down the middle. Generally this is more than enough to end up with safe segments.

            Vector3          _p0 = points[0];
            Vector3          _p1, _p2, _p3;
            List <Vector3[]> _newPointsSpline = new List <Vector3[]>();

            for (int i = 3; i < PointCount; i += 3)
            {
                _p1 = points[i - 2];
                _p2 = points[i - 1];
                _p3 = points[i];

                // roots of our cubic bezier curve to find extremes
                SortedSet <float> _solutions = new SortedSet <float>();
                {
                    float?_sol1, _sol2;

                    BezierMath.CubicGetRoots(_p0.x, _p1.x, _p2.x, _p3.x, out _sol1, out _sol2);
                    if (_sol1.HasValue && _sol1.Value < 1 && _sol1.Value > 0)
                    {
                        _solutions.Add(_sol1.Value);
                    }
                    if (_sol2.HasValue && _sol2.Value < 1 && _sol2.Value > 0)
                    {
                        _solutions.Add(_sol2.Value);
                    }

                    BezierMath.CubicGetRoots(_p0.y, _p1.y, _p2.y, _p3.y, out _sol1, out _sol2);
                    if (_sol1.HasValue && _sol1.Value < 1 && _sol1.Value > 0)
                    {
                        _solutions.Add(_sol1.Value);
                    }
                    if (_sol2.HasValue && _sol2.Value < 1 && _sol2.Value > 0)
                    {
                        _solutions.Add(_sol2.Value);
                    }

                    BezierMath.CubicGetRoots(_p0.z, _p1.z, _p2.z, _p3.z, out _sol1, out _sol2);
                    if (_sol1.HasValue && _sol1.Value < 1 && _sol1.Value > 0)
                    {
                        _solutions.Add(_sol1.Value);
                    }
                    if (_sol2.HasValue && _sol2.Value < 1 && _sol2.Value > 0)
                    {
                        _solutions.Add(_sol2.Value);
                    }
                }

                // the list of new points of the offset curve
                List <Vector3[]> _newPointsCurve = new List <Vector3[]>();

                // So we're gonna need to split the starting curve at potentially more points
                // We do that by splitting in order and always taking the second split curve as the next
                // starting curve
                {
                    Vector3[] _first, _second = new Vector3[] { _p0, _p1, _p2, _p3 };
                    float     _secondSize     = 1f; // we need this to know how big the second curve is compared to the very first starting curve
                                                    // so we can split at the right point
                    foreach (float sol in _solutions)
                    {
                        BezierMath.CubicSplitCurve(_second[0], _second[1], _second[2], _second[3], _secondSize * sol, out _first, out _second);

                        _secondSize *= (1f - sol);
                        _newPointsCurve.Add(_first);
                    }
                    _newPointsCurve.Add(_second); // no more calculations with the second curve, so we can add it to the list
                }

                // check whether each bezier curve is safe or not if not split it
                {
                    int _at = _newPointsCurve.Count - 1;

                    while (_at >= 0)
                    {
                        Vector3[] _split1, _split2;
                        // where the curv t = 0.5f
                        Vector3 _zeroDotFive = BezierMath.CubicGetPoint(_newPointsCurve[_at][0], _newPointsCurve[_at][1],
                                                                        _newPointsCurve[_at][2], _newPointsCurve[_at][3], 0.5f);
                        // the center of the curve's 4 points
                        Vector3 _center = (_newPointsCurve[_at][0] + _newPointsCurve[_at][1] + _newPointsCurve[_at][2] + _newPointsCurve[_at][3]) / 4f;

                        // if they are too far away
                        if (Vector3.Distance(_zeroDotFive, _center) > safeDist)
                        {
                            // split curva at 0.5f
                            BezierMath.CubicSplitCurve(_newPointsCurve[_at][0], _newPointsCurve[_at][1], _newPointsCurve[_at][2], _newPointsCurve[_at][3], 0.5f,
                                                       out _split1, out _split2);

                            // overwrite current curve
                            _newPointsCurve[_at] = _split2;
                            // add one before it
                            _newPointsCurve.Insert(_at, _split1);
                            // we need to check the _split too again as well, so add one to at
                            _at++;
                        }
                        else
                        {
                            // no problem with this curve, move on
                            _at--;
                        }
                    }
                }

                // scale
                {
                    Vector3 _pivot;

                    for (int k = 0; k < _newPointsCurve.Count; k++)
                    {
                        // get pivot -> the intersection of the point normals at the start and end points
                        bool _doIntersect = Math3D.LineLineIntersection(
                            out _pivot,
                            _newPointsCurve[k][0],
                            (Quaternion.LookRotation(Vector3.right) * BezierMath.CubicGetFirstDerivative(_newPointsCurve[k][0], _newPointsCurve[k][1], _newPointsCurve[k][2], _newPointsCurve[k][3], 0.01f)).normalized,
                            _newPointsCurve[k][3],
                            (Quaternion.LookRotation(Vector3.right) * BezierMath.CubicGetFirstDerivative(_newPointsCurve[k][0], _newPointsCurve[k][1], _newPointsCurve[k][2], _newPointsCurve[k][3], 0.99f)).normalized
                            );

                        // scaling
                        if (!_doIntersect)   // it's essentially a line
                        // which way the right is from the line
                        {
                            Vector3 _whichWay = Vector3.Cross(_newPointsCurve[k][3] - _newPointsCurve[k][0], Vector3.up).normalized;

                            for (int j = 0; j < _newPointsCurve[k].Length; j++)
                            {
                                _newPointsCurve[k][j] -= _whichWay * amount;
                            }
                        }
                        else
                        {
                            // cache this
                            Vector3 _middleDerivative = BezierMath.CubicGetFirstDerivative(
                                _newPointsCurve[k][0],
                                _newPointsCurve[k][1],
                                _newPointsCurve[k][2],
                                _newPointsCurve[k][3], 0.5f);

                            // which way is the middle point's right
                            Vector3 _curveMiddleRight = (Quaternion.LookRotation(Vector3.right) * _middleDerivative).normalized;
                            // which way is the middle point's left
                            Vector3 _curveMiddleLeft = (Quaternion.LookRotation(Vector3.left) * _middleDerivative).normalized;

                            for (int j = 0; j < _newPointsCurve[k].Length; j++)
                            {
                                Vector3 _scaleDir = (_pivot - _newPointsCurve[k][j]).normalized;

                                // pivot is to the right
                                bool _isPivotToRight = Vector3.Angle(_scaleDir, _curveMiddleRight) <
                                                       Vector3.Angle(_scaleDir, _curveMiddleLeft);

                                // move to position based on pivot direction
                                if (_isPivotToRight)
                                {
                                    _newPointsCurve[k][j] += _scaleDir * amount;
                                }
                                else
                                {
                                    _newPointsCurve[k][j] -= _scaleDir * amount;
                                }
                            }
                        }
                    }
                }

                _newPointsSpline.AddRange(_newPointsCurve);

                _p0 = _p3;
            }

            _shiftedSpline.points    = new Vector3[_newPointsSpline.Count * 3 + 1];
            _shiftedSpline.points[0] = _newPointsSpline[0][0];

            _shiftedSpline.modes    = new BezierControlPointMode[_newPointsSpline.Count + 1];
            _shiftedSpline.modes[0] = BezierControlPointMode.Free;

            for (int i = 0; i < _newPointsSpline.Count; i++)
            {
                _shiftedSpline.modes[i + 1] = BezierControlPointMode.Free;

                for (int k = 1; k <= 3; k++)
                {
                    _shiftedSpline.points[i * 3 + k] = _newPointsSpline[i][k];
                }
            }

            return(_shiftedSpline);
        }