計算機幾何相關算法

1.點到直線的距離
鏈接:https://www.jianshu.com/p/8ba826e6208a

   private static float distancePoint2Line(Vector3 point, Vector3 linePoint1, Vector3 linePoint2)
    {
        float cos = Vector3.Dot(point - linePoint1, (linePoint1 - linePoint2).normalized);
        return Mathf.Sqrt((point - linePoint1).sqrMagnitude - cos * cos);
    }

2.點到線段的距離

    /// <summary>
    /// 點到線段的距離
    /// </summary>
    /// <param name="point">點</param>
    /// <param name="start">起點</param>
    /// <param name="end">終點</param>
    /// <returns>距離,如果不在線段範圍內,返回-1 </returns>
    public static float DistancePoint2Segment(Vector3 point, Vector3 start, Vector3 end)
    {
        Vector3 line = end - start;
        //獲取點point在直線line上的投影位置
        Vector3 projectPoint = start + Vector3.Project(point - start, line);
        //計算投影點是否在線段外
        //如果與line方向不一致,表示在線段外部
        if (Vector3.Dot((projectPoint - start).normalized, line.normalized) < 0) return float.MaxValue; 
        //如果長度超過線段的長度,表示在選定外部
        if (Vector3.Distance(start, end) < Vector3.Distance(projectPoint, start)) return float.MaxValue;
        return Vector3.Distance(projectPoint, point);
    }

3.線段與線段是否相交
鏈接:丟失(找到了再補上)

    /// <summary>
    /// 兩線是否相交
    /// </summary>
    /// <param name="s1">線段1 起點</param>
    /// <param name="e1">線段1 終點</param>
    /// <param name="s2">線段2 起點</param>
    /// <param name="e2">線段2 終點</param>
    /// <returns></returns>
    public static bool IsIntersect(Vector3 s1, Vector3 e1, Vector3 s2, Vector3 e2)
    {
        //排斥
        if (Mathf.Max(s1.x, e1.x) < Mathf.Min(s2.x, e2.x))
            return false;
        if (Mathf.Min(s1.x, e1.x) > Mathf.Max(s2.x, e2.x))
            return false;
        if (Mathf.Max(s1.y, e1.y) < Mathf.Min(s2.y, e2.y))
            return false;
        if (Mathf.Min(s1.y, e2.z) > Mathf.Max(s2.y, e2.y))
            return false;

        //跨立
        float c1 = Corss(s1, e1, s2);
        float c2 = Corss(s1, e2, e1);
        float c3 = Corss(s2, e2, s1);
        float c4 = Corss(s2, e1, e2);
        if (c1 * c2 > 0 && c3 * c4 > 0)
            return true;
        return false;
    }
    /// <summary>
    /// 差積
    /// </summary>
    /// <param name="p1"></param>
    /// <param name="p2"></param>
    /// <param name="q1"></param>
    /// <returns></returns>
    private static float Corss(Vector3 p1, Vector3 p2, Vector3 q1)
    {
        //將點在一個平面內
        p1.y = p2.y = q1.y = 0;
        Vector3 v1 = p2 - p1;
        Vector3 v2 = q1 - p1;
        float corss = v1.x * v2.y - v1.y * v2.x;
        if (corss < 0) return -1;
        return 1;
    }

4.點是否在任意多邊形內
鏈接:https://www.cnblogs.com/grassgarden/p/9250946.html

    /// <summary>
    /// 是否在多邊形內部
    /// </summary>
    /// <param name="point"></param>
    /// <param name="polygons"></param>
    /// <returns></returns>
    public static bool IsInPolygon(Vector3 point, Vector3[] polygons)
    {
        int nCross = 0;
        Vector3 center = point;
        //判斷中點是否在多邊形內部 
        for (int i = 0; i < polygons.Length; i++)
        {
            Vector3 next = polygons[(i + 1) % polygons.Length];
            if (center.y < Mathf.Min(polygons[i].y, next.y)) continue;
            if (center.y > Mathf.Max(polygons[i].y, next.y)) continue;
            float x = (center.y - polygons[i].y) * (next.x - polygons[i].x) / (next.y - polygons[i].y) + polygons[i].x;
            if (x > center.x)
                ++nCross;
        }
        //==1 表示終點在內部
        if (nCross % 2 == 1)
            return false;
        return true;
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章