- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我已经使用 C++ 和 OpenGL 创建了一个简单的 3d 第一人称演示,它似乎运行良好。我的目标是:当用户将相机指向一个平面并单击鼠标左键时,我想绘制一条射线的交点,该射线从玩家的位置与该平面指向相机所面对的方向。
所以,我从两个 vector 开始,Vector position
和 Vector rotation
,其中 Vector 是一个非常标准的三维 vector 类:
class Vector
{
public:
GLfloat x, y, z;
Vector() {};
Vector(GLfloat x, GLfloat y, GLfloat z)
{
this->x = x;
this->y = y;
this->z = z;
}
GLfloat dot(const Vector &vector) const
{
return x * vector.x + y * vector.y + z * vector.z;
}
... etc ...
和 Plane p
,其中 Plane 是一个简单的结构,用于存储平面的法线和 d。我直接从 Christer Ericson 的“实时碰撞检测”一书中复制了这个结构:
struct Plane
{
Vector n; // Plane normal. Points x on the plane satisfy Dot(n,x) = d
float d; // d = dot(n,p) for a given point p on the plane
};
首先,我将 position
作为射线的起点,我称之为 a
。我使用该点和 rotation
找到射线的终点 b
。然后我使用一种算法从同一本书中找到射线和平面的交点。我实际上自己实现了相同的方法,但我在这里直接使用书中的代码只是为了确保我没有搞砸任何事情:
void pickPoint()
{
const float length = 100.0f;
// Points a and b
Vector a = State::position;
Vector b = a;
// Find point b of directed line ab
Vector radians(Math::rad(State::rotation.x), Math::rad(State::rotation.y), 0);
const float lengthYZ = Math::cos(radians.x) * length;
b.y -= Math::sin(radians.x) * length;
b.x += Math::sin(radians.y) * lengthYZ;
b.z -= Math::cos(radians.y) * lengthYZ;
// Compute the t value for the directed line ab intersecting the plane
Vector ab = b - a;
GLfloat t = (p.d - p.n.dot(a)) / p.n.dot(ab);
printf("Plane normal: %f, %f, %f\n", p.n.x, p.n.y, p.n.z);
printf("Plane value d: %f\n", p.d);
printf("Rotation (degrees): %f, %f, %f\n", State::rotation.x, State::rotation.y, State::rotation.z);
printf("Rotation (radians): %f, %f, %f\n", radians.x, radians.y, radians.z);
printf("Point a: %f, %f, %f\n", a.x, a.y, a.z);
printf("Point b: %f, %f, %f\n", b.x, b.y, b.z);
printf("Expected length of ray: %f\n", length);
printf("Actual length of ray: %f\n", ab.length());
printf("Value t: %f\n", t);
// If t in [0..1] compute and return intersection point
if(t >= 0.0f && t <= 1.0f)
{
point = a + t * ab;
printf("Intersection: %f, %f, %f\n", point.x, point.y, point.z);
}
// Else no intersection
else
{
printf("No intersection found\n");
}
printf("\n\n");
}
当我用 OpenGL 渲染这个点时,它看起来非常接近光线和平面的交点。但是通过打印出实际值,我发现对于特定的位置和旋转,交点最多可以偏离 0.000004。这是交点不准确的示例 - 我知道交点不在平面上,因为它的 Y 值应该是 0,而不是 0.000002。我也可以将它代入平面方程并得到不等式:
Plane normal: 0.000000, 1.000000, 0.000000
Plane value d: 0.000000
Rotation (degrees): 70.100044, 1.899823, 0.000000
Rotation (radians): 1.223477, 0.033158, 0.000000
Point a: 20.818802, 27.240383, 15.124892
Point b: 21.947229, -66.788452, -18.894285
Expected length of ray: 100.000000
Actual length of ray: 100.000000
Value t: 0.289702
Intersection: 21.145710, 0.000002, 5.269455
现在,我知道 float 只是实数的近似值,所以我猜这种不准确只是 float 舍入的结果,尽管我可能在代码的其他地方犯了错误。我知道交点只有极小的偏差,但我仍然很关心它,因为我打算使用这些点来定义模型或关卡的顶点,方法是将它们捕捉到任意方向的网格,所以我实际上想要那些点在那个网格上,即使它们稍微不准确。这可能是一种误入歧途的方法 - 我真的不知道。
所以我的问题是:这种不准确只是工作中的浮点舍入,还是我在其他地方犯了错误?
如果只是 float 舍入,有什么办法处理吗?我已经尝试以各种方式舍入旋转和位置 vector 的值,这显然会导致交点不太准确,但有时我仍然会得到不在平面上的交点。我确实读过一个类似问题 ( Is this plane-ray intersection code correct? ) 的答案,其中提到保持尺寸较大,但我不确定这到底是什么意思。
如果之前有人问过这个问题,我很抱歉 - 我进行了搜索,但我没有看到任何我遇到的问题。谢谢!
最佳答案
您的数学似乎是正确的,这看起来确实像是一个舍入误差。我有一种强烈的感觉,就是这一行:
GLfloat t = (p.d - p.n.dot(a)) / p.n.dot(ab);
也就是说我没有看到任何其他方法来计算 t。您可以通过在 printf 语句中使用“%.12f”(或更多)来验证您是否正在失去精度。查明罪魁祸首的另一种方法是尝试逐步进行 t 计算并打印结果以查看是否在某处失去了精度。
如果精度对您来说真的那么重要,您是否尝试过使用 double float ?
关于c++ - 射线平面相交 : inaccurate results - rounding errors?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15102738/
我有一个对象: [ { TEAMGROUP: "AB", TEAMNAME: "TEAM1", SPRINTS: [ { ID: 1,
颜色模型和颜色空间之间的差异 RGB565 与 RGB888 有何不同任何建议链接 YUV vs RGB vs YCbCr。? 最佳答案 RGB 是一种加法颜色模型,其中红色、绿色和蓝色强度以不同的组
我正在从单个顶点/索引缓冲区绘制一个具有多个网格的完整对象,并且它们具有不同的纹理。因此,我想到将纹理 ID 与顶点一起从顶点着色器传递到片段着色器中的片段。问题是禁用插值。我正在使用 GLSL ve
我有一个包含 40000 个 float 的数组,用于指定 map 上的高度级别。我想在 OpenGL ES 2.0 中创建一个网格/平面,为该网格中的每个顶点分配一个来自该数组的高度值,以便它们创建
我真的很喜欢 IQ 的页面以及有关 SDF 的信息: ( https://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
我创建了 QPushButton在带有此样式表的 Qt Designer 中: QPushButton#pushButton { background-color: #ffffff; } QP
所以我正在寻找一些平面 map 的解决方法,因为它在 IE 上不起作用,我找到了这个:但我不太明白为什么它会起作用 var gadjets = [ {computers:['asus', 'hp'
child Actor 会不会太多?例如,如果我有一个有 10000 个 child Actor 的 Actor ,与每个有 1000 个 child Actor 的 10 个 Actor 相比,这会
我有一个由法线 (n) 和距离 (d)(距原点)定义的平面。我想把它改造成一个新的系统。 长路是这样的: 1) 将距离 (d) 与法线 (n) 相乘得到一个向量 (p) 2) 旋转 (R) 并平移 (
问题: 从球体中减去立方体会得到一个结果,其中 z 轴保留体积,但 y 轴和 x 轴产生平面圆盘,如图所示。我不确定为什么球体在那些方面正在失去体积。我正在使用 threeCSG 的典型减法。 代码:
我通过 SQL 查询从我们的 ERP 获取产品数据,由此返回的数据在大小级别非常平坦。一个产品有 3 个级别: 风格 颜色 尺寸 一种款式有多种颜色,一种颜色有多种尺码。 我创建了以下模型: publ
我正在尝试展开一些 json 数据。如果我像下面这样使用我的测试数据,一切正常! var data = [ { "title": 1, "parentids": [0] }, { "title
我希望使用 SceneKit 在 Swift 中的 3D 空间中绘制多个平面。具体来说,这些表面都将位于双曲面内。我以前从未绘制过自定义形状/对象,而且在尝试理解文档时我已经迷失了方向。 关于在 3D
预先感谢您阅读我的问题。我对 ARKit 非常陌生,并且已经学习了几个教程,这些教程向我展示了如何使用平面检测以及如何为平面使用不同的纹理。这个功能真的很棒,但这是我的问题。玩家是否可以先将飞机放置在
我正在阅读下面的源代码,我想知道我到底为什么要使用平面图方式。正如我所看到的,与通过 if 语句进行简单的 null 检查相比,实例化了更多的对象,执行了更多代码,这将在第一个 null 时终止,而不
我正在编写一个 Rails 应用程序并使用 Flat UI 进行样式设置。我目前正在将 flatui-rails gem 与 twitter-bootstrap-rails gem 结合使用。一切正常
我在维基百科中找到了射线平面相交代码的解决方案,该解决方案有效,我只是在其中求解线性方程组。 后来我找到了一些点到平面投影的代码,显然实现方式不同,并且在特定条件下也会产生不同的解决方案。 但是,我并
我正在使用 http://designmodo.github.io/Flat-UI/ 中的扁平 UI 我复制了复选框示例页面中的所有文件和代码。 但是我注意到该复选框并未显示为样式复选框,但在我单击初
这个问题已经有答案了: True Isometric Projection with HTML5 Canvas (3 个回答) 已关闭 7 年前。 我想创建一个等轴测图。该 map 存在等距矩形,如图
http://designmodo.github.io/Flat-UI/ 我想创建一个 Css 下拉菜单,我已经完成了下拉部分,但是我似乎无法模拟转换,也不知道如何编写这些代码。这是我目前所知道的,在
我是一名优秀的程序员,十分优秀!