压平曲面
Flatten curved surface
我正在尝试计算用于牙科成像的全景投影。
我通过分段函数在一个方向上有一个矩形表面 "curved"。如果我们从顶部看它,它看起来像一个常规的分段函数。
"piecewise linear function" 只是由一组 3D 点定义。
所有的点都在同一个平面上。所有 3D 点所在的平面与曲面正交
(见左上角的绿线window)
我正在寻找 "flatten" 它的正确方法。 (非线性变换)
平面应该和曲面一样"length"。 (不是经典的正交投影)
最终,我将使用"flat surface"作为canvas显示感兴趣的信息。
(底部window)
最佳,
我是这样看的:
我会:
- 从曲线中取 3 个后续点
P0,P1,P2
计算U0,V0,U1,V1
U0 = P1-P0
U1 = P2-P1
V0 = cross(U0,(0,0,1)); V0=half_height/|V0|
V1 = cross(U1,(0,0,1)); V1=half_height/|V1|
所以 A,B
就是 P0 +/- V0
而 C,D
就是 P1 +/- V1
。在叉积中使用与 U0,U1
不平行的任何向量我选择了 (0,0,1)
但如果它平行选择任何其他...
使 ABCD
重新排列
所以计算A'B'C'D'
例如
A'.x = B'.x = index_of(P0) * sizex
C'.x = D'.x = index_of(P0) * sizex + sizex
A'.y = D'.y = sizey
B'.y = C'.y = 0
其中sizex,sizey
是矩形段的大小。您也可以使用 |U0|,|V0|
,但在这种情况下,起点 x
将是综合曲线长度。
计算ABCD
和A'B'C'D'
之间的转换
所以对于 ABCD
内的每个像素 P 计算 A'B'C'D'. The
x` 内的 (x,y)
很容易:
x = A'.x + dot(P-P0,U0)/|P-P0|
y
很棘手,需要进行一些调整以满足您的需求(因此结果很顺畅,符合您的喜好)。对于初学者尝试简单的方法(将导致段之间的接缝)
y = (A'.y+B'.y)/2 + dot(P-P),V0)/|P-P0|
现在只需将位置 P
的像素复制到目标图像的位置 (x,y)
为了使这更平滑,您可以使 V
根据 dot(P-P0,U0)/(|P-P0|*|U0|)
在 V0,V1
之间进行插值,这样它将无缝更改。
t = dot(P-P0,U0)/(|P-P0|*|U0|)
V = V0 + (V1-V0)*t
y = (A'.y+B'.y)/2 + dot(P-P),V)/|P-P0|
如果您需要帮助确定点是否在内部,则像素 P
在内部 if
dot(P-P0,U0)/(|P-P0|*U0) = <0.0,1.0>
曲线所有段的循环#1
按曲线的单个样本点步进(不是按 3 ...)
我正在尝试计算用于牙科成像的全景投影。
我通过分段函数在一个方向上有一个矩形表面 "curved"。如果我们从顶部看它,它看起来像一个常规的分段函数。
"piecewise linear function" 只是由一组 3D 点定义。 所有的点都在同一个平面上。所有 3D 点所在的平面与曲面正交
(见左上角的绿线window)
我正在寻找 "flatten" 它的正确方法。 (非线性变换)
平面应该和曲面一样"length"。 (不是经典的正交投影)
最终,我将使用"flat surface"作为canvas显示感兴趣的信息。
(底部window)
最佳,
我是这样看的:
我会:
- 从曲线中取 3 个后续点
P0,P1,P2
计算
U0,V0,U1,V1
U0 = P1-P0 U1 = P2-P1 V0 = cross(U0,(0,0,1)); V0=half_height/|V0| V1 = cross(U1,(0,0,1)); V1=half_height/|V1|
所以
A,B
就是P0 +/- V0
而C,D
就是P1 +/- V1
。在叉积中使用与U0,U1
不平行的任何向量我选择了(0,0,1)
但如果它平行选择任何其他...使
ABCD
重新排列所以计算
A'B'C'D'
例如A'.x = B'.x = index_of(P0) * sizex C'.x = D'.x = index_of(P0) * sizex + sizex A'.y = D'.y = sizey B'.y = C'.y = 0
其中
sizex,sizey
是矩形段的大小。您也可以使用|U0|,|V0|
,但在这种情况下,起点x
将是综合曲线长度。计算
之间的转换ABCD
和A'B'C'D'
所以对于
ABCD
内的每个像素 P 计算A'B'C'D'. The
x` 内的(x,y)
很容易:x = A'.x + dot(P-P0,U0)/|P-P0|
y
很棘手,需要进行一些调整以满足您的需求(因此结果很顺畅,符合您的喜好)。对于初学者尝试简单的方法(将导致段之间的接缝)y = (A'.y+B'.y)/2 + dot(P-P),V0)/|P-P0|
现在只需将位置
P
的像素复制到目标图像的位置(x,y)
为了使这更平滑,您可以使
V
根据dot(P-P0,U0)/(|P-P0|*|U0|)
在V0,V1
之间进行插值,这样它将无缝更改。t = dot(P-P0,U0)/(|P-P0|*|U0|) V = V0 + (V1-V0)*t y = (A'.y+B'.y)/2 + dot(P-P),V)/|P-P0|
如果您需要帮助确定点是否在内部,则像素
P
在内部 ifdot(P-P0,U0)/(|P-P0|*U0) = <0.0,1.0>
曲线所有段的循环#1
按曲线的单个样本点步进(不是按 3 ...)