- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我想知道两个 3D 凸包(A
vs B
)之间碰撞位置的近似 3D 位置和 3D 法线。
括号中的 CPU 显示了我完成的程序所需的相对 CPU 时间。
在第一步中,我使用了一个非常便宜的算法——separation axis theorem .
例如,我使用 15 axis 2 个立方体。 (在实际情况下,形状更复杂。)
如果至少有 1 个轴可以分离,返回“no-collide”
。
否则,做下一部分。
A
的每个顶点 - 是否在 B
内。 B
的每个顶点——是否在A
内。 有一个奇怪的案例,例如https://gamedev.stackexchange.com/questions/75437/collision-detection-3d-rectangles-using-sat .我从那里偷了图像:-
因此,我还需要 edge 与 edge。
A
的边中找到与 B
边最近的点。检查顶点是否在B
内。 A
内。 哇,计算量太大了。
然而,事情还没有结束。
报告的碰撞位置不太准确(左:当前,右:希望):-
为了解决这个问题,我想到了生成一个新的凸形 = A intersect B
。
有一些 C++ 免费库(例如 OpenMesh ),但我认为它的 CPU 开销太大。
请注意,我不需要它完全正确。
有时也会报错正常(左:当前,右:愿望):-
^ 这个问题可以通过添加 edge (of A) vs face (of B) 检查来解决,但这会使整个碰撞检测更加昂贵。
看起来互联网上的常见算法(我从中复制)只能识别微特征。
恕我直言,顶点体积/边缘边缘算法专注于拓扑,而不是两种形状都是实体体积的事实。
哪种算法更准确(第一优先级)并且可能更便宜?
我的方法在基础层面可能是错误的。
为了加快速度,我已经做了一些修剪,例如只选择靠近的一对边 A 和 B。
引用资料:-
Algorithms for Collision Detection between Arbitrarily sized Convex Polygons仅检查是否发生碰撞。
https://pybullet.org/Bullet/BulletFull/btBoxBoxDetector_8cpp_source.html : 启发 Bullet Physics 库中盒子与盒子碰撞检测的完整代码 - 很难理解。
https://math.stackexchange.com/questions/397413/determine-direction-of-minimum-overlap-of-convex-polygons与此非常相似的未回答的数学问题。
现在,我可以找到所有相交的凸点(凸点被描绘为粉红色的三角形/矩形):-
这是我找到正常的方法。
对于每个分离轴(all=15 轴),我将粉红色的凸面投影到轴上。
产生最短投影距离的轴(粉红色箭头)应该是法线方向。
我的上述假设通常是正确的(例如左),但有时是错误的(例如右)。
如何以 CPU 便宜的方式改进它?
最佳答案
游戏引擎通常会模拟一系列离散步骤的时间。因此,由于相互渗透(您的情况)或当事物快速移动时,碰撞系统可能会遇到困难(计算成本高)的情况 - 在步骤 N 处 A 位于 B 的一侧并且完全位于 B 的另一侧的情况下在步骤 N+1。如果您需要处理多体接触或连续接触或非凸面或关节或柔软物体,则更加困难。哎呀!我们正在模拟整个世界。
您想做“游戏物理”并使用近似值来买回帧速率...最后,你可以用一堆烟雾或光弹来掩盖很多错误。 :-)
有一类算法明确考虑模拟时间来帮助碰撞系统。有很多方法可以实现“连续碰撞检测”系统。您可以从这里开始,但您应该先广泛阅读,然后再提交代码。幸运的是,有很多关于碰撞的文献。这是一个很好的起点 https://docs.unity3d.com/Manual/ContinuousCollisionDetection.html https://pybullet.org/Bullet/phpBB3/viewtopic.php?t=20
这是一种建议的启发式方法,它可能适用于您现有的系统......这种启发式技术可能适用于像 astroids 3d 这样物体在空间中自由漂浮的游戏。这可能足以满足您的需要。
图像中每个对象都存储其当前状态 vector (位置、方向、速度、加速度、旋转...)及其上一个时间步的状态 vector 。
假设您在 time=current 检测到对象 A 和 B 之间的潜在碰撞。
对于 time=previous,假设 A 和 B 没有联系。
使用 A 和 B 的先前状态 vector 分别在 time=prev 计算 A 和 B 表面上的最近点。(最近的A,最近的B)。
线段 (closestA,closestB) 在 time=previous 时将具有非零长度。您可以只使用最接近B 作为您的位置和法线,但它会产生一些与线段长度成比例的误差..
因此,及时进行二分搜索,并通过查找 A 任意接近 B 的时间来最小化错误。在您的每次搜索过程中,将搜索时间步长减半。 0.5, 0.25, 0.125 .. 直到 (closestA,mostB) 的长度低于错误阈值或您放弃。
对于简单的情况,这应该会给你一个可接受的近似解决方案......
另外,您说您使用分离轴定理作为您的“第一次检查”。如果这真的是“第一次检查”,那对我来说实际上听起来很昂贵..
最快的计算是你不做的,所以快速碰撞意味着大量廉价的预测试并避免昂贵的情况。
您可以考虑使用空间技术,例如粗略的空间网格,并且只检查您已经知道彼此靠近的对象。
另外,sphere-sphere 测试是一种非常快速的预测试,用于查看两个凸对象的边界球是否甚至重叠。
关于c++ - 3D碰撞检测: convex hull vs convex hull ,需要位置和法线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56912376/
关闭。这个问题需要debugging details .它目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and th
我试图用这种形式简单地获取数字 28 integer+space+integer+integer+space+integer我试过这个正则表达式 \\s\\d\\d\\s 但我得到了两个数字11 和
最近一直在学习D语言。我一直对运行时感到困惑。 从我能收集到的关于它的信息中,(这不是很多)我知道它是一种有助于 D 的一些特性的运行时。像垃圾收集一样,它与您自己的程序一起运行。但是既然 D 是编译
想问一下这两个正则表达式有区别吗? \d\d\d 与 \d{3} 我已经在我的本地机器上使用 Java 和 Windows 操作系统对此进行了测试,两者都工作正常并且结果相同。但是,当在 linux
我正在学习 Go,而且我坚持使用 Go 之旅(exercise-stringer.go:https://tour.golang.org/methods/7)。 这是一些代码: type IPAddr
我在Java正则表达式中发现了一段令我困惑的代码: Pattern.compile( "J.*\\d[0-35-9]-\\d\\d-\\d\\d" ); 要编译的字符串是: String string
我在 ruby 代码上偶然发现了这个。我知道\d{4})\/(\d\d)\/(\d\d)\/(.*)/是什么意思,但是\1-\2-\3-\4 是什么意思? 最佳答案 \1-\2-\3-\4 是 b
我一直在努力解决这个问题,这让我很恼火。我了解 D 运行时库。它是什么,它做什么。我也明白你可以在没有它的情况下编译 D 应用程序。就像 XoMB 所做的那样。好吧,XoMB 定义了自己的运行时,但是
我有两个列表列表,子列表代表路径。我想找到所有路径。 List> pathList1 List> pathList2 当然是天真的解决方案: List> result = new ArrayList>
我需要使用 Regex 格式化一个字符串,该字符串包含数字、字母 a-z 和 A-Z,同时还包含破折号和空格。 从用户输入我有02-219 8 53 24 输出应该是022 198 53 24 我正在
目标是达到与this C++ example相同的效果: 避免创建临时文件。我曾尝试将 C++ 示例翻译为 D,但没有成功。我也尝试过不同的方法。 import std.datetime : benc
tl;dr:你好吗perfect forwarding在 D? 该链接有一个很好的解释,但例如,假设我有这个方法: void foo(T)(in int a, out int b, ref int c
有什么方法可以在 D 中使用abstract auto 函数吗? 如果我声明一个类如下: class MyClass { abstract auto foo(); } 我收到以下错误: mai
有没有人为内存中重叠的数组切片实现交集?算法在没有重叠时返回 []。 当 pretty-print (使用重叠缩进)内存中重叠的数组切片时,我想要这个。 最佳答案 如果您确定它们是数组,那么只需取 p
我已经开始学习 D,但我在使用 Andrei Alexandrescu 所著的 The D Programming Language 一书中提供的示例时遇到了一些麻烦。由于 int 和 ulong 类
如何创建一个不可变的类? 我的目标是创建一个实例始终不可变的类。现在我只是用不可变的方法和构造函数创建了一个“可变”类。我将其称为 mData,m 表示可变。然后我创建一个别名 alias immut
不久前我买了《The D Programming Language》。好书,很有教育意义。但是,我在尝试编译书中列出的语言功能时遇到了麻烦:扩展函数。 在这本书中,Andrei 写了任何可以像这样调用
我在 D http://www.digitalmars.com/d/2.0/lazy-evaluation.html 中找到了函数参数的惰性求值示例 我想知道如何在 D 中实现可能的无限数据结构,就像
这个问题在这里已经有了答案: 12 年前关闭。 Possible Duplicate: Could anyone explain these undefined behaviors (i = i++
当前是否可以跨模块扫描/查询/迭代具有某些属性的所有函数(或类)? 例如: source/packageA/something.d: @sillyWalk(10) void doSomething()
我是一名优秀的程序员,十分优秀!