投影 3D 网格的 2D 轮廓算法

发布于 2024-07-25 03:00:12 字数 179 浏览 7 评论 0原文

给定:一个 3D 网格,由一组顶点和三角形定义,并用这些点构建网格。

问题:找到任意平面上投影的任意旋转网格的二维轮廓。

投影很容易。 挑战在于找到平面中投影三角形边的“外壳”。 我需要一些有关研究该算法的输入/指针的帮助。 为简单起见,我们可以假设 3D 边缘直接向下投影到 xy 平面上。

Given: A 3D mesh defined with a set of vertices and triangles building up the mesh with these points.

Problem: Find the 2d outline of the projected arbitrarily rotated mesh on an arbitrary plane.

The projection is easy. The challenge lies in finding the "hull" of the projected triangle edges in the plane. I need some help with input/pointers on researching this algorithm. For simplicity, we can assume the 3D edges are projected straight down onto the xy plane.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

仙女 2024-08-01 03:00:13

本问题中提到的 alpha 形状技术处理顶点连接未知的一组通用点:

有没有一种有效的算法来生成2D凹壳?

但是,由于您已经知道可以通过投影保留的“面部”信息,这可能不是最好的方法。

蛮力算法可能是可行的,特别是在使用空间排序结构的情况下。 例如,对于每个面:

  1. 将面投影到平面上
  2. 检查投影面是否完全被现有几何图形包围,如果是:完成(无需扩展投影轮廓)
  3. 如果点落在现有几何图形之外,则进行三角形-三角形相交以确定哪个点部分落在外面,构建一个任意的 n 边形(可能是凹面)来填充缺失的空间,然后将 n 边形切成三角形

另一个想法,根据您所需的保真度,只需从投影法线射出一束光线平面到原始几何形状。 创建 2d 命中/未命中并使用它来确定您的范围。

The alpha shapes technique mentioned in this question handles a general set of points where the vertex connections are not known:

Is there an efficient algorithm to generate a 2D concave hull?

However, since you already know "face" information which can be preserved through the projection, it is probably not the best approach.

A brute force algorithm might feasible, especially if spatial sorting structures where used. eg for each facet:

  1. Project facet on to the plane
  2. Check if projected facet is completely enclosed by existing geometry, if yes: done (no need to expand projected silhouette)
  3. If points fall outside the existing geometry, do triangle-triangle intersections to determine which portions fall outside, build an arbitrary n-gon (possibly concave) to fill the missing space, then chop the n-gon in to triangles

Another idea, depending on the fidelity you require, is just shoot a bunch of rays normal from your projection plane to your original geometry. Create a 2d hit/miss and use that to determine your extents.

楠木可依 2024-08-01 03:00:13

我只看到凸解的答案,所以这是我的非凸解的答案。
(意图是什么有点令人困惑。)

从 2D 三角形中取出所有边并将它们分组。 如果两条边共享两个端点,则它们位于同一组中。 所有只有一条边的组都是壳的一部分。

最后,您可以将壳边缘连接在一起,将它们组合成一个环。

I only see answers for convex solutions, so here is mine for non-convex.
(It was a little confusing what was the intention.)

Take all edges from your 2D-triangles and group them. If two edges share both endpoints, they are in the same group. All groups, with only one edge, is then a part of the shell.

Finally you can combine the shell-edges to one ring, by joining them together.

身边 2024-08-01 03:00:13

网格投影的 2D 轮廓是其边缘投影的子集。

利用这一观察结果,可以使用以下方法确定 2D 轮廓:

  • 仅属于一个面的每条边的投影是 2D 轮廓的一部分,
  • 对于其他边,确定其相邻面的法向量,
  • 计算这些边的点积法线与投影平面的法线
  • 如果点积的所有符号不相同(这意味着一个面指向投影平面,而至少一个面不指向投影平面),则该边的投影属于 2D 轮廓,它将边缘标识为轮廓的一部分)。

请注意,此方法将报告与投影平面正交的所有边缘,甚至是从投影平面的角度看不到的边缘。 例如,对于环面,即使环面旋转到从投影平面的角度看不到其内部孔,它也会找到内部和外部轮廓。 要确定哪些边缘可见,您将需要某种可见性测试。 如果预期用途是用于用户显示,则可以使用通过正交投影矩阵计算的深度缓冲区来从投影平面的角度渲染几何图形,并进行一些 z 测试以确定哪些边缘从平面可见。 如果需要精度,则需要执行射线/三角形相交以确定可见性。

The 2D outline of the mesh projection is a subset of the projection of its edges.

Using this observation, one can determine the 2D outline using the following method:

  • the projection of every edge belonging to only one face is part of the 2D outline,
  • for other edges, determine the normal vector of its adjacent faces
  • calculate the dot products of those normals with the normal of the plane of projection
  • the projection of this edge belongs to the 2D outline if all the signs of the dot products not the same (which means, one face is pointing towards the projection plane while at least one other doesn't, which identifies the edge as part of the outline).

Note that this method will report all the edges that are orthogonal to the projection plane, even those which are not visible from the projection plane's point of view. For example, with a torus, it will find the interior and the exterior outlines, even when the torus is rotated in such a way that its interior hole isn't visible from the projection plane's point of view. To sort out which edges are visible, you will need some sort of visibility test. If the intended use is for user display, you can use a depth buffer computed with an orthogonal projection matrix to render the geometry from the projection plane's point-of-view and do some z-testing to determine which edges are visible from the plane. If you need precision, you will need to perform ray/triangle intersection to determine visibility.

乖乖公主 2024-08-01 03:00:13
  1. 找到 x 为 min 的点
  2. 找到从该点开始的该点的所有边
  3. ,想象你有一根棍子(绿色),它顺时针滚动以找到它遇到的第一条边。 我们称其为 A 边。
    edge-A
  4. 查找该边 A 中的交点。 找到导致相交的边B,我们称其为inter-A,这个inter-A就是你的第二个轮廓点。
    edge-B
  5. 我们再想一想,在edge-B的两点之间,下一个是谁轮廓点。 连接 A 间和起始点 然后我们就可以“滚动棍子”来找到下一个轮廓点。 (候选点1就是那个)
    在此处输入图像描述
  6. 重复上述步骤,直到找到集合中已存在的点。

观看寻找兔子轮廓的演示
这是上述算法的实现

  1. Find the point whose x is min
  2. Find all edges for this point
  3. start from this point, imaging you have a stick (green), it rolls clock-wisely to find the first edge that it meets. Let's call it edge-A.
    edge-A
  4. Look for intersections in that edge-A. Find the edge-B that causes the intersection, let's call it inter-A, this inter-A is your second outline point.
    edge-B
  5. Let's then think, between the two points of edge-B, who is the next outline point. Link inter-A and the start point We can then "roll the stick" to find the next outline point. (candidate point 1 is the one)
    enter image description here
  6. repeat above steps until you find points that already exist in your collection.

see a demo of finding outline for a bunny
Here is an implementation of the algorithm described above.

末骤雨初歇 2024-08-01 03:00:12
  • 从最右边的点(x坐标最大的点)开始
  • 获取从该点开始的所有边
  • 沿着与正x轴夹角最小的边,同样将其添加到解集中
  • 从到达的点开始,跟踪并添加与您来自的边缘具有最小角度的边缘
  • 重复直到到达原始点
  • Start with the rightmost point (the point with the biggest x coordinate)
  • Get all edges from this point
  • Follow the edge with the smallest angle to the positive x-axis, and also add it to the solution set
  • From the point reached, follow and add the edge with the smallest angle to the edge you came from
  • Repeat until you reach the original point
去了角落 2024-08-01 03:00:12

只是补充一下:在投影中查找边缘的一种非常直观的方法是背面剔除! 剔除面和未剔除面之间的任何边缘都应该是轮廓。 如果你想隐藏内部边缘,只需使用 z 缓冲区即可。 背面剔除只是后投影顶点顺序,计算起来非常便宜。

Just to add: A very intuitive way to find edges in a projection is back face culling! Any edge between a culled and non-culled face should be an outline. If you want to hide interior edges, just use the z-buffer. Back face culling is simply the post projection vertex order and very cheap to compute.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文