- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我可以实现 AABB 方法来检测碰撞,它既简单又便宜,但我想实现 OBB 以获得更高的准确性,所以我使用模型初始化创建了边界框,它由 8 个边界顶点和中心组成,我变换的每一帧所有具有适合定向边界框的变换矩阵的顶点,但我无法理解检测两个 OBB 之间碰撞的方法,我找不到一个简单明了的教程来解释算法的代码观点而不是数学,因为我不是数学家。
如果我有
struct Box {
glm::vec3 vertices[8];
Box() {
for (int i = 0; i < 8; i++) {
vertices[i] = glm::vec3(0);
}
}
glm::vec3 max;
glm::vec3 min;
glm::vec3 origin;
void reCompute() {
max = vertices[0];
min = vertices[0];
for (int i = 1; i < 8; i++) {
max.x = max.x > vertices[i].x ? max.x : vertices[i].x;
max.y = max.y > vertices[i].y ? max.y : vertices[i].y;
max.z = max.z > vertices[i].z ? max.z : vertices[i].z;
min.x = min.x < vertices[i].x ? min.x : vertices[i].x;
min.y = min.y < vertices[i].y ? min.y : vertices[i].y;
min.z = min.z < vertices[i].z ? min.z : vertices[i].z;
}
origin = glm::vec3((max.x + min.x) / 2.0f, (max.y + min.y) / 2.0f, (max.z + min.z) / 2.0f);
}
//AABB intersection
bool intersects(const Box &b) const {
return (min.x < b.max.x) && (max.x > b.min.x) && (min.y < b.max.y) && (max.y > b.min.y) && (min.z < b.max.z) && (max.z > b.min.z) && *this != b;
}
bool operator==(const Box& b) const {
return (max.x == b.max.x && max.y == b.max.y && max.z == b.max.z && min.x == b.min.x && min.y == b.min.y && min.z == b.min.z);
}
bool operator!=(const Box& b) const {
return (max.x != b.max.x) || (max.y != b.max.y) || (max.z != b.max.z) || (min.x != b.min.x) || (min.y != b.min.y) || (min.z != b.min.z);
}
};
在模型初始化时我创建了盒子
box.vertices[0] = glm::vec3(meshMinX, meshMinY, meshMinZ);
box.vertices[1] = glm::vec3(meshMaxX, meshMinY, meshMinZ);
box.vertices[2] = glm::vec3(meshMinX, meshMaxY, meshMinZ);
box.vertices[3] = glm::vec3(meshMaxX, meshMaxY, meshMinZ);
box.vertices[4] = glm::vec3(meshMinX, meshMinY, meshMaxZ);
box.vertices[5] = glm::vec3(meshMaxX, meshMinY, meshMaxZ);
box.vertices[6] = glm::vec3(meshMinX, meshMaxY, meshMaxZ);
box.vertices[7] = glm::vec3(meshMaxX, meshMaxY, meshMaxZ);
每一帧我用模型的变换矩阵重新计算框
for (int n = 0; n < 8; n++) {
boxs[j].vertices[n] = glm::vec3(matrix * glm::vec4(box.vertices[n], 1));
}
boxs[j].reCompute();
最佳答案
用于两个 3D OBB 之间简单碰撞检测的分离轴定理的 C++ 代码实现如下:
#include <iostream>
// define the operations to be used in our 3D vertices
struct vec3
{
float x, y, z;
vec3 operator- (const vec3 & rhs) const { return{ x - rhs.x, y - rhs.y, z - rhs.z }; }
float operator* (const vec3 & rhs) const { return{ x * rhs.x + y * rhs.y + z * rhs.z }; } // DOT PRODUCT
vec3 operator^ (const vec3 & rhs) const { return{ y * rhs.z - z * rhs.y, z * rhs.x - x * rhs.z, x * rhs.y - y * rhs.x }; } // CROSS PRODUCT
vec3 operator* (const float& rhs)const { return vec3{ x * rhs, y * rhs, z * rhs }; }
};
// set the relevant elements of our oriented bounding box
struct OBB
{
vec3 Pos, AxisX, AxisY, AxisZ, Half_size;
};
// check if there's a separating plane in between the selected axes
bool getSeparatingPlane(const vec3& RPos, const vec3& Plane, const OBB& box1, const OBB&box2)
{
return (fabs(RPos*Plane) >
(fabs((box1.AxisX*box1.Half_size.x)*Plane) +
fabs((box1.AxisY*box1.Half_size.y)*Plane) +
fabs((box1.AxisZ*box1.Half_size.z)*Plane) +
fabs((box2.AxisX*box2.Half_size.x)*Plane) +
fabs((box2.AxisY*box2.Half_size.y)*Plane) +
fabs((box2.AxisZ*box2.Half_size.z)*Plane)));
}
// test for separating planes in all 15 axes
bool getCollision(const OBB& box1, const OBB&box2)
{
static vec3 RPos;
RPos = box2.Pos - box1.Pos;
return !(getSeparatingPlane(RPos, box1.AxisX, box1, box2) ||
getSeparatingPlane(RPos, box1.AxisY, box1, box2) ||
getSeparatingPlane(RPos, box1.AxisZ, box1, box2) ||
getSeparatingPlane(RPos, box2.AxisX, box1, box2) ||
getSeparatingPlane(RPos, box2.AxisY, box1, box2) ||
getSeparatingPlane(RPos, box2.AxisZ, box1, box2) ||
getSeparatingPlane(RPos, box1.AxisX^box2.AxisX, box1, box2) ||
getSeparatingPlane(RPos, box1.AxisX^box2.AxisY, box1, box2) ||
getSeparatingPlane(RPos, box1.AxisX^box2.AxisZ, box1, box2) ||
getSeparatingPlane(RPos, box1.AxisY^box2.AxisX, box1, box2) ||
getSeparatingPlane(RPos, box1.AxisY^box2.AxisY, box1, box2) ||
getSeparatingPlane(RPos, box1.AxisY^box2.AxisZ, box1, box2) ||
getSeparatingPlane(RPos, box1.AxisZ^box2.AxisX, box1, box2) ||
getSeparatingPlane(RPos, box1.AxisZ^box2.AxisY, box1, box2) ||
getSeparatingPlane(RPos, box1.AxisZ^box2.AxisZ, box1, box2));
}
// a quick test to see the code working
int _tmain(int argc, _TCHAR* argv[])
{
// create two obbs
OBB A, B;
// set the first obb's properties
A.Pos = { 0.f, 0.f, 0.f }; // set its center position
// set the half size
A.Half_size.x = 10.f;
A.Half_size.y = 1.f;
A.Half_size.z = 1.f;
// set the axes orientation
A.AxisX = { 1.f, 0.f, 0.f };
A.AxisY = { 0.f, 1.f, 0.f };
A.AxisZ = { 0.f, 0.f, 1.f };
// set the second obb's properties
B.Pos = { 20.f, 0.f, 0.f }; // set its center position
// set the half size
B.Half_size.x = 10.f;
B.Half_size.y = 1.f;
B.Half_size.z = 1.f;
// set the axes orientation
B.AxisX = { 1.f, 0.f, 0.f };
B.AxisY = { 0.f, 1.f, 0.f };
B.AxisZ = { 0.f, 0.f, 1.f };
// run the code and get the result as a message
if (getCollision(A, B)) std::cout << "Collision!!!" << std::endl;
else std::cout << "No collision." << std::endl;
// pause and quit
std::cout << std::endl;
system("pause");
return 0;
}
关于c++ - Simple Oriented Bounding Box OBB 碰撞检测解释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47866571/
我知道在 OOP 中你希望每个对象(来自一个类)都是一个“东西”,例如。用户、验证者等 我了解 MVC 的基础知识,了解它们的不同部分如何相互交互。 但是,我想知道MVC中的模型是否应该按照传统的OO
我想知道 Android 手机是否真的有方向传感器。我怀疑并不是所有的安卓手机屏幕都会随着方向的改变而改变(比如带有 qwerty 键盘的手机) 我浏览了文档并找到了一个 bool 方法“canDet
我已经创建了一个设备方向监听器来捕捉设备旋转的时间,就像这样 [[NSNotificationCenter defaultCenter] addObserver:self
我已通过 XCode 将方向锁定为横向左和横向右,但使用 UIDevice.current.orientation 给出的方向就好像未锁定一样。就像当我物理上(在现实生活中)处于纵向,但我的 View
我无法保持当前的 View 方向。在下面的设置中,我已经能够将第一个 View Controller 锁定为纵向,将第二个 View Controller 锁定为横向或纵向。但是,当我将第二个导航 C
This question already has answers here: is it wrong to treat panic / recover as throw / catch (2个答案)
使用 iOS 8.3 我有一个横向模式的 View ,我正在尝试打开一个仅纵向 View Controller 。每次我尝试打开它时,应用程序都会崩溃。 我读过这个official apple ans
我正在编写一个将在手机和 Honeycomb 平板电脑上运行的 Android 应用程序,并且从一开始就运行基于操作系统的不同 Activity 。在非 honeycomb 设备上,我将所有 Acti
我看到我们可以使用以下方法创建 orient db: ODatabaseDocumentTx db2 = new ODatabaseDocumentTx ( "local:C:/temp/db/scr
我想知道这两者之间有什么区别?一个比另一个的好处?等等…… 最佳答案 “水平”允许布局中的元素彼此并排放置,而“垂直”则将它们堆叠在一起。两者都没有真正的好处 - 使用最适合您的设计的那个。 offi
HTML 代码: Home Feed
我正在尝试使用此代码在 View 上强制定向。 -(BOOL)shouldAutorotate { return YES; } -(NSUInteger)supportedInterfaceO
我有一个 XML 布局,在横向和纵向方向上工作得很好,但有一个异常(exception) - LinearLayout 中的两个按钮需要水平放置在横向设备方向上,垂直放置在纵向设备方向上。 我想知道是
我四处搜寻,结果很难找到答案。 Theres算法可以生成四元数形式的随机方向,但是它们涉及sqrt和trig函数。我真的不需要统一分布的方向。我只需要生成(许多)四元数,以使它们的方向随机性“足够好”
我想在 2 轴上监视设备的方向:非常简单:哪个方向朝下。 它必须在长时间(12 小时)内保持准确性 它将受到围绕所有轴的旋转和加速度 该设备将是带有标准陀螺仪/加速度计的 Android 手机。对于这
我有一个初始四元数q0。我得到了角速度测量结果,对速度进行了积分,所以在50Hz左右获得了3个角度。如何基于3个角度制作四元数?我不能只做3个四元数,可以吗? 所以要说清楚。 Q.new = Q.ne
我正在尝试实现用于方向检测的卡尔曼滤波器。就像我在网上找到的大多数其他实现一样,我将使用陀螺仪和加速度计来测量俯仰和滚动,但我还打算添加水平检测。这将使我对俯仰和滚动进行第二次阅读。这意味着我将有两种
我们有 XSENS MTi IMU 设备并使用 ROS 框架 (Ubuntu/Fuerte)。我们订阅了 IMU 数据,所有数据看起来都不错,除了方向。 在 Euler-Outputmode 中,就像
我想设置一个 TabControl 使其标题位于左侧而不是顶部,我该怎么做? 最佳答案 关于wpf - TabControl.Orientation?,我们在Stack Overflow上找到一个
是否有任何用于方向更改和窗口调整大小的 openui5 事件处理程序? onInit: function() { var data; this.drawChart(data);
我是一名优秀的程序员,十分优秀!