예제 #1
0
    void Update()
    {
        Vector3 v1 = (P2.transform.localPosition - P1.transform.localPosition);
        Vector3 va = (Pb.transform.localPosition - Pa.transform.localPosition);

        if ((v1.magnitude < float.Epsilon) || (va.magnitude < float.Epsilon))
        {
            return;  // will only work with well defined line segments
        }
        Vector3 va1 = P1.transform.localPosition - Pa.transform.localPosition;
        Vector3 v1n = v1.normalized;
        Vector3 van = va.normalized;
        float   d   = Vector3.Dot(v1n, van);

        bool almostParallel = (1f - Mathf.Abs(d) < float.Epsilon);

        float d1 = 0f, da = 0f;

        if (!almostParallel)  // two lines are not parallel
        {
            float dot1A1 = Vector3.Dot(v1n, va1);
            float dotAA1 = Vector3.Dot(van, va1);

            d1 = (-dot1A1 + d * dotAA1) / (1 - (d * d));
            da = (dotAA1 - d * dot1A1) / (1 - (d * d));

            d1 /= v1.magnitude;
            da /= va.magnitude;

            Pd_1.transform.localPosition = P1.transform.localPosition + d1 * v1;
            Pd_a.transform.localPosition = Pa.transform.localPosition + da * va;
            float dist = (Pd_1.transform.localPosition - Pd_a.transform.localPosition).magnitude;
            Debug.Log("d1=" + d1 + " da=" + da + " Distance=" + dist);
        }
        else
        {
            Debug.Log("Line segments are parallel, special case not handled");
        }

        #region  For visualizing the line
        ShowV1.VectorFromTo(P1.transform.localPosition, P2.transform.localPosition);
        ShowVa.VectorFromTo(Pa.transform.localPosition, Pb.transform.localPosition);
        ShowVp.DrawVector = (!almostParallel);

        Pd_1.SetActive(!almostParallel);
        Pd_a.SetActive(!almostParallel);

        if (!almostParallel)  // two lines are not parallel
        {
            bool  d0Out = (d1 < 0f) || (d1 > 1.0f);
            bool  daOut = (da < 0f) || (da > 1.0f);
            Color c     = Pd_1.GetComponent <Renderer>().material.color;

            c.a = d0Out ? 1.0f : 0.25f;
            Pd_1.GetComponent <Renderer>().material.color = c;
            c.a = daOut ? 1.0f : 0.25f;
            Pd_a.GetComponent <Renderer>().material.color = c;

            // ShowVp.VectorColor = c;
            ShowVp.VectorFromTo(Pd_1.transform.localPosition, Pd_a.transform.localPosition);

            float s = ShowVp.Magnitude * kScaleFactor;
            Pd_1.transform.localScale = new Vector3(s, s, s);
            Pd_a.transform.localScale = new Vector3(s, s, s);
        }
        #endregion
    }
예제 #2
0
    void Update()
    {
        Vector3 v1 = (P2.transform.localPosition - P1.transform.localPosition);
        Vector3 va = (Pb.transform.localPosition - Pa.transform.localPosition);

        if ((v1.magnitude < float.Epsilon) || (va.magnitude < float.Epsilon))
        {
            return;  // will only work with well defined line segments
        }
        Vector3 vb  = P1.transform.localPosition - Pa.transform.localPosition;
        Vector3 v1n = v1.normalized;
        Vector3 van = va.normalized;
        float   d   = Vector3.Dot(v1n, van);

        bool almostParallel = (1f - Mathf.Abs(d) < float.Epsilon);

        float d1 = 0f, da = 0f;
        bool  d0Out = true;
        bool  daOut = true;

        if (!almostParallel)  // two lines are not parallel
        {
            float dotAB = Vector3.Dot(van, vb);
            float dot1B = Vector3.Dot(v1n, vb);

            d1 = (-dot1B + d * dotAB) / (1 - (d * d));
            da = (dotAB - d * dot1B) / (1 - (d * d));

            d1 /= v1.magnitude;
            da /= va.magnitude;

            Pd_1.transform.localPosition = P1.transform.localPosition + d1 * v1;
            Pd_a.transform.localPosition = Pa.transform.localPosition + da * va;
            float dist = (Pd_1.transform.localPosition - Pd_a.transform.localPosition).magnitude;
            Debug.Log("d1=" + d1 + " da=" + da + " Distance=" + dist);

            d0Out = (d1 < 0f) || (d1 > 1.0f);
            daOut = (da < 0f) || (da > 1.0f);
        }

        if (almostParallel || d0Out || daOut)
        {
            // Debug.Log("Line segments are parallel, special case not handled");
            // Compute end pt to line
            Vector3 pon1a, pon1b, pona1, pona2;
            bool    inside = false;

            // distance from Line-P1P2 to points Pa, and Pb
            d1 = -1f;
            float d1a = LineToPoint(P1.transform.localPosition, P2.transform.localPosition, Pa.transform.localPosition, out pon1a, out inside);
            if (inside)
            {
                Pd_1.transform.localPosition = pon1a;
                Pd_a.transform.localPosition = Pa.transform.localPosition;
                d1 = d1a / v1.magnitude;
                da = 0f;
            }
            else
            {
                float d1b = LineToPoint(P1.transform.localPosition, P2.transform.localPosition, Pb.transform.localPosition, out pon1b, out inside);
                if (inside)
                {
                    Pd_1.transform.localPosition = pon1b;
                    Pd_a.transform.localPosition = Pb.transform.localPosition;
                    d1 = d1b / v1.magnitude;
                    da = 1f;
                }
                else
                {
                    if (d1a < d1b)
                    {
                        Pd_1.transform.localPosition = pon1a;
                        d1 = d1a / v1.magnitude;
                    }
                    else
                    {
                        Pd_1.transform.localPosition = pon1b;
                        d1 = d1b / v1.magnitude;
                    }

                    // distance from Line-PaPb to points P1 and P2
                    float da1 = LineToPoint(Pa.transform.localPosition, Pb.transform.localPosition, P1.transform.localPosition, out pona1, out inside);
                    if (inside)
                    {
                        Pd_a.transform.localPosition = pona1;
                        Pd_1.transform.localPosition = P1.transform.localPosition;
                        da = da1 / va.magnitude;
                        d1 = 0f;
                    }
                    else
                    {
                        float da2 = LineToPoint(Pa.transform.localPosition, Pb.transform.localPosition, P2.transform.localPosition, out pona2, out inside);
                        if (inside)
                        {
                            Pd_a.transform.localPosition = pona2;
                            Pd_1.transform.localPosition = P2.transform.localPosition;
                            da = da2 / va.magnitude;
                            d1 = 1f;
                        }
                        else
                        {
                            if (da1 < da2)
                            {
                                da = da1 / va.magnitude;
                                Pd_a.transform.localPosition = pona1;
                            }
                            else
                            {
                                da = da2 / va.magnitude;
                                Pd_a.transform.localPosition = pona2;
                            }
                        }
                    }
                }
            }
            d0Out = (d1 < 0f) || (d1 > 1.0f);
            daOut = (da < 0f) || (da > 1.0f);
        }

        #region  For visualizing the line
        ShowV1.VectorFromTo(P1.transform.localPosition, P2.transform.localPosition);
        ShowVa.VectorFromTo(Pa.transform.localPosition, Pb.transform.localPosition);
        // ShowVp.DrawVector = (!almostParallel);
        // Pd_1.SetActive(!almostParallel);
        // Pd_a.SetActive(!almostParallel);



        Color c = Pd_1.GetComponent <Renderer>().material.color;

        c.a = d0Out ? 1.0f : 0.25f;
        Pd_1.GetComponent <Renderer>().material.color = c;
        c.a = daOut ? 1.0f : 0.25f;
        Pd_a.GetComponent <Renderer>().material.color = c;

        // ShowVp.VectorColor = c;
        ShowVp.VectorFromTo(Pd_1.transform.localPosition, Pd_a.transform.localPosition);

        float s = ShowVp.Magnitude * kScaleFactor;
        Pd_1.transform.localScale = new Vector3(s, s, s);
        Pd_a.transform.localScale = new Vector3(s, s, s);
        #endregion
    }