首页 > 其他分享 >交点 - 求两线段交点2

交点 - 求两线段交点2

时间:2023-11-23 22:55:21浏览次数:34  
标签:Vector2 两线 && 交点 position Gizmos public

效果

 

会用到的知识

相交 - 两线段是否相交 - yanghui01 - 博客园 (cnblogs.com)

线性代数 - 已知点求直线方程 - yanghui01 - 博客园 (cnblogs.com)

交点 - 两直线交点 - yanghui01 - 博客园 (cnblogs.com)

 

//两线段是否相交
public static bool IsTwoSegmentIntersect2(Vector2 a, Vector2 b, Vector2 c, Vector2 d, out Vector2 point)
{
    //先判断是否相交
    if (Shape2DHelper.IsLineSegmentIntersect(a, b, c, d))
    {
        //因为已经确定线段相交, 那么线段所在直线的交点就是线段交点
        //已知两点求点斜式: k=-(b.y-a.y)/(a.x-b.x), t=-(a.y*b.x-a.x*b.y)/(a.x-b.x)
        float k1 = -(b.y - a.y) / (a.x - b.x);
        float t1 = -(a.y * b.x - a.x * b.y) / (a.x - b.x);

        float k2 = -(d.y - c.y) / (c.x - d.x);
        float t2 = -(c.y * d.x - c.x * d.y) / (c.x - d.x);

        float x = (t1 - t2) / (k2 - k1);
        float y = k1 * x + t1;
        point = new Vector2(x, y);
        return true;
    }

    point = Vector2.zero;
    return false;
}

该函数比IsTwoSegmentIntersect慢,主要涉及5次除法

 

测试代码

using System;
using UnityEditor;
using UnityEngine;

public class SegmentTest : MonoBehaviour
{
    //线段1的顶点A, B
    public Transform m_A; 
    public Transform m_B;

    //线段2的顶点C, D
    public Transform m_C;
    public Transform m_D;

    public Vector2 m_Point; //显示交点用

    public int m_ApiType = 1;
    [Range(1, 3999999)]
    public int m_InvokeCount = 1; //用于测试大批量调用时的性能
    public bool m_AutoIcrApiType = false; //自动调用每一个函数, 看看各个函数的执行耗时

    private bool m_IsIntersect;
    private Vector3 m_CubeSize = new Vector3(0.02f, 0.02f, 0.01f);

    void Update()
    {
        m_IsIntersect = false;
        m_Point = Vector2.zero;
        if (m_A && m_B && m_C && m_D)
        {
            var t1 = DateTime.Now;
            switch (m_ApiType)
            {
            case 1:
                for (int i = 0; i < m_InvokeCount; ++i)
                    m_IsIntersect = Shape2DHelper.IsTwoSegmentIntersect(m_A.position, m_B.position, m_C.position, m_D.position, out m_Point);
                break;

            case 2:
                for (int i = 0; i < m_InvokeCount; ++i)
                    m_IsIntersect = Shape2DHelper.IsTwoSegmentIntersect2(m_A.position, m_B.position, m_C.position, m_D.position, out m_Point);
                break;
            }

            if (m_InvokeCount > 1 && m_AutoIcrApiType)
            {
                if (m_ApiType < 3)
                    m_ApiType++;
            }

            if (m_InvokeCount > 1)
            {
                var t2 = DateTime.Now;
                var dur = t2 - t1;
                if (dur.TotalMilliseconds >= 100)
                    Debug.Log($"totalMs:{dur.TotalMilliseconds}");
            }
        }
    }

    private void OnDrawGizmos()
    {
        if (m_A && m_B && m_C && m_D)
        {
            if (m_IsIntersect)
            {
                Gizmos.color = Color.red;
                Gizmos.DrawLine(m_A.position, m_B.position);
                Gizmos.DrawLine(m_C.position, m_D.position);

                Gizmos.color = Color.green;
                float handleSize = HandleUtility.GetHandleSize(m_Point) * 0.1f;
                m_CubeSize.Set(handleSize, handleSize, 0.01f);
                Gizmos.DrawCube(m_Point, m_CubeSize);

                Gizmos.color = Color.white;
            }
            else
            {
                Gizmos.DrawLine(m_A.position, m_B.position);
                Gizmos.DrawLine(m_C.position, m_D.position);
            }
        }
    }

}

 

标签:Vector2,两线,&&,交点,position,Gizmos,public
From: https://www.cnblogs.com/sailJs/p/17852329.html

相关文章

  • 直线是否相交以及交点
    直线的点斜公式y=kx+b,k为直线斜率,b为直线在y轴上的交点 两条直线平行则不相交, 否则就相交publicstaticboolIsLineIntersect(floatk1,floatb1,floatk2,floatb2,outVector2intersectPoint){intersectPoint=Vector2.zero;if(Mathf.Approximat......
  • NOI2021 路径交点
    洛谷传送门LOJ传送门两条路径的交点数量只和起点数量有关。容易发现是终点排列的逆序对数的奇偶性。求一个\(f_{i,j}\)表示从第\(1\)层的第\(i\)个点到第\(k\)层的第\(j\)个点的路径数量,对这个矩阵求行列式即可。对于相交的路径数不用考虑,因为总存在和它对应的一条......
  • 使用CGAL计算直线和圆的交点
     #include<vector>#include<iostream>#include<CGAL/Exact_predicates_exact_constructions_kernel.h>#include<CGAL/Ray_2.h>#include<CGAL/Polygon_2.h>#include<CGAL/intersections.h>typedefCGAL::Exact_predicates_e......
  • 谈谈"求线段交点"的几种算法(js实现,完整版)
    谈谈"求线段交点"的几种算法(js实现,完整版)"求线段交点"是一种非常基础的几何计算,在很多游戏中都会被使用到. 下面我就现学现卖的把最近才学会的一些"求线段交点"的算法说一说,希望对大家有所帮助. 本文讲的内容都很初级,主要是面向和我一样的初学者,所以请各位算法帝......
  • AutoCAD VBNET 曲线求交点
    曲线求取点,利用几何库<CommandMethod(NameOf(TT_PolyLineCrossCheck))>PublicSubTT_PolyLineCrossCheck()DimdocAsDocument=Application.DocumentManager.MdiActiveDocumentDimdbAsDatabase=doc.DatabaseDimedAsEditor=doc.Editor'......
  • P2789 直线交点数
    Link首先很容易想到地一点就是平行的直线可以划分为一组,他们的每一条线是“相同的”,这样我们第一件事情就是计算可以有多少划分方式。然后该怎样计算最后每一种情况是多少个交点呢?我们考虑一下,每一条直线都会和不平行的直线产生交点,这样就可以计算每一条直线地贡献了。\(\frac......
  • 直线求交点公式及代码
    直线求交点题目链接:https://www.acwing.com/problem/content/3693/1.直线的表示直线标准形式:Ax+By=C设直线经过的两个点为(x1,y1),(x2,y2)则:A=y2-y1B=x1-x2C=A*x1+B*y12.两条直线求交点设两条直线方程为:A1x+B1y=C1A2x+B2y=C2特殊情况:......
  • [NOI2021] 路径交点 题解
    [NOI2021]路径交点题解题意给定一张\(k\)层的有向图,第\(i\)层有\(n_i\)​个顶点,第​\(1\)层与第\(k\)​层顶点数相同。对于第​​\(j\)\((1\leqj<k)\)层的顶点,只会连向第\(j+1\)层的顶点。没有边连向第\(1\)层的顶点,第\(k\)层的顶点不会向其他顶点连边......
  • 计算几何之两条线段的交点
    1.概述可以通过线段的跨立实验[1]判断两条线段是否相交,但是想要进一步求它们的交点还是比较麻烦。[2]给出的方法更加简单,其原理来自求三维空间两条线段的交点[3]。为了更好的理解,本文将详细介绍二维空间两条线段的交点求解过程。2.两条线段交点求解过程给定两条线段\(\overl......
  • MAXWELL两线圈静磁场仿真
    【1】初始界面 【2】选中MAXWELL3D仿真 默认为静磁场,刚好是需要的,无需改动  【3】放置原边线圈 主要需要修改的参数 PolygonSegments:Numberofcross_sectionsegments,0forcircle。截面多边形线段数,0表示圆。PolygonRadius:outerradiusofcross-sectonpoly......