1 几何学中用到的一些方法

2017-12-21  本文已影响15人  _谭小坤

1.点到直线的距离

    /// <summary>
    /// 某个点到线段上的距离
    /// </summary>
    /// <param name="point"></param>
    /// <param name="linePointA"></param>
    /// <param name="linePointB"></param>
    /// <returns></returns>
    public static double DisPoint2Line(Vector2 point, Vector2 linePointA, Vector2 linePointB)
    {
        double dis = 0;
        if (linePointA.x == linePointB.x)
        {
            dis = Math.Abs(point.x - linePointA.x);
            return dis;
        }
        double lineK = (linePointB.y - linePointA.y) / (linePointB.x - linePointA.x);
        double lineC = (linePointB.x * linePointA.y - linePointA.x * linePointB.y) / (linePointB.x - linePointA.x);
        dis = Math.Abs(lineK * point.x - point.y + lineC) / (Math.Sqrt(lineK * lineK + 1));
        return dis;
    }

2.获取点在直线上的垂直投影点

 /// <summary>
    /// 获得某点在一个直线上的投影
    /// </summary>
    /// <param name="point"></param>
    /// <param name="linePoint1"></param>
    /// <param name="linePoint2"></param>
    /// <returns></returns>
    public static Vector3 GetProjectivePoint(Vector3 point, Vector3 linePoint1, Vector3 linePoint2)
    {
        Vector3 target;

        Vector3 lineDir = (linePoint2 - linePoint1).normalized;

        Vector3 projectiveDir = Quaternion.Euler(0, 90, 0) * lineDir;

        Vector3 point2 = point + projectiveDir;

        target = GetIntersectionByPoints(point, point2, linePoint1, linePoint2);

        return target;
    }

3.获取两直线交点

                                区分直线和线段
    /// <summary>
    /// 得到两直线交点的方法
    /// </summary>
    /// <param name="lineFirstStart"> 第一条线的一个点 </param>
    /// <param name="lineFirstEnd"> 第一条线的另外一个点 </param>
    /// <param name="lineSecondStart"> 第二条线的一个点 </param>
    /// <param name="lineSecondEnd"> 第二条线的另外一个点 </param>
    /// <returns></returns>
    public static Vector3 GetIntersectionByPoints(Vector3 lineFirstStart, Vector3 lineFirstEnd, Vector3 lineSecondStart,
        Vector3 lineSecondEnd)
    {
        float y = lineFirstStart.y;
        double a = 0, b = 0;
        int state = 0;
        if (lineFirstStart.x != lineFirstEnd.x)
        {
            a = (lineFirstEnd.z - lineFirstStart.z) / (lineFirstEnd.x - lineFirstStart.x);
            state |= 1;
        }
        if (lineSecondStart.x != lineSecondEnd.x)
        {
            b = (lineSecondEnd.z - lineSecondStart.z) / (lineSecondEnd.x - lineSecondStart.x);
            state |= 2;
        }
        switch (state)
        {
            case 0:
                {
                    if (lineFirstStart.x == lineSecondStart.x)
                    {
                        return Vector3.zero;
                    }
                    else
                    {
                        return Vector3.zero;
                    }
                }
            case 1:
                {
                    double x = lineSecondStart.x;
                    double z = (lineFirstStart.x - x) * (-a) + lineFirstStart.z;
                    return new Vector3((float)x, y, (float)z);
                }
            case 2:
                {
                    double x = lineFirstStart.x;
                    double z = (lineSecondStart.x - x) * (-b) + lineSecondStart.z;
                    return new Vector3((float)x, y, (float)z);
                }
            case 3:
                {
                    if (Mathf.Abs((float)(a - b)) < 0.0001)
                    {
                        return Vector3.zero;
                    }
                    double x = (a * lineFirstStart.x - b * lineSecondStart.x - lineFirstStart.z + lineSecondStart.z) / (a - b);
                    double z = a * x - a * lineFirstStart.x + lineFirstStart.z;
                    return new Vector3((float)x, y, (float)z);
                }
        }
        return Vector3.zero;
    }

4.获取线段与直线的交点

   public static Vector3? GetIntersectonBetweenLineAndSegment(Vector3 linePointA, Vector3 linePointB, Vector3 segmentPointA, Vector3 segmentPointB)
    {
        // 先求两直线交点 再判断交点是否在线段上
        Vector3? intersection = GetIntersectionByPoints(linePointA, linePointB, segmentPointA, segmentPointB);
        if (intersection != Vector3.zero)
        {
            //if (CheckPointInSegement(segmentPointA, segmentPointB, intersection.Value))
            //{
            //    Debug.Log(string.Format("segmentStart: {0} segmentEnd: {1} intersection:{2}", segmentPointA.ToString("f4"), segmentPointB.ToString("f4"), intersection.Value.ToString("f4")));
            //    return intersection;
            //}

            if (IsPointInsideSegment(new List<Vector2>() { segmentPointA.ToVector2XZ(), segmentPointB.ToVector2XZ() }, intersection.Value.ToVector2XZ()))
            {
                //Debug.Log(string.Format("segmentStart: {0} segmentEnd: {1} intersection:{2}", segmentPointA.ToString("f4"), segmentPointB.ToString("f4"), intersection.Value.ToString("f4")));
                return intersection;
            }
        }
        return null;
    }

5.点是否在线段上(含两端点)

 public static bool IsPointInsideSegment(IEnumerable<Vector2> segment, Vector2 point)
    {
        // 线段顶点数目必须等于2
        if (segment.Count() != 2)
        {
            Debug.LogError(string.Format("Segment must have only 2 vertex, current segment have {0} vertex!", segment.Count()));
            return false;
        }

        if (Mathf.Approximately((point - segment.First()).magnitude + (point - segment.Last()).magnitude, (segment.First() - segment.Last()).magnitude))
            return true;
        else
            return false;
    }

6.检测某个点是否在线段上

  public static bool CheckPointInSegement(Vector2 lineStart, Vector2 lineEnd, Vector2 point)
    {
        // 误差范围

        if (DisPoint2Line(point, lineStart, lineEnd) >= 0.002f)
        {
            return false;
        }

        Vector2 p2Start = (lineStart - point).normalized;
        Vector2 p2End = (lineEnd - point).normalized;

        if (Vector2.Dot(p2End, p2Start) <= 0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
  1. 判断两线段是否相交
 //firstlineStart, firstlineEnd为一条线段两端点 SecondlineStart, SecondlineEnd为另一条线段的两端点 相交返回true, 不相交返回false  
    public static bool CheckTwoSegmentCrose(Vector2 firstlineStart, Vector2 firstlineEnd, Vector2 SecondlineStart, Vector2 SecondlineEnd)
    {
        if (max(firstlineStart.x, firstlineEnd.x) < min(SecondlineStart.x, SecondlineEnd.x))
        {
            return false;
        }
        if (max(firstlineStart.y, firstlineEnd.y) < min(SecondlineStart.y, SecondlineEnd.y))
        {
            return false;
        }
        if (max(SecondlineStart.x, SecondlineEnd.x) < min(firstlineStart.x, firstlineEnd.x))
        {
            return false;
        }
        if (max(SecondlineStart.y, SecondlineEnd.y) < min(firstlineStart.y, firstlineEnd.y))
        {
            return false;
        }
        if (mult(SecondlineStart, firstlineEnd, firstlineStart) * mult(firstlineEnd, SecondlineEnd, firstlineStart) < 0)
        {
            return false;
        }
        if (mult(firstlineStart, SecondlineEnd, SecondlineStart) * mult(SecondlineEnd, firstlineEnd, SecondlineStart) < 0)
        {
            return false;
        }
        return true;
    }

  1. 判断两个线段是否端点相连
// 判断两条线段是否相连
    public static bool CheckTwoSegmentSharePoint(Vector2 firstlineStart, Vector2 firstlineEnd, Vector2 SecondlineStart, Vector2 SecondlineEnd)
    {
        return firstlineStart == SecondlineStart || firstlineStart == SecondlineEnd || firstlineEnd == SecondlineStart || firstlineEnd == SecondlineEnd;
    }

9.判断两线段是否共线

    /// <summary>
    /// 判断两个线段是否共线
    /// </summary>
    /// <param name="firstWall"></param>
    /// <param name="secondWall"></param>
    /// <returns></returns>
    public static bool CheckTwoSegmentShareLine(Vector2 lineAStart, Vector2 lineAEnd, Vector2 lineBStart, Vector2 lineBEnd)
    {
        Vector2 firstWallDir = (lineAEnd - lineAStart).normalized;
        Vector2 secondWallDir = (lineBEnd - lineBStart).normalized;
        //Debug.Log(string.Format("aStart:{2] end:{3} bStart:{4} end:{5} firstWallDir:{0} secondWallDir:{1}",
        //    firstWallDir.ToString("f4"), secondWallDir.ToString("f4"), lineAStart.ToString("f4"), lineAEnd.ToString("f4"), lineBStart.ToString("f4"), lineBEnd.ToString("f4")));
        //if (DisPoint2Line(lineAStart, lineBStart, lineBEnd)>0.001f|| DisPoint2Line(lineAEnd, lineBStart, lineBEnd)>0.001f)
        //    return false;
        //// 没有加检测
        //return Vector3.Distance(firstWallDir, secondWallDir) < 0.001f || Vector3.Distance(firstWallDir, -secondWallDir) < 0.001f;

        return (CheckThreePointShareLine(lineAStart, lineAEnd, lineBStart)) && (CheckThreePointShareLine(lineAStart, lineAEnd, lineBEnd));
    }

10.判断三点是否共线

   /// <summary>
    /// 判断三点是否共线
    /// </summary>
    /// <param name="lineA"></param>
    /// <param name="lineB"></param>
    /// <param name="lineC"></param>
    /// <returns></returns>
    public static bool CheckThreePointShareLine(Vector2 lineA, Vector2 lineB, Vector2 lineC)
    {
        if (lineA != lineB && lineB != lineC && lineC != lineA)//这里修改了一下
        {
            Vector2 a2b = (lineB - lineA).normalized;
            Vector2 c2b = (lineB - lineC).normalized;

            //Debug.Log(a2b.ToString("f6") + "  " + c2b.ToString("f6"));

            return (a2b == c2b) || (a2b == -c2b);
        }
        else
        {
            return true;
        }
    }

11.判断两条线段是否共线且存在重叠

 /// <summary>
    /// 判断两条选段是否有重叠
    /// </summary>
    /// <param name="lineAStart"></param>
    /// <param name="lineAEnd"></param>
    /// <param name="lineBStart"></param>
    /// <param name="lineBEnd"></param>
    /// <returns></returns>
    public static bool CheckTwoSegmentOverlap(Vector2 lineAStart, Vector2 lineAEnd, Vector2 lineBStart, Vector2 lineBEnd)
    {
        if (CheckTwoSegmentShareLine(lineAStart, lineAEnd, lineBStart, lineBEnd))
        {
            //Debug.Log("ShareLine");
            Vector2 s2s = (lineBStart - lineAStart).normalized;
            Vector2 s2e = (lineBEnd - lineAStart).normalized;
            Vector2 e2s = (lineBStart - lineAEnd).normalized;
            Vector2 e2e = (lineBEnd - lineAEnd).normalized;

            if (s2s == s2e && s2e == e2s && e2s == e2e)
            {
                return false;
            }

            return true;
        }
        return false;
    }
上一篇 下一篇

猜你喜欢

热点阅读