1

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

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

4

2 回答 2

1

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

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

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

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

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

P = tA + (1-t)B

是在实数AB所在的线上。t

何时0 <= t <= 1P介于何时A和何时之间。B_P=At=1P=Bt=0

现在把它放到编程的角度来看,你可以创建两个类:PointLine. 使用上面给出的等式,很容易确定 a 是否Point位于给定的 上Line。要确定两条线段是否在同一条线上,只需使用Point定义一条线的两条线Line并检查它们是否位于另一条线上Line

于 2013-02-17T23:18:53.667 回答
0

如果 2 条线段是同一条线

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

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

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

IE

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),它将边缘映射到 faces 列表,std::multimap<std::pair<Index, Index>, FaceIndex>将边缘映射到使用这些边缘的 faces 索引std::map<std::pair<VertexIndex, VertexIndex>, FaceIndex>等等。

于 2013-02-18T01:46:29.157 回答