c++ - 在 2d 中缩放对象以精确地覆盖自身

标签 c++ algorithm math glsl 2d

我正在尝试使用 Vulkan 的模板缓冲区渲染轮廓。该技术涉及渲染对象两次,第二次放大以考虑所述轮廓。通常这是在 3D 空间中完成的,其中每个顶点的法 vector 可用于正确缩放对象。然而,我正在 2D 空间中尝试相同的操作,并且没有预先计算法线。

illustration

示例:给定坐标 IHJ,我需要找到 LKM,条件是每组平行 vector 之间的距离相同。

我尝试放大该对象,然后将其移动到正确的位置,但这却无济于事。

我正在寻找一种非常适用于 2D 空间中的任意形状并且也有些高效的解决方案。我也不确定这应该在 GPU 还是 CPU 上计算。

最佳答案

让我们绘制一些二维多边形的单个点的示例。

Triangle shift

M的位置仅取决于A及其两条相邻线的位置,我也添加了法线 - 绿色和蓝色。点 PQ 线位于移位线和非移位线的交点上。

如果我们知道 A - BC 的相邻点以及到 OP 的距离,那么

M = A - d_p * normalize(B-A) - d_o * normalize(C-A)

这是正确的,因为 P、O 位于 B-AC-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 by d*n_b 其中 n_bB-A 线的标准化法线,在 2D 中它是标准化((B.y - A.y, A.x -B.x))。

关于c++ - 在 2d 中缩放对象以精确地覆盖自身,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74247792/

相关文章:

c++ - NxM 网格上的平行四边形数

java - 通过数据库或算法比较不同日期的两个对象

javascript 非顺序随机数生成器

c++ - 如何在第一次输入后立即停止 C++ 控制台关闭

c++ - 重载函数with (unsigned chars,传char,保证不编译?

algorithm - 重叠区间

Javascript积分计算系统

c++ - 使用C++查找直线中的第三个点

c++ - 使用 gl3w 的 OpenGL

c++ - gstreamermm和Qt编译错误