我正在尝试使用 Vulkan 的模板缓冲区渲染轮廓。该技术涉及渲染对象两次,第二次放大以考虑所述轮廓。通常这是在 3D 空间中完成的,其中每个顶点的法 vector 可用于正确缩放对象。然而,我正在 2D 空间中尝试相同的操作,并且没有预先计算法线。
示例:给定坐标 I
、H
和 J
,我需要找到 L
, K
和M
,条件是每组平行 vector 之间的距离相同。
我尝试放大该对象,然后将其移动到正确的位置,但这却无济于事。
我正在寻找一种非常适用于 2D 空间中的任意形状并且也有些高效的解决方案。我也不确定这应该在 GPU 还是 CPU 上计算。
最佳答案
让我们绘制一些二维多边形的单个点的示例。
点M
的位置仅取决于A
及其两条相邻线的位置,我也添加了法线 - 绿色和蓝色。点 P
和 Q
线位于移位线和非移位线的交点上。
如果我们知道 A - B
、 C
的相邻点以及到 O
和 P
的距离,那么
M = A - d_p * normalize(B-A) - d_o * normalize(C-A)
这是正确的,因为 P、O
位于 B-A
和 C-A
线上。
距离很容易从双色直角三角形计算出来:
d_p=s/sin(alfa)
d_o=s/sin(alfa)
其中s
是所需的模板移位。它们当然是相同的。
因此,给定某个多边形角的 A,B,C
坐标和所需的位移 s
,整个计算为:
b = normalize(B-A) # vector
c = normalize(C-A) # vector
alfa = arccos(b.c) # dot product
d = s/sin(alfa)
M = A - sign(b.c) * (b+c)*d
这也证明了M
位于α角平分线上。
无论如何,该公式是通用的并且适用于任何 2D 多边形,它很容易并行化,因为每个点都独立于其他点进行移动。但是
- 对于非凸角,需要使用相反的符号,我们可以使用点积来概括。
- 当
b.c
接近于零时,即当b,c
线几乎平行时,它在数值上不稳定,在这种情况下,我建议只移动A
byd*n_b
其中n_b
是B-A
线的标准化法线,在 2D 中它是标准化((B.y - A.y, A.x -B.x))。
关于c++ - 在 2d 中缩放对象以精确地覆盖自身,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74247792/