RotateImage Changes Size of SquaresArchives Forums/Blitz3D Bug Reports/RotateImage Changes Size of Squares
| The problem I am having is with the ROTATEIMAGE command and rotating images that are square. When I rotate the image by 90, 180 or 270 degrees it should still be square and have the same dimensions as the original shape. I am using Blitz3D v1.103 and here some code which demonstrates how a 64x64 square when rotated 180 degrees is now 66x66. I have the same problem with other sizes and degrees of rotation.|
| Yep, same here.. very odd indeed!|
(incidentally, I am running v1.04 though there wasn't any changes to the 2D graphics stuff, so I didnt expect there to be any issue there)
Just as a test, I tried susbtituting TFromImage instead of RotateImage (for quad3 only), again, the size of the is 66x66
| Sorry for double post, but this is anotgher point of note:|
I tried various differing sizes, again, the value is always +2 on each side.
When I tried a large value (actually 1600) quad2 ALSO gave the result of 1602
I wondered if it may be related in anyway to the use of 24-bit depth somehow, or the resolution mode, but none of these made a difference.
| This is most likely a result of using a general routine for all rotations. There is no special code for "exact" cases like 90, 180 etc. The floating point calculations involved are approximate. Even the values of Sin and Cos are approximate. You might assume Cos(90) is exactly 0, but it's not.|
If you want exact results for 90, 180, 270 you should either write your own routine, which is easy enough, or use the TFormImage command. This let's you set exact values, such as exactly 0.0 rather that Cos(90).
| Why would floating point errors be different for, say 90 and 270 or -90 or -270 degrees?|
Or 180degrees and 540degrees?
If it was purely floating point inaccuracy, there would be consistency of error?
| Why should there be consistency?|
I think you are confusing theoretical and practical versions of Sin() and Cos(). These would be used to perform the rotation. They both have a period of exactly 360 degrees. But the hardware doesn't use degrees. It uses radians. That makes the period 2*Pi, which cannot be expressed exactly.
Graphics 500, 500, 0, 2 For n = 0 To 20 Print Sin( 360 * n ) Next WaitKey
If you want exact results for 90, 180, 270 you should either write your own routine, which is easy enough, or use the TFormImage command. This let's you set exact values,
I tried susbtituting TFromImage instead of RotateImage (for quad3 only), again, the size of the is 66x66
Whilst you'd think from its syntax TForm Image would work from a transformation matrix, it still produces the error, so perhaps it's doing the samwe thing behind the scenes, or RotateImage does the same as TFormImage.
Either way, it's not a solution, so as you state, Floyd, writing one's own routine would appear to be the best workaround here, Reading & Writing pixels from one image buffer to another.
| TFormImage uses the matrix you provide. It is exact if given exact values.|
For example, a 90 degree rotation is done with
TFormImage YourImage, 0, 1, -1, 0This uses the exact values 0,1 rather than the approximations Cos(90),Sin(90).
| Yet still results in the error.|
So it's NOT the floating point calculations that cause a problem?
I'm not trying to argue with you, Floyd, I'm trying to understand more about what the root cause of this may be, as it doesn't appear make any logical sense as to why the error only appears in some cases not others.
I would imagine that errors in calculation with regards to approximations would multiply the error according to scale or the angle used, since the error is always two pixels, though how and when they appear seems to be inconsistent across differing criteria, I am convinced that this size difference being two pixels irrespective of scale indicates that an extra 'line' is added to either side of the image.
| I noticed this in the versions.txt patch/update inf|
***** V1.35 *****
TFormImage/ScaleImage/ResizeImage/RotateImage fixed: the output size was being calculated incorrectly.
I wonder if tsomewhere along the lines, this has somehow gotten re-implemented?