QB64 Phoenix Edition
Rotozoom without the skew - Printable Version

+- QB64 Phoenix Edition (https://staging.qb64phoenix.com)
+-- Forum: QB64 Rising (https://staging.qb64phoenix.com/forumdisplay.php?fid=1)
+--- Forum: Code and Stuff (https://staging.qb64phoenix.com/forumdisplay.php?fid=3)
+---- Forum: Utilities (https://staging.qb64phoenix.com/forumdisplay.php?fid=8)
+---- Thread: Rotozoom without the skew (/showthread.php?tid=1406)

Pages: 1 2


RE: Rotozoom without the skew - bplus - 01-21-2023

The skew problem arose from using different scales for x and y. If you (Steve) aren't doing that your code should be fine. Rotozoom2 went for years without detection of problem.


RE: Rotozoom without the skew - James D Jarvis - 01-21-2023

(01-21-2023, 07:10 PM)SMcNeill Wrote: I'll have to check later to see if my DisplayImage suffers from this same skew problem.  https://staging.qb64phoenix.com/showthread.php?tid=133

Yup, just checked it shows the skew on rotating when x and y aren't the same scale.


RE: Rotozoom without the skew - SMcNeill - 01-21-2023

(01-21-2023, 07:27 PM)James D Jarvis Wrote:
(01-21-2023, 07:10 PM)SMcNeill Wrote: I'll have to check later to see if my DisplayImage suffers from this same skew problem.  https://staging.qb64phoenix.com/showthread.php?tid=133

Yup, just checked it shows the skew on rotating when x and y aren't the same scale.

Hopefully I've fixed that.  (I followed your changes to rotozoom as a basic roadmap to my own changes, so I hope they're right now.)  At least, it seems to be working to me, but heck; I never noticed the problem to begin with!  I'ma gonna pretend that it's working now, until someone tells me that it isn't.  LOL!  Wink


RE: Rotozoom without the skew - SMcNeill - 01-21-2023

One thing I noticed tweaking DisplayImage, which you guys might want to go back and incorporate into your Rotozoom changes:

W& = _Width(Image&): H& = _Height(Image&)

Add a line below this one and make it:
W1& = W& *xScale: H1& = H& *yScale

Then when you do all the P(x) and P(y) calculations, you can use W1 and H1 and reduce the overall math in your routine, which would end up making it a little bit faster in the long run.  And, when it comes to graphics, any little speed boost (which as simple to implement as this one), is one that a programmer should always think about making use of.  Wink


RE: Rotozoom without the skew - James D Jarvis - 01-21-2023

(01-21-2023, 09:22 PM)SMcNeill Wrote: One thing I noticed tweaking DisplayImage, which you guys might want to go back and incorporate into your Rotozoom changes:

W& = _Width(Image&): H& = _Height(Image&)

Add a line below this one and make it:
W1& = W& *xScale: H1& = H& *yScale

Then when you do all the P(x) and P(y) calculations, you can use W1 and H1 and reduce the overall math in your routine, which would end up making it a little bit faster in the long run.  And, when it comes to graphics, any little speed boost (which as simple to implement as this one), is one that a programmer should always think about making use of.  Wink

Thank you for pointing that out.


RE: Rotozoom without the skew - James D Jarvis - 01-21-2023

updated routine(s)
Code: (Select All)
Sub RotoZoom23d (centerX As Long, centerY As Long, Image As Long, xScale As Single, yScale As Single, Rotation As Single)
    Dim px(3) As Single: Dim py(3) As Single
    Wi& = _Width(Image&): Hi& = _Height(Image&)
    W& = Wi& / 2 * xScale
    H& = Hi& / 2 * yScale
    px(0) = -W&: py(0) = -H&: px(1) = -W&: py(1) = H&
    px(2) = W&: py(2) = H&: px(3) = W&: py(3) = -H&
    sinr! = Sin(-0.01745329 * Rotation): cosr! = Cos(-0.01745329 * Rotation)
    For i& = 0 To 3
        x2& = (px(i&) * cosr! + sinr! * py(i&)) + centerX: y2& = (py(i&) * cosr! - px(i&) * sinr!) + centerY
        px(i&) = x2&: py(i&) = y2&
    Next
    _MapTriangle (0, 0)-(0, Hi& - 1)-(Wi& - 1, Hi& - 1), Image& To(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
    _MapTriangle (0, 0)-(Wi& - 1, 0)-(Wi& - 1, Hi& - 1), Image& To(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
End Sub

Sub RotoZoom23ds (centerX As Long, centerY As Long, Image As Long, xScale As Single, yScale As Single, Rotation As Single)
    Dim px(3) As Single: Dim py(3) As Single
    Wi& = _Width(Image&): Hi& = _Height(Image&)
    W& = Wi& / 2 * xScale
    H& = Hi& / 2 * yScale
    px(0) = -W&: py(0) = -H&: px(1) = -W&: py(1) = H&
    px(2) = W&: py(2) = H&: px(3) = W&: py(3) = -H&
    sinr! = Sin(-0.01745329 * Rotation): cosr! = Cos(-0.01745329 * Rotation)
    For i& = 0 To 3
        x2& = (px(i&) * cosr! + sinr! * py(i&)) + centerX: y2& = (py(i&) * cosr! - px(i&) * sinr!) + centerY
        px(i&) = x2&: py(i&) = y2&
    Next
    _MapTriangle _Seamless(0, 0)-(0, Hi& - 1)-(Wi& - 1, Hi& - 1), Image& To(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
    _MapTriangle _Seamless(0, 0)-(Wi& - 1, 0)-(Wi& - 1, Hi& - 1), Image& To(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
End Sub

Code: (Select All)
Sub RotoZoom_23r (centerX As Long, centerY As Long, Image As Long, xScale As Single, yScale As Single, Rotation As Single)
'uses radians
    Dim px(3) As Single: Dim py(3) As Single
    W& = _Width(Image&): H& = _Height(Image&)
    Wp& = W& / 2 * xScale
    Hp& = H& / 2 * yScale
    px(0) = -Wp&: py(0) = -Hp&: px(1) = -Wp&: py(1) = Hp&
    px(2) = Wp&: py(2) = Hp&: px(3) = Wp&: py(3) = -Hp&
    sinr! = Sin(-Rotation): cosr! = Cos(Rotation)
    For i& = 0 To 3
        ' x2& = (px(i&) * cosr! + sinr! * py(i&)) * xScale + centerX: y2& = (py(i&) * cosr! - px(i&) * sinr!) * yScale + centerY
        x2& = (px(i&) * cosr! + sinr! * py(i&)) + centerX: y2& = (py(i&) * cosr! - px(i&) * sinr!) + centerY
        px(i&) = x2&: py(i&) = y2&
    Next
    _MapTriangle (0, 0)-(0, H& - 1)-(W& - 1, H& - 1), Image& To(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
    _MapTriangle (0, 0)-(W& - 1, 0)-(W& - 1, H& - 1), Image& To(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
End Sub



RE: Rotozoom without the skew - bplus - 01-22-2023

(01-21-2023, 11:09 PM)James D Jarvis Wrote: updated routine(s)
Code: (Select All)
Sub RotoZoom23d (centerX As Long, centerY As Long, Image As Long, xScale As Single, yScale As Single, Rotation As Single)
    Dim px(3) As Single: Dim py(3) As Single
    Wi& = _Width(Image&): Hi& = _Height(Image&)
    W& = Wi& / 2 * xScale
    H& = Hi& / 2 * yScale
    px(0) = -W&: py(0) = -H&: px(1) = -W&: py(1) = H&
    px(2) = W&: py(2) = H&: px(3) = W&: py(3) = -H&
    sinr! = Sin(-0.01745329 * Rotation): cosr! = Cos(-0.01745329 * Rotation)
    For i& = 0 To 3
        x2& = (px(i&) * cosr! + sinr! * py(i&)) + centerX: y2& = (py(i&) * cosr! - px(i&) * sinr!) + centerY
        px(i&) = x2&: py(i&) = y2&
    Next
    _MapTriangle (0, 0)-(0, Hi& - 1)-(Wi& - 1, Hi& - 1), Image& To(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
    _MapTriangle (0, 0)-(Wi& - 1, 0)-(Wi& - 1, Hi& - 1), Image& To(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
End Sub

Sub RotoZoom23ds (centerX As Long, centerY As Long, Image As Long, xScale As Single, yScale As Single, Rotation As Single)
    Dim px(3) As Single: Dim py(3) As Single
    Wi& = _Width(Image&): Hi& = _Height(Image&)
    W& = Wi& / 2 * xScale
    H& = Hi& / 2 * yScale
    px(0) = -W&: py(0) = -H&: px(1) = -W&: py(1) = H&
    px(2) = W&: py(2) = H&: px(3) = W&: py(3) = -H&
    sinr! = Sin(-0.01745329 * Rotation): cosr! = Cos(-0.01745329 * Rotation)
    For i& = 0 To 3
        x2& = (px(i&) * cosr! + sinr! * py(i&)) + centerX: y2& = (py(i&) * cosr! - px(i&) * sinr!) + centerY
        px(i&) = x2&: py(i&) = y2&
    Next
    _MapTriangle _Seamless(0, 0)-(0, Hi& - 1)-(Wi& - 1, Hi& - 1), Image& To(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
    _MapTriangle _Seamless(0, 0)-(Wi& - 1, 0)-(Wi& - 1, Hi& - 1), Image& To(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
End Sub

Code: (Select All)
Sub RotoZoom_23r (centerX As Long, centerY As Long, Image As Long, xScale As Single, yScale As Single, Rotation As Single)
'uses radians
    Dim px(3) As Single: Dim py(3) As Single
    W& = _Width(Image&): H& = _Height(Image&)
    Wp& = W& / 2 * xScale
    Hp& = H& / 2 * yScale
    px(0) = -Wp&: py(0) = -Hp&: px(1) = -Wp&: py(1) = Hp&
    px(2) = Wp&: py(2) = Hp&: px(3) = Wp&: py(3) = -Hp&
    sinr! = Sin(-Rotation): cosr! = Cos(Rotation)
    For i& = 0 To 3
        ' x2& = (px(i&) * cosr! + sinr! * py(i&)) * xScale + centerX: y2& = (py(i&) * cosr! - px(i&) * sinr!) * yScale + centerY
        x2& = (px(i&) * cosr! + sinr! * py(i&)) + centerX: y2& = (py(i&) * cosr! - px(i&) * sinr!) + centerY
        px(i&) = x2&: py(i&) = y2&
    Next
    _MapTriangle (0, 0)-(0, H& - 1)-(W& - 1, H& - 1), Image& To(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
    _MapTriangle (0, 0)-(W& - 1, 0)-(W& - 1, H& - 1), Image& To(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
End Sub

+1 James and Steve I like the degree conversions washed out. Luv it when list of contributors gets to 4!
Thanks for updating this with Radians, I hope it's tested because I just added to my Tool box because I am betting it is! Smile

Update: now tested and the blue grid edges are better without _Seamless, good!