[Gambas-user] the math behind full screen rotation

Kevin Fishburne kevinfishburne at ...1887...
Sun Mar 27 21:22:10 CEST 2011


On 03/26/2011 03:49 AM, Doriano Blengino wrote:
> Il 26/03/2011 04:08, Kevin Fishburne ha scritto:
>> On 03/24/2011 12:05 AM, John Spikowski wrote:
>>
>>> On Wed, 2011-03-23 at 23:03 -0400, Kevin Fishburne wrote:
>>>
>>>
>>>> That will probably work, but there should be a mathematical way to
>>>> compensate for not cropping the image twice, or even once. As long as
>>>> the entire image is preserved by the rotation function (it is) and it
>>>> behaves in a predictable manner (it does), the camera's coordinates
>>>> should be able to be translated and rotated so that they are in the same
>>>> position in the rotated image as they were in the non-rotated image. For
>>>> the sake of efficiency that is what I'm trying to accomplish.
>>>>
>>> This thread might help. (or not)
>>>
>>> http://forums.libsdl.org/viewtopic.php?t=2983&sid=1d2c6a94470c0fd56f3f542cd702ec37
>>>
>> No go, but thanks for trying to help. Right now my code looks something
>> like this:
>>
>>      ' Convert camera coordinates to their distance from the center of the
>> tile grid.
>>      newcx = newcx - (bworkspace.Width / 2)
>>      newcy = newcy - (bworkspace.Height / 2)
>>
>>      ' Rotate camera.
>>      newcx = Cos(Rad(- Client.orientation)) * newcx - Sin(Rad(-
>> Client.orientation)) * newcy
>>      newcy = Sin(Rad(- Client.orientation)) * newcx + Cos(Rad(-
>> Client.orientation)) * newcy
>>
>>      ' Adjust the camera coordinates to fit the rotated tile grid.
>>      newcx = newcx + (brotated.Width / 2)
>>      newcy = newcy + (brotated.Height / 2)
>>
>>      ' Draw the rotated workspace centered on the camera and cropped by
>> the render window size.
>>      Draw.Image(brotated, 0, 0, swidth, sheight, newcx - swidth / 2, newcy
>> - sheight / 2, swidth, sheight)
>>
>> First I figure out the distance of the camera from the center of the
>> non-rotated image. Then I rotate the camera using those distance values
>> as the camera's coordinates. That should in effect make the center of
>> the non-rotated image the origin of rotation. I then take the rotated
>> camera values and add them to the center point of the rotated image to
>> determine the camera's position in the rotated image.
>>
>> Maybe my logic is wrong, maybe it's my math. Maybe demons are hovering
>> over my shoulder casting black magic. I'm about to hit up Facebook for
>> an old math whiz I knew in high school, as gamedev.net has failed me as
>> well.<blood curdling Arnold scream from Predator>
>>
>>

Hi Doriano, thanks for helping. You're definitely getting your name in 
the game credits when it's done. :)

> Dear Kevin,
>
> if I well understand, you have to rotate your world around the player.
> To rotate a point around another arbitrary point (different from the
> origin), you must first translate the point, then rotate it, then
> translate it again in the original position. If you want I can give you
> a working routine to do so. Your code seems to do something similar,

Yes, I hope that's what my code is doing. Basically I find the distance 
of the camera from the center of the non-rotated image, whether negative 
or positive. That should mean that when I rotate those new coordinates, 
then add them to the center point of the rotated image, that they've 
effectively been rotated about the center of the rotated image. For 
example, if the camera in the non-rotated image is at (10,10) and the 
center of the non-rotated image is at (11,11), I'd do (10,10) - (11,11) 
= (-1,-1), rotate (-1,-1), then add the rotated values to the center 
point of the rotated image. Maybe that's all wrong, I don't know.

> but... should not the player always stay in the middle of the screen? If
> so, you need not to translate anything, but just rotate the original
> image. Or, perhaps, you want to reduce scrolling, so the player is not
> always in the middle? If there is not a true motivation, due to some
> game concept, to have different x/y positions of the player inside the
> screen, then it is much simpler to always keep the player in the middle.
> I try to explain in other words. Suppose that you can't get enough
> framerate when you rotate the world, so you try to minimize this, and
> let the player move around the screen. When the player reaches the
> boundary of the screen, you update the whole screen. Doing so, you speed
> up considerably. Nevertheless, when the player reaches a boundary, you
> must invoke anyway the "slow" routines to update the world. The net
> result is a stiffy game, which alternates fast movements with slow ones.

That is exactly what I'm doing because this is a tile-based game that 
uses a complex method of drawing and blending the tiles. Here's how it 
works, using real numbers this time.

First the camera is detached from the player, so the player's position 
for the sake of this discussion isn't important. The camera loosely 
follows the player using an algorithm to simulate natural camera 
movement. So the camera position is all that matters.

The landscape is broken into three progressively smaller chunks: the 
game world (data on server), the cell grid (data on client) and the tile 
grid (image on client). The world for testing purposes is currently 
4096x4096 tiles. The cell grid is a block of 96x96 tiles (3x3 cells of 
32x32 tiles), and is all the game client is aware of at any given time. 
Finally the tile grid is an image containing the rendered tile data of a 
subset of the cell grid, with the camera always being in the center 
tile. At 1280x720 the tile grid is 13x13 tiles, or 1664x1664 pixels, 
with the camera always being somewhere in tile (7,7).

When the camera moves out of the center tile of the tile grid, the tile 
grid is shifted one tile (128 pixels) in any of eight directions and a 
new row and/or column of tiles are drawn into it. The tile grid image is 
what's being rotated, and the camera never is farther than 64 pixels in 
any direction from the center of the tile grid image.

I've attached the relevant, abbreviated code. The function 
CellGrid2TileGrid() is being called to convert the camera's cell grid 
coordinates to tile grid coordinates. I believe the conversion function 
is working properly (scrolling works fine until the screen is rotated), 
but it may be worth a look. I've also recorded a video showing what is 
currently happening when the screen is rotated:

http://www.youtube.com/watch?v=iw64jcdNJY4

> I am also confused by our previous thread, where you rotated the player
> instead of the world. Not knowing enough, I can only say that you can,
> perhaps, gain some speed by doing calculations in the dead times
> (delays, if you have/use them). I have read that you reach speeds as
> high as 200 FPS or similar... if you reduce FPS to 25, you gain a lot of
> spare time to calculate ahead the new scenes (or perhaps not). If you
> explain better your ideas, may be I can try to give some advice.

That's a good idea, I will definitely consider doing that.

-- 
Kevin Fishburne
Eight Virtues
www:http://sales.eightvirtues.com
e-mail:sales at ...1887...
phone: (770) 853-6271

-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: rotation_failure
URL: <http://lists.gambas-basic.org/pipermail/user/attachments/20110327/80c2f9ff/attachment.ksh>


More information about the User mailing list