游戏编程精粹学习 - 线段与非无限平面相交检测
2017-09-02 20:12
323 查看
参考自《游戏编程精粹1》多边形相交部分,用该方法除了知道是否相交以外还可以得到相交点,从而用于其他判断。
原文用到了平面方程Ax+By+Cz+D=0,通过三角形求出平面,然后用方程求出线段交点
这里直接使用平面,然后再拿相交点和平面所占区域进行判断,以下为Unity中的实现代码:
原文用到了平面方程Ax+By+Cz+D=0,通过三角形求出平面,然后用方程求出线段交点
这里直接使用平面,然后再拿相交点和平面所占区域进行判断,以下为Unity中的实现代码:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Practice : MonoBehaviour { public Transform p0; public Transform p1; public Transform planeLocation; public float size = 5f; void OnDrawGizmos() { if (p0 == null) return; if (p1 == null) return; if (planeLocation == null) return; var cacheColor = Gizmos.color; var r = GetIntersectPoint(planeLocation.forward, planeLocation.position, p0.position, p1.position); if (r != null) { var matrix = Matrix4x4.TRS(planeLocation.position, Quaternion.FromToRotation(planeLocation.forward, Vector3.forward), planeLocation.localScale); var temp = matrix.inverse.MultiplyPoint(r.Value); var sizeHalf = size * 0.5f; if (temp.x <= sizeHalf && temp.x >= -sizeHalf && temp.y <= sizeHalf && temp.y >= -sizeHalf) { Gizmos.color = Color.red; } Gizmos.DrawWireSphere(r.Value, 0.1f); } var cacheMatrix = Gizmos.matrix; Gizmos.matrix = Matrix4x4.TRS(planeLocation.position, planeLocation.rotation, Vector3.one); Gizmos.DrawWireCube(Vector3.zero, new Vector3(size, size, 0f)); Gizmos.matrix = cacheMatrix; Gizmos.color = cacheColor; } /// <summary> /// 检测相交点的原始函数,没有相交点返回空,否则返回相交点。 /// </summary> /// <param name="planeNormal">平面的法线朝向</param> /// <param name="planePosition">平面的位置</param> /// <param name="p0">线段点0</param> /// <param name="p1">线段点1</param> Vector3? GetIntersectPoint(Vector3 planeNormal, Vector3 planePosition, Vector3 p0, Vector3 p1) { var sign1 = Mathf.Sign(Vector3.Dot(planeNormal, (planePosition - p0).normalized)); var sign2 = Mathf.Sign(Vector3.Dot(planeNormal, (planePosition - p1).normalized)); if (Mathf.Approximately(sign1, sign2)) return null;//同侧异侧. var a = planeNormal.x; var b = planeNormal.y; var c = planeNormal.z; var d = -a * planePosition.x - b * planePosition.y - c * planePosition.z; var i0 = a * p0.x + b * p0.y + c * p0.z; var i1 = a * p1.x + b * p1.y + c * p1.z; var final_t = -(i1 + d) / (i0 - i1); var finalPoint = new Vector3() { x = p0.x * final_t + p1.x * (1 - final_t), y = p0.y * final_t + p1.y * (1 - final_t), z = p0.z * final_t + p1.z * (1 - final_t), }; return finalPoint; } }
相关文章推荐
- 游戏编程精粹学习 - 路径/线段平滑
- 游戏编程精粹学习 - 使用Bloom过滤来提高计算性能(BloomFilter)
- 游戏手柄(JoyStick)编程学习笔记(1)
- 开始利用CSDN做学习笔记,从windows 游戏编程大师技巧和3D游戏编程大师开始
- java界面编程学习笔记:打地鼠游戏
- DirectX游戏编程入门——第二部分(游戏编程工具箱) ——精灵编程之碰撞检测
- 向量几何在游戏编程中的使用3-2-D边界碰撞检测
- DirectX 11游戏编程学习笔记之4: 第3章Transformations(变换)
- 关于如何判断在平面上的两条线段是否相交
- 我想学习游戏编程
- DirectX 11游戏编程学习笔记之3: 第2章Matrix Algebra(矩阵代数)
- DirectX 11游戏编程学习笔记之6: 第5章The Rendering Pipeline(渲染管线)
- 通过游戏学习编程
- cocos2d-x 3.0游戏实例学习笔记 《跑酷》第七步--物理碰撞检测(1)
- DirectX 11游戏编程学习笔记2: 文章1章Vector Algebra(向量代数)
- 平面内两条线段的位置关系(相交)判定与交点求解
- XNA游戏编程 学习备忘
- 射线与平面的相交检测(Ray-Plane intersection test)
- 如何把孩子玩游戏动力转换为学习动力,或是编程入门引导?
- 游戏核心算法编程内幕学习(一):游戏发展历史