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

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;
    }
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,186评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,858评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,620评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,888评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,009评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,149评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,204评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,956评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,385评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,698评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,863评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,544评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,185评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,899评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,141评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,684评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,750评论 2 351

推荐阅读更多精彩内容

  • 今天开始2017第一次代购生涯,感恩信任我下单的顾客! 年前的规划想今年减少代购次数提高生活质量,但是看着那么多顾...
    belivePossible阅读 148评论 0 0
  • 么么哒
    婉林阅读 193评论 0 0
  • 风想要带走花瓣却被拒绝了 记忆拿着放大镜观察着你的气息 灿烂的阳光浪漫了岁月的温情 期盼在门外迟迟不肯敲门我看到了...
    心花园子阅读 229评论 0 3
  • 原文 【43.6】爱因未会先生知行合一之训,与宗贤、惟贤往复辩论,未能决,以问于先生。先生曰:“试举看”。爱曰:“...
    鸿图大展阅读 799评论 0 0