如何确定两个 3D 边缘是否相同

How can I determine if two 3d edges are identical?

本文关键字:边缘 3D 是否 两个 何确定      更新时间:2023-10-16

我正在尝试检测 3d 对象的轮廓边缘。我知道你必须首先确定一张脸正在看一个位置的天气,然后找到正面和背面之间共享的边缘。

我已经能够弄清楚正面和背面的东西,但我无法弄清楚如何在没有很多 if 语句的情况下找到边缘是否被共享。我的顶点数据存储在每个多边形的 x1,z1,y1,x2,z2,y2,x3,z3,y3 中。

如果你问如何确定两条线段是否在同一条线上,你可以使用一点欧几里得几何。让我们介绍几个定义:

A 是实数的 n 元组(a1, a2, ..., an)。在 3D 情况下,n=3 .

点 A 和实数 t标量乘法定义为

tA = (t*a1, t*a2, ..., t*an)

有了这两个想法,我们可以很容易地表示一条线。对于AB两个点,满足方程的点P

P = tA + (1-t)B

AB t是实数的行上。

0 <= t <= 1时,P介于AB之间,t=1P=At=0P=B

现在,为了将其置于编程角度,您可以创建两个类:PointLine 。使用上面给出的方程,很容易确定Point是否位于给定的Line上。要确定两条线段是否在同一条线上,只需使用定义一个Line的两个Point并检查它们是否位于另一条Line上。

如果 2 条线段是同一条线

如果两个线段使用相同的点坐标或相同的点索引,则它们是相同的。测试它们是否在同一条线上是完全不同的问题,您无需解决即可找到轮廓。

  1. 使用索引基元。
  2. 加载模型时,提前预先计算边列表和所需的拓扑表。
  3. 如果您正在尝试绘制阴影,请使用阴影贴图 - 它们更容易理解。

索引基元意味着
1.将所有点存储在数组中(std::vector<vector3> points;或类似的东西,其中vector3是存储xyz坐标的数据类型(,并且每个点都是唯一的。
2. 面和边是指使用整数点索引的点。

struct Vec3{
    float x, y, z;
};
typedef unsigned int Index;
struct Face{
    enum{vertsPerFace=3};
    Index verts[vertsPerFace];
};
struct Edge{
    enum{vertsPerEdge=2};
    Index verts[vertsPerEdge];
};

加载模型时,可以构建点列表,并使用std::set std::map或类似结构将所有面转换为索引基元。一旦你建立了索引基元,你就可以构建关联表(使用 std::map(,这些表将边映射到人脸列表std::multimap<std::pair<Index, Index>, FaceIndex>,将边映射到使用这些边的人脸索引std::map<std::pair<VertexIndex, VertexIndex>, FaceIndex>等等。