- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
给定顶点的位置和表面法线。如何计算两个三角形接触的面积(可能为 0)?这些三角形也在 3D 空间中,所以如果它们没有正确排列,只是相互挤压,接触面积应该为 0。(在 C# 中)
最佳答案
这不是一个微不足道的问题,所以让我们把它分解成几个步骤。
要使两个三角形共面,一个三角形的所有顶点必须位于另一个三角形确定的平面内。
使用描述的算法 here我们可以检查每个顶点是否是这种情况,但由于 float 不是完全精确的事实,您将需要定义一些错误阈值以确定仍然算作共面的东西。
假设 va
和 vb
分别是三角形 A 和 B 的向量,代码可能如下所示。
(注意:我从未使用过 Unity,所有代码都是靠内存编写的,所以如果不是 100% 正确,请原谅)。
public static bool AreTrianglesCoplanar(Vector3[] va, Vector3[] vb) {
// make sure these are actually triangles
Debug.Assert(va.Length == 3);
Debug.Assert(vb.Length == 3);
// calculate the (scaled) normal of triangle A
var normal = Vector3.Cross(va[1] - va[0], va[2] - va[0]);
// iterate all vertices of triangle B
for(var vertex in vb) {
// calculate the dot product between the normal and the vector va[0] --> vertex
// the dot product will be 0 (or very small) if the angle between these vectors
// is a right angle (90°)
float dot = Vector3.Dot(normal, vertex - va[0]).
// the error threshold
const float epsilon = 0.001f;
// if the dot product is above the threshold, the vertex lies outside the plane
// in that case the two triangles are not coplanar
if(Math.Abs(dot) > epsilon)
return false;
}
return true;
}
我们现在知道所有六个顶点都在同一个嵌入到 3D 空间的 2D 平面中,但是我们所有的顶点坐标仍然是三维的。所以下一步是将我们的点投影到 2D 坐标系中,这样它们的相对位置就会被保留。
This answer很好地解释了数学。
首先,我们需要找到一组构成正交基的三个向量(它们必须彼此正交且长度为 1)。
va[0]
到 va 的向量[1]
) 并将其归一化。我们还需要在平面上选择一个点作为我们的原点,例如 va[0]
。
有了所有这些参数,并使用链接 amswer 中的公式,我们可以从其他答案)。请注意——因为我们所有的点都位于定义该法向量的平面内——第三个坐标(在另一个答案中称为 s
)将始终(接近)零。
public static void ProjectTo2DPlane(
Vector3[] va, Vector3[] vb
out Vector2[] vaProjected, out Vector2[] vbProjecte
) {
// calculate the three coordinate system axes
var normal = Vector3.Cross(va[1] - va[0], va[2] - va[0]).normalized;
var e1 = Vector3.Normalize(va[1] - va[0]);
var e2 = Vector3.Cross(normal, e1);
// select an origin point
var origin = va[0];
// projection function we will apply to every vertex
Vector2 ProjectVertex(Vector3 vertex) {
float s = Dot(normal, vertex - origin);
float t1 = Dot(e1, vertex - origin);
float t2 = Dot(e2, vertex - origin);
// sanity check: this should be close to zero
// (otherwise the point is outside the plane)
Debug.Assert(Math.Abs(s) < 0.001);
return new Vector2(t1, t2);
}
// project the vertices using Linq
vaProjected = va.Select(ProjectVertex).ToArray();
vbProjected = vb.Select(ProjectVertex).ToArray();
}
健全性检查:
va[0]
应该投影到 (0, 0)。va[1]
应该被投影到 (*, 0),所以在新的 x 轴上的某个地方。 This answer这个答案提到了最后一步所需的算法。
Sutherland-Hodgman algorithm连续剪辑一个三角形与另一边的每一边。结果将是三角形、四边形或空多边形。
最后,shoelace formula可用于计算生成的裁剪多边形的面积。
假设您实现了 CalculateIntersecionPolygon
和 CalculatePolygonArea
这两个函数,最终的交集面积可以这样计算:
public static float CalculateIntersectionArea(Mesh triangleA, Mesh triangleB) {
var verticesA = triangleA.GetVertices();
var verticesB = triangleB.GetVertices();
if(!AreTrianglesCoplanar(verticesA, verticesB))
return 0f; // the triangles are not coplanar
ProjectTo2DPlane(verticesA, verticesB, out Vector2[] projectedA, out Vector2[] projectedB);
CalculateIntersecionPolygon(projectedA, projectedB, out List<Vector2> intersection);
if(intersection.Count == 0)
return 0f; // the triangles didn't overlap
return CalculatePolygonArea(intersection);
}
关于c# - 怎么求两个三角形相交的面积,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66614852/
我正在开发一个企业名录网站,其搜索将由 Google map 驱动。用户将能够根据各种标准搜索他们所在地区的企业,但主要的想法是,如果您搜索例如“新泽西州的水管工”,您将获得新泽西州所有水管工的结果。
我得到了一条任意形状的曲线,包围了一些区域。 我想估计曲线在 iPhone/iPad 屏幕上包围的像素数。我该怎么做? 曲线被定义为点的连续 x/y 坐标。 闭合曲线。 通过用户的触摸(touches
我想删除 R 在点阵图周围的默认边距。这意味着我想摆脱红色矩形之外的所有空白。这是示例: library (raster) library(rasterVis) f <- system.file("e
无法找到任何直接的解决方案来计算 GMSPolygon 对象面积。有什么方法可以做到这一点,或者我必须用边长和一些数学计算来计算它? 最佳答案 感谢@Larme; GMSGeometryArea 就是
假设例如我想将标准正态分布的密度曲线下方的面积着色为十分。我希望最左边 10% 的区域具有与接下来的 10% 不同的阴影,依此类推。 这是问题“Shading a kernel density plo
我正在为 Extjs 开发一个混合图表组件,并且曲线太尖锐了。我找不到曲线具有半径的配置。如果你处理过类似的事情,你能提供一些方法让我的曲线变得平滑一点吗?这是我的代码: Ext.define('Ex
上下文 我有一个 3D 对象,我有它的坐标。然后我将对象旋转 n 次,当对象投影到网格上时,我想计算对象的 2D 面积(以纳米为单位)。 例如, 我在下面有一张图片描述了我的问题。我有相同的对象,但在
当我知道我需要的地 block 总数并且我希望排列是一个正方形(可能有一些空的子地 block )时,我正在尝试弄清楚如何计算子地 block 尺寸。 例如,如果我需要 22 个子图,那么我会为总共
我是一名数据科学家。主要使用Python和SQL来编写代码。我使用data studio进行可视化。所以我对JS不熟悉。我的诀窍data studio community visualizations
我有 1797 张 Mnist 图像,为此我需要提取两个特征(FilledArea、EulerNumber)。我知道如何在 Matlab 中做到这一点。我的特征矩阵在 Matlab 中具有(并且是正确
我希望能够在 Google map 上绘制形状(圆形、多边形和矩形),但我想限制可以绘制的形状的大小(面积)。因此,以圆圈为例,期望的行为是当用户开始从 map 上的某个点拖动鼠标以形成圆圈时,圆圈会
我是一名优秀的程序员,十分优秀!