现在的位置: 首页 > 综合 > 正文

线线相交 (Unity代码)

2012年06月04日 ⁄ 综合 ⁄ 共 3410字 ⁄ 字号 评论关闭

 

using UnityEngine;

using System.Collections;

 

public enum LineIntersectType

{

    None = -1,//没有交点

    OnBothExtend = 0,//在两条直线的延长线上

    OnFirstLine = 1,//在第一条直线上 p0-p1

    OnSecondLine = 2,//在第二条直线上 p2-p3

    OnBothLine = 3//在第两条直线上

}

 

public static class ToolsMathUnity

{

 

    /// <summary>

    /// 判断两个浮点数字是否相等

    /// 注意,不能用该函数判断浮点数是否为0.应用IsZero

    /// </summary>

    /// <param name="r1"></param>

    /// <param name="r2"></param>

    /// <param name="tolerance">精度</param>

    /// <returns></returns>

    public static bool IsRealEqual(float r1, float r2, float tolerance)

    {

        if (Mathf.Abs(r2) <= tolerance)

        {

            if (r1 > tolerance)

            {

                return false;

            }

        }

        else

        {

            if (Mathf.Abs(r1 / r2) - 1.0 > tolerance)

            {

                return false;

            }

        }

        return true;

    }

 

    public static bool IsRealEqual(float r1, float r2)

    {

        float tolerance = GlobalVariables._realTolerance;

        if (Mathf.Abs(r2) <= tolerance)

        {

            if (r1 > tolerance)

            {

                return false;

            }

        }

        else

        {

            if (Mathf.Abs(r1 / r2) - 1.0 > tolerance)

            {

                return false;

            }

        }

        return true;

    }

 

    public static bool IsZero(float r, float tolerance)

    {

        return (r <= tolerance && r >= -tolerance) ? true : false;

    }

 

    public static bool IsZero(float r)

    {

        float tolerance = GlobalVariables._realTolerance;

        return (r <= tolerance && r >= -tolerance) ? true : false;

    }

 

     public static LineIntersectType LineXLine(Vector2 p0, Vector2 p1, Vector2 p2, Vector2 p3, ref Vector2 xpt)

    {

        /*

        **  Get the intersection of the line defined by p0 and p1 with the

        **  line defined by p2 and p3.  Sets xpt to the intersection point

        **  if return value is non-negative. 

        **

        **  Returns:

        **       None = Lines are paralell or the points are the same.

        **       OnBothExtend = Intersection is not on either segment.

        **       OnFirstLine = Intersection is on the 1st segment (p0-p1) but not the 2nd.

        **       OnSecondLine = Intersection is on the 2nd segment (p2-p3) but not the 1st.

        **       OnBothLine = Intersection is on both line segments.

        */

        float a1 = p1.y - p0.y;

        float b1 = p0.x - p1.x;

        float c1 = a1 * p0.x + b1 * p0.y;

 

        float a2 = p3.y - p2.y;

        float b2 = p2.x - p3.x;

        float c2 = a2 * p2.x + b2 * p2.y;

 

        float denominator = a1 * b2 - a2 * b1;

        if (IsZero(denominator))

        {

            //paralell

            return LineIntersectType.None;

        }

        else

        {

            int on1 = 1;

            int on2 = 1;

 

            xpt.x = (b2 * c1 - b1 * c2) / denominator;

            xpt.y = (a1 * c2 - a2 * c1) / denominator;

            Vector2 vecMin = Vector2.Min(p0, p1);

            Vector2 vecMax = Vector2.Max(p0, p1);

            on1 = (vecMin.x <= xpt.x && xpt.x <= vecMax.x &&

                vecMin.y <= xpt.y && xpt.y <= vecMax.y) ? 1:0;

            vecMin = Vector2.Min(p2, p3);

            vecMax = Vector2.Max(p2, p3);

            on2 = (vecMin.x <= xpt.x && xpt.x <= vecMax.x &&

                vecMin.y <= xpt.y && xpt.y <= vecMax.y) ? 1 : 0;

            int result = on1 + 2*on2;

            if (0 == result)

            {

                return LineIntersectType.OnBothExtend;

            }

            else if (1 == result)

            {

                return LineIntersectType.OnFirstLine;

            }

            else if (2 == result)

            {

                return LineIntersectType.OnSecondLine;

            }

            else// 3==result

            {

                return LineIntersectType.OnBothLine;

            }

        }

    }

}

 

 

 

public static class GlobalVariables

{

    //private GlobalVariables()

    //{

    //    //防止实例化

    //}

    public const float _realTolerance = 1.0e-11f;

}

 

测试代码:

public class test : MonoBehaviour

{

    void Update()

    {

        if (Input.GetKeyDown(KeyCode.L))

        {

            Vector2 p0 = new Vector2(0, 0);

            Vector2 p1 = new Vector2(1, 0);

            Vector2 p2 = new Vector2(-1, 0.5f);

            Vector2 p3 = new Vector2(-1, 1);

            Vector2 xpt = new Vector2(100, 100);

            LineIntersectType lit = ToolsMathUnity.LineXLine(p0, p1, p2, p3, ref xpt);

            print(lit + ": " + xpt);

        }

    }

}

 

 

 

抱歉!评论已关闭.