微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何确定我是否刚刚计算了正确方向的法线?

如何解决如何确定我是否刚刚计算了正确方向的法线?

为了解释上下文,我在 C# 中按程序生成了统一的建筑物。我创建一个网格并填充顶点和三角形,然后计算不同点的法线。我生成了数百个建筑物,但有些面的方向不正确,法线指向内而不是外。

法线很好

enter image description here

法线不好

enter image description here

为了计算法线,我用构成三角形的不同顶点创建了一个平面,然后我检索了平面的法线。我还测试了得出相同结果的叉积。

Plane plane = new Plane(v1,v2,v3);
normals.Add(plane.normal);

我如何生成三角形?

enter image description here

例如:我在建筑物底部的点上做了一个 for 循环。

 vectors.Add(v1);
 vectors.Add(v2);
 vectors.Add(v3); //v3 = v1+height
 vectors.Add(v4); //v4 = v2+height

 // index values
 int idx1,idx2,idx3,idx4;
 idx4 = vectors.Count - 1;
 idx3 = vectors.Count - 2;
 idx2 = vectors.Count - 3;
 idx1 = vectors.Count - 4;

 // Triangle 1
 indices.Add(idx1);
 indices.Add(idx3);
 indices.Add(idx2);
...
mesh.triangles = indices.ToArray();

所以我的问题是:如何确定法线方向是否正确(内部或外部)?如果我能确定,我就可以翻转法线,正常情况下它会起作用。

解决方法

我不完全理解你的问题,但是对于简单形状来说,一个简单的算法是..

  • 只需取对象的“中心”(CG 很好)并从那里制作一个向量到您的顶点或三角形。那个方向是“外面”。如果您指向的角度超过 90°,则您指向的是对象的内部

下一个更复杂的方法......

  • 沿着你平常说的“一米”移动。称该点为“测试点”。你应该现在“在你的建筑物外面”,对吗?

  • 现在您只需要检查 testPoint 是在您的 3D 形状内部还是外部。

  • 简而言之,要确定您是在 3D 对象内部还是外部,您只需投射一条射线并计算与墙壁相交的次数。 如果奇怪,你在里面,即使你在外面。

您可以在 www 上搜索数百个关于此的讨论,例如 https://stackoverflow.com/a/63572837/294884

请注意,这方面有很多很多变化,也有很多问题。在某些情况下,您从正常的“内部”开始(即稍微向后);有时最好从对象的中间开始(如果这样的事情是可知的);有时会出现关于光线投射系统在边缘情况下如何工作的问题(例如“就在”表面,这就是您的顶点所在的位置)


在我看来,第一个解决方案是正确的

可能是。有时它是无用的。这取决于您的形状的性质。

我想避免进行光线投射..

可以向您保证 - 在任何构建过程中,您都必须不断地进行光线投射!如果你想“避免”强制转换,就把这个想法搁置一旁。你会一直投射直到你厌倦了 :)

我想避免必须进行光线投射以限制生成时间

好消息是这完全不正确。与 3D 场景中发生的所有事情相比,投射是极其微不足道的,而且是非常小的负担。当您播放任何 3D 场景时,每帧都会进行 100 到 1000 次演员。

但是如果我有两座彼此靠近的建筑物,光线会找到墙壁,但是来自第二座建筑物,所以我无法确定法线是“内部”还是“外部”,对吗?

我描述的简单系统中的待定。您肯定只会对您正在处理的同一建筑物进行投射!所以这就是要走的路。

但确实,与您要问的内容无关。假设你在一个“城市”。您确实可以穿过“所有墙壁”,并且奇偶校验(即:奇数或偶数)会让您知道您是在室内还是室外。不过这有一些问题,与边缘、角落等有关。但在某些情况下,它与该问题有关。

正如在这个答案中提到的 https://stackoverflow.com/a/63593282/294884 最终你可以研究凸包等等。这是一个很大的话题!

请注意,通常当您构建动态建筑物/形状时,您拥有每个“墙”的数据结构,并且确实它知道哪一面在里面,哪一面在外面。当您首先这样做时,很容易以正确的方式绘制三角形。这是一个很大的话题!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。