### Author Topic: A Little Trigonometry  (Read 19124 times)

#### AGP

• Posts: 1609
##### Re: A Little Trigonometry
« Reply #30 on: June 03, 2009, 07:58:59 pm »
Thanks, man, and I wish I could take credit for the model, but I bought it. :-) I'm preparing a website with a bunch of things I did over the years (since I didn't finish a lot there's a lot to do), but I'll be posting the links here as I finish them.

#### paulscode

• double
• Posts: 863
##### Re: A Little Trigonometry
« Reply #31 on: June 04, 2009, 02:03:55 am »
Ok, I made a test applet.  I found one problem with the formula I wrote - namely that it only produces a positive angle, so you can't simply use rotateZ() or the car will only rotate counterclockwise.  I fixed that problem by defining the rotationAxis as I mentioned in an earlier post:
Code: [Select]
`                SimpleVector rotationAxis = a.calcCross( b );                car.rotateAxis( rotationAxis, theta );`
This greatly improves the movement, but there is still a problem with some of the rotations being not quite right.  I'll work on this some more to see if I can solve the problem.

Here is the test applet (let me know if this is the same behavior you are seeing in your program):

#### AGP

• Posts: 1609
##### Re: A Little Trigonometry
« Reply #32 on: June 04, 2009, 03:07:21 am »
I applied your change and the result is conservative (it does most of the rotation, maybe 70% of it, but never quite enough). Also, since my streets always turn left, I didn't get to test a right turn, although I supposed your applet does. Here's a quick question: why doesn't the following code produce an even speed?

Code: [Select]
`float translationAmount = 72f/distance; //MOVE % OF distance THAT EQUALS 72SimpleVector directionMoved;directionMoved = moveTowardsMinusZ(opponentCar, rails[currentDirectionMarker], translationAmount);//THE DISTANCE IS UPDATED WHENEVER calculateDistance(opponentCar.getTransformedCenter(), rails[currentDirectionMarker]) < 1f AND currentDirectionMarker IS INCREMENTED//THEN THE MOVETOWARDS METHOD CALCULATES THE DELTAS:float deltaX = (direction.x -origin.x)*translationAmount;float deltaY = (direction.y -origin.y)*translationAmount;`

#### EgonOlsen

• Posts: 11885
##### Re: A Little Trigonometry
« Reply #33 on: June 04, 2009, 07:15:49 am »
Here's a quick question: why doesn't the following code produce an even speed?
Maybe because of an uneven frame rate? Just a wild guess...

#### AGP

• Posts: 1609
##### Re: A Little Trigonometry
« Reply #34 on: June 04, 2009, 08:06:13 am »
It's not supposed to be uneven, it sleeps 40 milliseconds, and draws. Obviously some parts of the model might take a little longer to render, but it should hardly be perceptible, and it really really is.

Egon, on yet a separate question (not to draw too much attention away from the bigger turning problem), how do I draw an image onto the buffer using the hardware renderer outside of an AWTGLCanvas? I've tried reading the lwjgl docs, but I found nothing there. I even tried looking for my C OpenGL programs of so many years ago, but I can't find them right now. Do you know?

#### EgonOlsen

• Posts: 11885
##### Re: A Little Trigonometry
« Reply #35 on: June 04, 2009, 08:21:58 am »
You could load the image into a texture and blit it. Or does it change constantly?

Edit: About the turning problem: Wasn't my approach sufficient?

#### EgonOlsen

• Posts: 11885
##### Re: A Little Trigonometry
« Reply #36 on: June 04, 2009, 08:24:01 am »
It's not supposed to be uneven, it sleeps 40 milliseconds, and draws. Obviously some parts of the model might take a little longer to render, but it should hardly be perceptible, and it really really is.
Have you printed out deltaX and deltaY to see how they actually change over time?

#### AGP

• Posts: 1609
##### Re: A Little Trigonometry
« Reply #37 on: June 04, 2009, 08:39:30 am »
Thanks for the blitting suggestion, I'm about to try it out. But yes, it's really an animated gif I want drawn (but at this point I'll settle for a static one).

And no, your approach constantly rotates the car in odd angles. The closest one so far has been paulscode's latest, but even that doesn't quite do it.

And I solved the speed issue (I was working from a constantly-updated carCenter). Sorry if I waste your time sometimes, but I really try not to. This particular question took me a couple of days to ask. I think something happens with me after I ask a question (unburden myself, I suppose!) that I think more clearly. So, down to two problems. :-)

#### EgonOlsen

• Posts: 11885
##### Re: A Little Trigonometry
« Reply #38 on: June 04, 2009, 09:06:53 am »
Well, if all you want to to rotate something to match another vectors direction, maybe getRotationMatrix() in SimpleVector helps to solve this? I usually prefer to work with matrices instead of euler angles...causes less trouble in the end.

#### AGP

• Posts: 1609
##### Re: A Little Trigonometry
« Reply #39 on: June 04, 2009, 09:22:18 am »
If you mean something like the following, it didn't do it for me either.

Code: [Select]
`opponentCar.setRotationMatrix(rails[currentDirectionMarker].getRotationMatrix());`

#### EgonOlsen

• Posts: 11885
##### Re: A Little Trigonometry
« Reply #40 on: June 04, 2009, 09:57:34 am »
But it should...are you sure that the problem isn't somewhere else? Maybe in the direction markers themselves?

#### paulscode

• double
• Posts: 863
##### Re: A Little Trigonometry
« Reply #41 on: June 04, 2009, 12:55:59 pm »
A note on constant speed (regardless of framerate).  I usually define a "distancePerMilli" float and a "lastTick" long:

Code: [Select]
`    private float distPerMilli = 0.018f;    private long lastTick;`
When initializing, I give "lastTick" its initial value:
Code: [Select]
`        lastTick = System.currentTimeMillis();`
Then when moving the object, I determine how long it's been since the last move, and calculate how far to move the object:
Code: [Select]
`        long currentTime = System.currentTimeMillis();        long millisPast = currentTime - lastTick;        lastTick = currentTime;        float distance = millisPast * distPerMilli;`
Then given a direction, I normalize, scalarMul by the distance, and apply the translation:
Code: [Select]
`SimpleVector trans = new SimpleVector( direction ).normalize();trans.scalarMul( distance );myObject.translate( trans );`
I also use this type of setup for rotations, special effects, and so on.  Higher framerates, of course, have smoother movement, but things will move the same speed for both high and low framerates.

#### AGP

• Posts: 1609
##### Re: A Little Trigonometry
« Reply #42 on: June 05, 2009, 01:11:59 am »
Egon, what kind of a problem could the direction markers have? I store the center of my car and the opponent car follows the markers perfectly.

And paulscode, thanks for the tip, but on a PC (where performance differences won't be that significant) isn't that a little bit overkill?

#### EgonOlsen

• Posts: 11885
##### Re: A Little Trigonometry
« Reply #43 on: June 05, 2009, 09:10:56 am »
You should always time your game logic based on ticks or real ms (whatever you prefer, i prefer ticks as they are easier to handle IMHO). Imagine the game running on a slow PC or with AA enabled or swapping causes a slow down or...

Could you provide the marker data in form of a simple ASCII-file or something? I would like to try this myself to see what's actually going on. Getting the rotation matrix out of the direction vector and apply it has to work IMHO...