Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Truezoom (fixing rotozoom)
#1
So I've noticed rotozoom wasn't reproducing images in 1 to 1 scaling (i.e. no scaling) properly. Here's a demo to show the issue and an attempt to correct it.

Code: (Select All)
'truezoomtest
'OCT 13,2023 10:30 EST
'
'working with rotozoom to draw lines I noted lines of even thickness were not drawing correctly
'I've suspected rotozoom wasn't rescaleing correctly for images of even height and weight for a while now
' but it was close enough for sprites and most uses but in drawing lines the issue was more obvious
'rotozoom is not reporduing images correctly when turning them in 90 degree units
'truezoom is an attempt at a soultion (I'be only tested it at a "scaling of 1" being more interested in rotating for now
'
'this program draws a pair of simple images and places them on the screen to compare the differences
'between the two routines
'it's a very minor change  and I've only done ot for 1 to 1 scaling for now
'
'in the demo I've had to manually adjuts the center point for the demonstration having not yet worked out how...
'...to properly adjust the center
'
'and yes... before someone mentions it displayimage has similar issues in reporducing the original image
'


Screen _NewImage(30, 50, 32)
Dim ai&, bi&
ai& = _NewImage(16, 16, 32)
bi& = _NewImage(16, 16, 32)

_FullScreen _SquarePixels
'prepare 2 images
_PrintMode _KeepBackground
Line (1, 1)-(14, 14), _RGB32(200, 0, 0), B
_PrintString (0, 0), "AB"
_PutImage (0, 0)-(15, 15), 0, ai&, (0, 0)-(15, 15)
Cls
Line (1, 1)-(14, 14), _RGB32(0, 200, 0), B
_PrintString (0, 0), "AB"
_PutImage (0, 0)-(15, 15), 0, bi&, (0, 0)-(15, 15)


'Show  image put in place
Cls
_PutImage (0, 0), ai&
drawruler
Sleep
'show image rotozoomed into place
RotoZoom23d 8, 8, ai&, 1, 1, 0
_PrintString (0, 25), "R"
drawruler
Sleep
'show image truezoomed into place
Cls
'_PutImage (0, 0), ai&
TrueZoom 8, 8, bi&, 1, 1, 0
_PrintString (0, 25), "T"
drawruler
Sleep
'show image rotozoomed with 90 turn
'have to account for x shift because center is  drawn at 8,8 otherwise
Cls
RotoZoom23d 7, 8, ai&, 1, 1, 90
drawruler
_PrintString (0, 25), "R"
Sleep
'show image truezoomed with 90 turn
'have to account for x shift because center is  drawn at 8,8 otherwise
Cls
TrueZoom 7, 8, bi&, 1, 1, 90
drawruler
_PrintString (0, 25), "T"
Sleep
'show image Rotozoomed with 180 turn
'have to account for x and y shift because center is  drawn at 8,8 otherwise

Cls
RotoZoom23d 7, 7, ai&, 1, 1, 180
drawruler
_PrintString (0, 25), "R"
Sleep
'show image truezoomed with 180 turn
'have to account for x and y shift because center is  drawn at 8,8 otherwise

Cls
TrueZoom 7, 7, bi&, 1, 1, 180
drawruler
_PrintString (0, 25), "T"
Sleep



Sub drawruler
    'just a few marks for this demo program
    Line (0, 0)-(15, 0), _RGB32(200, 0, 0)
    For x = 0 To 15 Step 2
        PSet (x, 0), _RGB32(200, 200, 200)
        PSet (16, x), _RGB32(200, 200, 200)
    Next x
End Sub


Sub TrueZoom (centerX As Single, centerY As Single, Image As Long, xScale As Single, yScale As Single, Rotation As Single)
    'rotate an image with Rotation defined in units of degrees, 0 is along x axis to the right gogin clockwise
    Dim px(3) As Single: Dim py(3) As Single
    Wi& = _Width(Image&): Hi& = _Height(Image&)
    W& = Wi& / 2 * xScale
    H& = (Hi& / 2) * yScale
    If Hi& Mod 2 Or Hi& < 2 Then
        px(0) = -W&: py(0) = -H&: px(1) = -W&: py(1) = H&
        px(2) = W&: py(2) = H&: px(3) = W&: py(3) = -H&
    Else
        px(0) = -W&: py(0) = -H&: px(1) = -W&: py(1) = H& - 1
        px(2) = W& - 1: py(2) = H& - 1: px(3) = W& - 1: py(3) = -H&

    End If
    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 RotoZoom23d (centerX As Single, centerY As Single, Image As Long, xScale As Single, yScale As Single, Rotation As Single)
    'rotate an image with Rotation defined in units of degrees, 0 is along x axis to the right gogin clockwise
    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
Reply
#2
I got the if then out of the earlier version.  This might work in images that are not scaled just 1 to 1 as well.
Code: (Select All)
'truezoomtest 2
'OCT 13,2023 4:45PM EST
'
'working with rotozoom to draw lines I noted lines of even thickness were not drawing correctly
'I've suspected rotozoom wasn't rescaleing correctly for images of even height and weight for a while now
' but it was close enough for sprites and most uses but in drawing lines the issue was more obvious
'rotozoom is not reporduing images correctly when turning them in 90 degree units
'truezoom is an attempt at a soultion
'
'this program draws a pair of simple images and places them on the screen to compare the differences
'between the two routines
'
'in the demo I've had to manually adjuts the center point for the demonstration having not yet worked out how...
'...to properly adjust the center
'
'and yes... before someone mentions it displayimage has similar issues in reporducing the original image
'


Screen _NewImage(30, 50, 32)
Dim ai&, bi&
ai& = _NewImage(16, 16, 32)
bi& = _NewImage(16, 16, 32)

_FullScreen _SquarePixels
'prepare 2 images
_PrintMode _KeepBackground
Line (1, 1)-(14, 14), _RGB32(200, 0, 0), B
_PrintString (0, 0), "AB"
_PutImage (0, 0)-(15, 15), 0, ai&, (0, 0)-(15, 15)
Cls
Line (1, 1)-(14, 14), _RGB32(0, 200, 0), B
_PrintString (0, 0), "AB"
_PutImage (0, 0)-(15, 15), 0, bi&, (0, 0)-(15, 15)


'Show  image put in place
Cls
_PutImage (0, 0), ai&
drawruler
Sleep
'show image rotozoomed into place
RotoZoom23d 8, 8, ai&, 1, 1, 0
_PrintString (0, 25), "R"
drawruler
Sleep
'show image truezoomed into place
Cls
'_PutImage (0, 0), ai&
TrueZoom2 8, 8, bi&, 1, 1, 0
_PrintString (0, 25), "T"
drawruler
Sleep
'show image rotozoomed with 90 turn
'have to account for x shift because center is  drawn at 8,8 otherwise
Cls
RotoZoom23d 7, 8, ai&, 1, 1, 90
drawruler
_PrintString (0, 25), "R"
Sleep
'show image truezoomed with 90 turn
'have to account for x shift because center is  drawn at 8,8 otherwise
Cls
TrueZoom2 7, 8, bi&, 1, 1, 90
drawruler
_PrintString (0, 25), "T"
Sleep
'show image Rotozoomed with 180 turn
'have to account for x and y shift because center is  drawn at 8,8 otherwise

Cls
RotoZoom23d 7, 7, ai&, 1, 1, 180
drawruler
_PrintString (0, 25), "R"
Sleep
'show image truezoomed with 180 turn
'have to account for x and y shift because center is  drawn at 8,8 otherwise

Cls
TrueZoom2 7, 7, bi&, 1, 1, 180
drawruler
_PrintString (0, 25), "T"
Sleep



Sub drawruler
    'just a few marks for this demo program
    Line (0, 0)-(15, 0), _RGB32(200, 0, 0)
    For x = 0 To 15 Step 2
        PSet (x, 0), _RGB32(200, 200, 200)
        PSet (16, x), _RGB32(200, 200, 200)
    Next x
End Sub



Sub TrueZoom2 (centerX As Single, centerY As Single, Image As Long, xScale As Single, yScale As Single, Rotation As Single)
    'rotate an image with Rotation defined in units of degrees, 0 is along x axis to the right gogin clockwise
    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& + (Hi& - 1) * yScale
    px(2) = -W& + (Wi& - 1) * xScale: py(2) = -H& + (Hi& - 1) * yScale: px(3) = -W& + (Wi& - 1) * xScale: 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 RotoZoom23d (centerX As Single, centerY As Single, Image As Long, xScale As Single, yScale As Single, Rotation As Single)
    'rotate an image with Rotation defined in units of degrees, 0 is along x axis to the right gogin clockwise
    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
Reply




Users browsing this thread: 2 Guest(s)