algorithm - 胶囊 - 射线(线段)相交,2D
问题描述
我正在我的游戏中编写 C++ 碰撞检测并试图提出一个算法:我有一个定义了两个中心点(C1、C2)、长度和半径的胶囊。然后我有一个用两个点(R1,R2)定义的射线。我已经知道它们是相交的。我只需要找到胶囊(H1-H2)中包含的光线的内部部分。提前感谢所有帮助。
解决方案
首先我们看一张图供参考:
计算过程H1
如下H2
:
R
计算射线和线段之间的交点(如果有)P1P2
。我们只对位于内部的交叉点感兴趣P1P2
。同样对于P3P4
。点P1
可以P4
很容易地从圆心C1
和C2
以及一些矢量数学计算出来。例如P1 = C1 + r*nC
,哪里是从到nC
的单位向量的法线(CCW)。这个 关于 SO 的答案提供了必要的数学来确定两条线段之间是否存在交点,如果存在,则计算参数,使得,其中是交点。此步骤可产生 0、1 或 2 个有效值C1
C2
h
H=R1+h(R2-R1)
H
h
值,取决于光线是否与 、 、 中的一个或两者都不P1P2
相交P3P4
。- 计算射线与 2 个圆中的每一个之间的交点(如果有)。同样,一个 SO答案为射线到圆的交点提供了必要的数学运算。每个圆可以产生 0、1 或 2 个交点,再次以参数方式表示。
- 如果
h
步骤 1 和 2 没有生成有效值,则射线不会与胶囊相交。否则,计算hMin
和hMax
,在步骤 1 和 2 中确定的所有有效交点的最小和最大参数值。请注意,hMin==hMax
在光线与其中一个圆相切且不相交的情况下,P1P2
或是可能的P3P4
。所需的交点现在可以计算为H1=R1+hMin(R2-R1)
和H2=R1+hMax(R2-R1)
。
恐怕我选择的语言是 Java 而不是 C++,但希望您会发现我整理的代码 ( IDEOne ) 作为参考有用。double
请注意,在计算过程中,由于数值四舍五入而导致的稳健性问题并未得到解决。
推荐阅读
- c# - 如何在控制台应用程序中与 ConfigureAwait(true) 进行有效交互?
- python - 在 Python 中将字符串行转换为有效的 json 格式
- java - 如何更改查找共享库的位置?
- javascript - 在正则表达式中结合 2 个条件
- c# - C# winform 复选框仍然选中
- database - 与 MongoDB 的 BSON 更新相比,Postgres jsonb_set 的性能如何?
- javascript - 上下文/弹出菜单在黄金布局的拆分器上被剪切
- flutter - 下载 ZIP,解压缩并显示图像文件,但未从文档目录加载?
- node.js - 如何更改 discord.js 中的角色设置?
- c++ - 将 cv::Mat 插入 std::map 后会改变吗?根本原因是什么?