Truezoom (fixing rotozoom) - James D Jarvis - 10-13-2023
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
RE: Truezoom (fixing rotozoom) - James D Jarvis - 10-13-2023
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
|