I am trying to compute a panoramic projection for dental imaging purpose.
I have a rectangle surface "curved" in one direction by a piecewise function. If we look at it from the top, it looks like a regular piecewise function.
The "piecewise linear function" is just defined by a set of 3D points. All the points are in the same plane. The plane where all the 3D points sit is orthogonal to the curved surface
(see the green line in the top-left window)
I am looking for the proper way to "flatten" it. (non linear transform)
The flat surface should have the same "length" as the curved one. (it is not a classic orthogonal projection)
Ultimately, I will use the "flat surface" as a canvas to display the information of interest.
(Bottom window)
Best,
I see it like this:
I would:
P0,P1,P2
from your curvecompute 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|
so A,B
is just P0 +/- V0
and C,D
is P1 +/- V1
. In the cross product Use any vector non parallel with U0,U1
I chose (0,0,1)
but in case it si parallel chose any other...
make the ABCD
a recangle
So compute A'B'C'D'
for example
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
Where sizex,sizey
is the size of rectangle segment. You can also use |U0|,|V0|
but in that case the start x
will be integrated curve length.
compute transformation between ABCD
and A'B'C'D'
so for each pixel P inside ABCD
compute (x,y)
inside A'B'C'D'. The
x` is easy:
x = A'.x + dot(P-P0,U0)/|P-P0|
y
is tricky and need some tweaking to suite your needs (so the result is smooth to your liking). For starters try simple approach (will lead to seams between segments)
y = (A'.y+B'.y)/2 + dot(P-P),V0)/|P-P0|
Now just copy the pixel at position P
into your target image at position (x,y)
To make this more smooth you can make V
interpolated between V0,V1
dependent on the dot(P-P0,U0)/(|P-P0|*|U0|)
so it will change seamlessly.
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|
If you need help with determining if point is inside then pixel P
is inside if
dot(P-P0,U0)/(|P-P0|*U0) = <0.0,1.0>
loop #1 for all segments of the curve
step by single sample point of curve (not by 3 ...)