【问题标题】:Incorrect calculating of surface normal of a triangle in C++C ++中三角形的表面法线计算不正确
【发布时间】:2021-01-01 01:26:58
【问题描述】:

我正在尝试根据三角形的 3 个顶点计算 C++(和 OpenGL)中三角形的表面法线。对于未旋转的三角形,我得到了正确的结果,但是对于旋转的三角形,我得到了半正确的结果。不知道我做错了什么。预期的结果应该是为三角形 1(未旋转)返回一个向量 (1, 0, 0),为三角形 2(在 Y 轴上旋转 90 度)返回一个向量 (0, 0, -1),但是我得到 (1, 0 , 0) 对于三角形 1 和 (-4.15243e-08, 1.82413e-08, -1)

如您所见,第一个向量和第二个法线向量的 Z 分量是正确的,但是第二个向量的 X 和 Y 分量在很大程度上是不准确的,因为它们都应该为零

我的代码是一个使用 GLM 的非常简单的函数:

void CalcSurfaceNormal(glm::vec3 tri1, glm::vec3 tri2, glm::vec3 tri3)
{
        //tri1 tri2 and tri3 are the triangles 3 vertices
        //Simple algorithm followed from another stack overflow article
        glm::vec3 u = tri2 - tri1;
        glm::vec3 v = tri3 - tri1;
    
        glm::vec3 nrmcross = glm::cross(u, v);
        nrmcross = glm::normalize(nrmcross);
        std::cout << "NormalCrs " << nrmcross.x << " " << nrmcross.y << " " << nrmcross.z << "\n";

}

附加信息: 三角形参数现在没有改变,所以我可以让它工作

第一个正确的调用传入了这些 vec3: (0.970976, -0.0246142, -0.0621899) (0.970976, 0.0553858, 0.0178101)' (0.970976, -0.0246142, 0.117237)

最后一个 z 组件正确的第二个调用传入了这些 vec3: (1.93781, 0.0246142, 0.0290235) (2.01781, 0.0553858, 0.0290235) (2.11724, -0.0246142, 0.0290235)

【问题讨论】:

  • -4.15243e-081.82413e-08 几乎为零,称这很大程度上不准确可能有点错误。
  • -4.15243e-08。这是可以预期的浮点错误。参见,例如,Is floating point math broked
  • 参数向量的值是您之前计算得出的,还是您打印出来的,还是您手动输入的?您是否尝试打印出向量 uv 的值?
  • 它们是由早期计算产生的,但是我已经确保并跨过我的代码,并确保这些旋转的顶点是正确的。打印出损坏的 U 和 V 的值是“U COMP: 0.08 0.08 -1.86265e-09 V COMP: 0.179427 0 -7.45058e-09” 我认为这是 C++ 本身的浮点错误,而不是我的代码。有谁知道我该如何解决这个问题?我需要这个值非常准确,因为我需要一个分离轴来执行分离轴定理以进行碰撞检测
  • 你是什么意思很大程度上不准确? -0.00000004 非常接近于 0。

标签: c++ algorithm math opengl collision-detection


【解决方案1】:

-4.15243e-081.82413e-08 几乎为零,称这很大程度上不准确可能有点错误,尤其是当您考虑到您谈论的是长度为 1 的向量时。

有人知道我该如何解决这个问题吗?`

您总是会遇到浮点错误,这是无法解决的。 sin, tan, cos, pi, ... 只是近似值,所以你总是要预料到错误。如果您需要更高的准确度,您可以使用glm::dvec3 使用double 而不是float

这会影响碰撞检测或分离轴定理吗?我没有意识到这些值几乎为零。尽管它们仍然不完全准确,但我可以想象这不会过多地扰乱 SAT 吗?

这些不准确之处会随着时间的推移而累积,具体取决于您的使用方式。例如。如果您有 3 个轴并随着时间的推移分别旋转它们。它们之间的角度可能会发生明显变化。所以它总是取决于你如何使用结果,如果它是一个问题。

【讨论】:

  • 如果我使用这个轴来测试与分离轴定理的碰撞,我会得到很多误报还是不会注意到差异?我认为浮点错误是可以的,只要它不会搞砸。
  • 双打也不能修复我刚刚尝试过的错误。所以我假设这是不可修复的?只需要处理不准确性?
  • @user324093252 通常不应该不是问题。但这取决于您如何继续使用这些值。那是例如为什么你有一个模型矩阵来描述场景中顶点的位置和方向 - 它们属于一起 - 而不是直接随着时间的推移直接平移和旋转顶点。
  • @user324093252 Also doubles don't fix the error I just tried. 你无法修复它,你可以通过它来提高准确性并最大限度地减少错误。
【解决方案2】:

单精度浮点数提供七位有效数字的准确度(2^-23 相对误差)。对于长度为 1 的向量,像 4.10^-8 这样的分量无法与 0 区分开来。

【讨论】:

    猜你喜欢
    • 2013-12-21
    • 2011-10-03
    • 2017-09-23
    • 1970-01-01
    • 1970-01-01
    • 2011-01-09
    • 1970-01-01
    • 1970-01-01
    • 2021-07-12
    相关资源
    最近更新 更多