效果
会用到的知识
相交 - 两线段是否相交 - 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