11 2023 档案
摘要:1) 加速原理:排除掉那些不可能发生的碰撞检测,通过减少碰撞检测次数来加速。 2) 如何排除不可能发生的碰撞检测? 比如:现在要检测左上角的物体A和哪些物体发生了碰撞,最简单的方式就是用for循环,把场景中的所有物体都检测一遍,看是否发生了碰撞。 但我们一眼就能看出,其他3个都在角落里,不可能和物体
阅读全文
摘要:效果 //求射线与线段交点 - 直线方程方式 public static bool IsRaySegmentIntersect(Vector2 o, Vector2 dir, Vector2 a, Vector2 b, out Vector2 point) { point = Vector2.zer
阅读全文
摘要:1) 在两侧 2) 与端点重合 3) 在端点之间 判断共线 1) 用pa和pb判断 图1:pa和pb为0度,pa•pb=|pa|*|pb|*cos(0)=|pa|*|pb|; pa×pb=|pa|*|pb|*sin(0)=0 图2:p和端点重合,pa•pb=pa.x*pb.x+pa.y*pb.y=0
阅读全文
摘要:AABBTree加速碰撞检测的原理? 减少碰撞检测的执行次数。怎么减少呢?排除那些不可能发生碰撞的形状间的检测。 最简单粗暴的碰撞检测就是两个for循环嵌套 void ForLoopCheckIntersect() { for (int i = 0; i < m_RectList.Count; ++
阅读全文
摘要:向量点乘ap•ab,即p在线段ab上的投影结果 上图的两种情况(重叠和直角),p在线段ab上的投影结果都是0, 可以用if (ap.sqrMagnitude <= float.Epsilon)判断重叠,如果不重叠则是直角的情况
阅读全文
摘要:直线的点斜公式 y=kx+t, k为直线斜率, t为直线在y轴上的交点; 直线与y轴平行时, k不存在, 方程为x=a, a为常量值; //两直线交点 - 直线点斜式 public static bool IsTwoLineIntersect2(float k1, float t1, float k
阅读全文
摘要:测试代码会用到的基类 using System; using UnityEngine; public abstract class CollideTestBase : MonoBehaviour { [Range(0, 9)] public int m_ApiType = 1; [Range(1,
阅读全文
摘要:效果 //点是否在射线上 public static bool IsPointOnRay(Vector2 o, Vector2 dir, Vector2 p) { var op = p - o; if (Mathf.Approximately(op.sqrMagnitude, 0)) //o和p重叠
阅读全文
摘要://求两直线交点 - 直线方程组方式 public static bool IsTwoLineIntersect(Vector2 A, Vector2 B, Vector2 C, Vector2 D, out Vector2 point) { point = Vector2.zero; /** 1
阅读全文
摘要:1) 点在三角形的边上时 AP=AE+AF (向量加法) 设AE=v*AB, AF=u*AC; 则AP=v*AB+u*AC(二元一次方程,u, v为我们引入的变量) 根据向量三点共线定理可知:u+v=1 2) 点在三角形内时 AE不变, 让AF变短一些, 当用u*AC表示AF时, u的值肯定也比1)
阅读全文
摘要:夹角 1) 夹角一般用180度内的角 2) 如果夹角用于计算sin正弦值(叉乘公式有sin计算),那还要区分向量的先后顺序,即:夹角是顺时针还是逆时针。因为像sin(60)和sin(-60)结果是不一样的。 a到b的夹角:逆时针180度内 b到a的夹角:顺时针180度内 法向量 1) 左法向量,逆时
阅读全文
摘要:如果ABQ三点共线,则OQ=a*OA+b*OB,且a+b=1,其中O表示不在直线AB上的任意点,当然如果原点不在直线AB上,用原点也是成立的。 推导 1) OA+AB=OB => AB=OB-OA 2) OA+AQ=OQ 设AQ=r1*AB, 则OA+r1*AB=OQ, 将1)中的AB代入得: OQ
阅读全文
摘要:圆心为(xc, yc), 半径为r的圆: 两圆方程组联立后,求方程组的解 1) 圆1方程 - 圆2方程: 2) 把x=a*y+b代入圆1方程: 3) 利用一元二次方程求根公式,求出x, y a, b, A, B, C, D1, E1, F1这些都可根据圆心和半径求出,所以x, y也能求出来了。 特殊
阅读全文
摘要:效果 1) 可以显示gjk的每一步执行情况,步骤可以在Inspector上调 2) 步骤的信息包括:原点到最近边的垂线(蓝色线),support点用的方向(右上角的绿色箭头), support点用的shape上的点(在shape上用绿线连接)(原点到最新support点的绿色连线和这跟线是一样长度)
阅读全文
摘要:原理 GJK算法的核心就是闵可夫斯基差,即若两个多边形相交,则它们的闵可夫斯基差必然包括原点。 闵可夫斯基差 用多边形A的所有点,减去多边形B中所有的点得到的一个点集合(是点之间两两相减后得到的集合,而不是做集合的差集)。A–B = {a–b∣a ∈ A, b ∈ B} 在碰撞检测中,不会用到完整的
阅读全文
摘要:原理: 1) 求出向量ao在ab上的投影距离 2) a沿着ab方向移动投影距离就是垂足点的位置 // 获得原点到直线ab的垂点 public static Vector2 GetPerpendicularToOrigin(Vector2 a, Vector2 b) { var ab = b - a;
阅读全文
摘要:所有内角都在(0, 180)的多边形为凸多边形(Convex),否则为凹多边形(Concave)。 顶点顺序逆时针 顶点顺序顺时针 判断依据 凸多边形,邻边向量的叉乘结果均为同号,均为正或均为负; 凹多边形,邻边向量的叉乘结果有正有负; //是否为凸多边形 public static bool Is
阅读全文
摘要:1) 线段ab的法线上投影 点b的投影为|ob2|,线段cd的端点的投影为:|od2|,|oc2| 1-a) |od2|-|ob2|>0,|oc2|-|ob2|<0 1-b) |od2|-|ob2|>0,|oc2|-|ob2|<0 1-c) |od2|-|ob2|>0,|oc2|-|ob2|>0,肯
阅读全文
摘要:已知两直线的方程组,求这两条直线的交点。 把方程转换成矩阵表示的方式 最终表示为: 求逆矩阵: 参考 求两条线段交点zz - 马语者 - 博客园 (cnblogs.com) 线性方程组矩阵解法 (shuxuele.com) 矩阵的行列式 (shuxuele.com)
阅读全文
摘要:1) 以矩形的中心作为原点,建立坐标系。 2) 算出矩形的旋转角度,然后将矩形和圆都旋转回去。 3) 就可以按照普通的圆与矩形是否相交来判断了。 关于圆心旋转后的坐标计算 先求出oc与x轴的夹角,然后根据旋转角度就可计算出c'的坐标 c'.x = r * cos(θ+θ2), c'.y = r *
阅读全文
摘要:直线方程的一般式:ax+by+c=0 点p(x1, y1)到直线的距离: //点到直线的距离(一般式表示直线) public static float PointToLineDistance(Vector2 point, float a, float b, float c) { //直线一般式: a
阅读全文
摘要:ap1×ab与ap2×ab的结果异号,则表示两点在线段两侧;同号则表示在线段同侧 有一个点在线段上或两个点都在线段上,当做在线段同侧处理 //两点是否在线段同侧 public static bool IsTwoPointSameSideOfSegment(Vector2 a, Vector2 b,
阅读全文
摘要:分离轴算法 1) 英文名Separating Axis Theorem,简称SAT 2) 就是利用投影法将多边形所有点都投影到分离轴上,如果在分离轴上的投影不重叠,则两凸多边形不相交。 那将哪个轴作为分离轴呢? 多边形的每条边的法线都分别作为分离轴来计算一次,在所有分离轴上都测试通过,则两个多边形相
阅读全文
摘要:1) 以矩形的中心作为原点,建立坐标系。 2) 通过圆到矩形的最短距离<=r来判断是否相交,几种情况 2-a) bc.x>0&bc.y>0时,圆到矩形的最短距离为|bc|,所以|bc|>r则圆和矩形没有相交 2-b) bc.x<=0&bc.y>0时,圆到矩形的最短距离为|bc.y|即|dc|,把bc
阅读全文
摘要:同侧法 点p在三角形三条边的同侧时,点p在三角形内。可以通过叉乘结果是否都为正或负来判断是否同侧 1) 三角形顶点逆时针时 1-a) ab与ap, bc与bp, ca与cp的夹角均为右手逆时针锐角,sin(锐角)>0,即:叉乘结果>0,此时p在三角形内。 1-b) bc与bp的夹角为0度,sin(0
阅读全文
摘要:1) 如果点在以线段ab为对角线的矩形外, 肯定不在线段上 2) 点p和线段端点a或b重叠时, 在线段上 3) ap和ab的夹角为0度,则点在线段上; 否则不在线段上 叉乘判断 //点是否在线段上 public static bool IsPointOnSegment(Vector2 p, Vect
阅读全文
摘要:一个点在圆内 两个点都在圆内 两个点都在圆外 public static bool IsSegmentCircleIntersect(Vector2 p1, Vector2 p2, Vector2 center, float r) { float sqrR = r * r; //1) 一个点在圆内,
阅读全文
摘要:更推荐这个:点到线段的最近距离, 点与线段的位置关系 - 投影方式 判断依据 点与线段端点组成的三角形,有一个角是钝角或180度时,点在线段外侧 sin(锐角)>0, sin(钝角)>0,无法区分,所以叉乘不行。 cos(锐角)>0, cos(钝角)<0,可以区分,所以用点乘。 1) 在外侧时 a)
阅读全文
摘要:注意:这边的矩形不带旋转 两圆是否相交 //两圆是否相交 public static bool IsTwoCircleIntersect(Vector2 center1, float r1, Vector2 center2, float r2) { var r = r1 + r2; var resu
阅读全文
摘要:点是否在矩形内 //点是否在矩形内 public static bool IsPointInRect(Vector2 p, Vector2 min, Vector2 max) { if (p.x < min.x || p.x > max.x) return false; if (p.y < min.
阅读全文
摘要:把p点的x值代入直线方程算出y,如果和p点的y值相同则在直线上 public static bool IsPointOnLine(Vector2 p, float k, float t) { //y=kx+t float y = k * p.x + t; return Mathf.Approxima
阅读全文
摘要:直线的表示方法 点斜式:y=kx+t, 其中k为直线斜率, t为直线在y轴上的截距 一般式:ax+by+c=0 求直线方程 1) 已知直线上的两个点(x1, y1), (x2, y2),求直线ax+by+c=0 a) 我们先转换成点斜式: b) 斜率可以根据已知的两点计算出来 ,所以a=y2-y1,
阅读全文
摘要:GeoGebra - 风靡世界, 过亿师生沉迷使用的免费数学软件, 函数图像, 几何画板, 3d计算器等 www.desmos.com, 函数图像, 几何, 矩阵, 3d工具等 Symbolab 数学求解器 - 分步计算器, 函数图像, 几何, 数学计算器, 解体步骤等 MathTool公式编辑器
阅读全文