Originally Posted by
mpolak
X Axis:
shear: add coefficient * Y
keystone: add coefficient * (X * Y)
linearity: add coefficient * (X^2)
bow: add coefficient * (Y^2)
pincushion: add coefficient * (X * Y^2)
Y Axis:
shear: add coefficient * X
keystone: add coefficient * (X * Y)
linearity: add coefficient * (Y^2)
bow: add coefficient * (X^2)
pincushion: add coefficient * (Y * X^2)
I'll try to keep an eye on this thread for replies, but due to my busy schedule I'm really not on here much.
So... Go Forth And Make Ye Geometrically-Corrected Laser Output Such That Thy May Convolve To Many An Oddly Shaped Surface And Still Looketh Great! (Oh, and do not bloweth up thy scanners with thy oversize correction coefficients!)
Hello M. Polak,
Also please allow me bump this thread one again and to offer you great thanks for this post. Unbelievably easy to implement this in software for my ESP32 based test box and ILDA/WAV player ILDAC-WAV (see: https://ildac.com) . I can't quite wrap my head around why the simple math works, but it just works! And it's really really cool.
I used the C code you supplied essentially unchanged. Wow. I did have to convert my unsigned 12-bit XY coordinates to -1 to 1 floats (and back out again), but that was easy.
And I noticed in the assembler code you included "Edge Rotation" (which is a COOL effect!) but in not the C code. I went to convert these to C like the others, but the comments on the "cm" and "lamc" lines threw me for a loop. I was knocking my head around trying to figure out what X*X and Y*Y were doing in the lamc line comments. So just in case other people are also looking at this code in the future, I made a few suggestions below to fix the comments for pincushion and edge rotation below.
And as per your ASM code, you have the following pre-calculated in the accumulators:
(X*X*Y) in $105
(Y*Y*X) in $106
Here's your original source for pincushion and edge rotation with my suggested changes as "<--"
; Do "X Pincushion" term
cm 1.0 $106 ; load X*X*Y into accumulator <-- $106 is Y*Y*X
lamc 0.0 $018 ; multiply accumulator (X*X) by X_Pincushion and place in accumulator, add 0.0 <-- should be (Y*Y*X)
; Do "Y Pincushion" term
cm 1.0 $105 ; load Y*Y*X into accumulator <-- $105 is X*X*Y
lamc 0.0 $019 ; multiply accumulator (Y*Y) by Y_Pincushion and place in accumulator, add 0.0 <-- should be (X*X*Y)
; Do "X Edge Rotation" term
cm 1.0 $105 ; load Y*Y*X into accumulator <-- $105 is X*X*Y -- Y*Y*X would be the same as pincushion X
lamc 0.0 $01A ; multiply accumulator (X*X) by X_EdgeRotation and place in accumulator, add 0.0 <-- should be (X*X*Y)
; Do "Y Edge Rotation" term
cm 1.0 $106 ; load X*X*Y into accumulator <-- $106 is Y*Y*X -- X*X*Y would be the same as pincushion Y
lamc 0.0 $01B ; multiply accumulator (Y*Y) by Y_EdgeRotation and place in accumulator, add 0.0 <-- should be (Y*Y*X)
So here's the full code with the suggested updates:
Code:
; Do "X Pincushion" term
cm 1.0 $106 ; load Y*Y*X into accumulator
lamc 0.0 $018 ; multiply accumulator (Y*Y*X) by X_Pincushion and place in accumulator, add 0.0
lca 1.0 $110 ; retrieve running X term into B register
cab 1.0 ; add B register to accumulator
sca 1.0 $110 ; store to running X term memory $110
; Do "Y Pincushion" term
cm 1.0 $105 ; load X*X*Y into accumulator
lamc 0.0 $019 ; multiply accumulator (X*X*Y) by Y_Pincushion and place in accumulator, add 0.0
lca 1.0 $111 ; retrieve running Y term into B register
cab 1.0 ; add B register to accumulator
sca 1.0 $111 ; store to running Y term memory $111
; Do "X Edge Rotation" term
cm 1.0 $105 ; load X*X*Y into accumulator
lamc 0.0 $01A ; multiply accumulator (X*X*Y) by X_EdgeRotation and place in accumulator, add 0.0
lca 1.0 $110 ; retrieve running X term into B register
cab 1.0 ; add B register to accumulator
sca 1.0 $110 ; store to running X term memory $110
; Do "Y Edge Rotation" term
cm 1.0 $106 ; load Y*Y*X into accumulator
lamc 0.0 $01B ; multiply accumulator (Y*Y*X) by Y_EdgeRotation and place in accumulator, add 0.0
lca 1.0 $111 ; retrieve running Y term into B register
cab 1.0 ; add B register to accumulator
sca 1.0 $111 ; store to running Y term memory $111
And here's the additional C code for the edge rotation effect:
Code:
// do rotation
if (xAxis.rotation) x += xAxis.rotation * (pY * pX * pX); // XXY
if (yAxis.rotation) y += yAxis.rotation * (pX * pY * pY); // YYX
It's really interesting that these two effects (pincushion and edge rotation) are just swapping out the YYX and XYY coefficients between X and Y, but the resulting effects are very different!
Again, thank you for sharing this. I had so much fun learning this and adding it to my project. I will make sure you received proper credit where due.
-Hank