[Gambas-user] translating planar coordinates relative to point's angle

Kevin Fishburne kevinfishburne at ...1887...
Thu Mar 17 05:40:09 CET 2011


On 03/15/2011 05:03 PM, Doriano Blengino wrote:
> Kevin Fishburne ha scritto:
>>     Just to be clear on what -should- be happening, here's an example.
>>     Player is facing up (0 degrees): left stick pushed up moves up, pushed down
>>     moves down, pushed left moves left, pushed right moves right.
>>     Player is facing right (90 degrees): left stick pushed up moves right,
>>     pushed down moves left, pushed left moves up, pushed right moves down.
>>
> Well, you need to rotate the data from the left joystick around the
> player. This is the formula of rotation:
>    xr := xp*g92cos - yp*g92sin;
>    yr := xp*g92sin + yp*g92cos;
>
> Sorry, I took them from an old pascal program, but I explain.
> The above code rotates a point (xp; yp) around the origin, by a given
> angle "g92", of which g92cos and g92sin are the cosine and sine. The new
> rotated point is (xr; yr). Please note that 0 degrees is toward right,
> 90° up, 180 left, but a computer screen is flipped up side down (which
> is not a rotation but a mirror), so the y coordinates must be mirrored
> (choose the opposite sign if a coordinate is relative, or subtract the
> coordinate from the maximum Y coordinate if absolute). In addition, you
> say that 0° is up, and 90° right, which is both mirrored and rotated in
> respect to the canonical trigonometry... this kind of things can drive
> me crazy... :-)
>
> Back to the problem. If I well understand, at every frame you take the
> left joystick, and apply its "command" to the player. But the direction
> of the movement depends on the orientation of the player. Well, you take
> the left joystick data (x and y) and rotate them using the formulas
> above, basin on current player orientation. This way, when the left
> joystick slides up, the player will always move ahead, along its current
> direction. Now I will make an example.
>
> Suppose your player is at X=0 and Y=0, facing up (0 degrees), and you
> move the left joystick "up". You receive y=10 and x=0 from the left
> joystick. The above formula gives (cos(0)=1, sin(0)=0):
>    xr := xp*g92cos - yp*g92sin    = 0*1 - 10*0 = 0
>    yr := xp*g92sin + yp*g92cos   = 0*0 + 10*1 = 10
>
> So you add 0 to X and subtract 10 from Y (or add "-yr" to Y). The player
> moves up. Note that X is added and Y is subtracted because of the screen.
>
> Now, suppose that the player instead is facing right (90°). The formula
> gives (cos(90)=0, sin(90)=1:
>    xr := xp*g92cos - yp*g92sin    = 0*0 - 10*1 = -10
>    yr := xp*g92sin + yp*g92cos   = 0*1 + 10*0 = 0
>
> So you add -10 to X, and subtract 0 from Y. The player moves left. Why
> not to the right? Because if you rotate your head to the left, you turn
> 90 degrees, and if you turn your head to the right, you turn -90°. So if
> you say that 0° is up and 90° is right, there is something wrong. I hope
> that what I write is comprehensible...
>
> I don't know at which extent your program is already using this strange
> coordinates, so I prefer to elaborate no more (a little tired this
> night), but by inverting the readings from the joystick, and/or swapping
> X and Y from the joystick, or by using "90-angle" instead of "angle"
> when calculating cos() and sin(), you should quickly solve without
> touching the rest of the program. I presume you should use both
> "90-angle" and subtract from Y instead of adding to it, but I am not
> sure - sorry. In a few days I will go to visit those URLs you posted, I
> am always curious about math and videogames :-)

Doriano, you a genius. =) I adjusted my calculations based on your 
formulas and I'll be damned it if didn't work perfect on the first try. 
Amazing... Here's the code in gb:

' Move player relative to player's orientation.
worldx = worldx + (Interface.stick_leftx / 131072) * 
Cos(Rad(orientation)) - (Interface.stick_lefty / 131072) * 
Sin(Rad(orientation))
worldy = worldy + (Interface.stick_leftx / 131072) * 
Sin(Rad(orientation)) + (Interface.stick_lefty / 131072) * 
Cos(Rad(orientation))

For others who may read this in the future, the division by 131072 just 
compresses the movement range to -0.25 to 0.25 since the gamepad stick 
input goes from -32767 to 32767, so apply your own number as necessary.

Of course as soon as my celebration ended I realized I was now deep in 
the swamp of getting full-screen rotation working. I've made pretty good 
progress so far and surprisingly am actually learning a little new math 
(namely how to rotate point A around point B by angle X).

Thanks again Doriano.

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





More information about the User mailing list