flat assembler
Message board for the users of flat assembler.

 Index > Heap > For the mathematically inclined Goto page 1, 2  Next
Author
kohlrak

Joined: 21 Jul 2006
Posts: 1421
kohlrak
I've been trying to make a simple OpenGL app (in C until i get the math down) for the longest time now (a few years actually), however I clearly don't have the math background nor can i seem to find the answer on google (or am i just that bad at googling?).

I need to rotate an object on it's local axis (x, y, and z) then use that rotation to translate that object (x, y, and z again) with global coordinates (for cheap collision detection). I haven't even been able to get myself to even move the camera (well, the world around position 0) without loosing control of the camera at 180 degrees on the Y axis of rotation (and that's without considering the Z).

Anyone want to point me in the right direction?
22 Apr 2010, 03:08
ass0

Joined: 31 Dec 2008
Posts: 521
Location: ( . Y . )
ass0

_________________

Nombre: Aquiles Castro.
22 Apr 2010, 04:25
kohlrak

Joined: 21 Jul 2006
Posts: 1421
kohlrak
ass0 wrote:

Thanks, i'll see what these can get me.
22 Apr 2010, 05:07
bitshifter

Joined: 04 Dec 2007
Posts: 764
Location: Massachusetts, USA
bitshifter
My fps camera demo does what you need...
http://board.flatassembler.net/topic.php?t=9262
I can provide C-code if you are still confused...

Basically you can use two methods to get same result...
1) Transform the object while camera stays still.
2) Transform the camera while object stays still.
My demo transforms the camera...

Most of the math is hidden in matrix form and is
worked upon using glTranslate/glRotate/glScale.
I have handrolled matrix routines that expose this math
which are part of my 3D software rendering project...

Also my engine uses ellipsoid collision detection based on this paper...

22 Apr 2010, 07:03
edfed

Joined: 20 Feb 2006
Posts: 4237
Location: 2018
edfed
to rotate a 3D point:
obtain the module of the point.
then, m=(x²+y²)^(1/2)
this operation is not made in practice.

point dd x,y,z

angle dd ax,ay,az (in degree)

calculate cos and sin for each angles.
then, cosx, sinx, cosy,siny, cosz,sinz

and then, compute the new points like this:

rotate on z
x=x*cosz-y*sinz
y=y*cosz-x*sinz

rotate on x
y=y*cosx-z*sinx
z=z*cosx+y*sinx

rotate on y
x=x*cosy-z*siny
z=z*cosy+x*siny

the problem with 3D rotation is that you can have two kinds of rotations.
relative to absolut origin, and relative to local origin.
the solution there is relative to absolut origin.

for local origin, it is a bit more complicated because you should for example rotate on z (will inclinate), then, rotate on y turn left or right(resulting in a combinaison of rotations...and rotate on x, up or down...

in absolute rotation, it is like in the formula, but for relative to object, it is not easy.
22 Apr 2010, 10:38
kohlrak

Joined: 21 Jul 2006
Posts: 1421
kohlrak
bitshifter wrote:
My fps camera demo does what you need...
http://board.flatassembler.net/topic.php?t=9262
I can provide C-code if you are still confused...

Basically you can use two methods to get same result...
1) Transform the object while camera stays still.
2) Transform the camera while object stays still.
My demo transforms the camera...

Most of the math is hidden in matrix form and is
worked upon using glTranslate/glRotate/glScale.
I have handrolled matrix routines that expose this math
which are part of my 3D software rendering project...

Not quite what i'm looking for. I'm thinking more along the lines of flight instead of walking.

Quote:
Also my engine uses ellipsoid collision detection based on this paper...

However, this is the next step after i do get this much working.

edfed wrote:
to rotate a 3D point:
obtain the module of the point.
then, m=(x²+y²)^(1/2)
this operation is not made in practice.

point dd x,y,z

angle dd ax,ay,az (in degree)

calculate cos and sin for each angles.
then, cosx, sinx, cosy,siny, cosz,sinz

and then, compute the new points like this:

rotate on z
x=x*cosz-y*sinz
y=y*cosz-x*sinz

rotate on x
y=y*cosx-z*sinx
z=z*cosx+y*sinx

rotate on y
x=x*cosy-z*siny
z=z*cosy+x*siny

the problem with 3D rotation is that you can have two kinds of rotations.
relative to absolut origin, and relative to local origin.
the solution there is relative to absolut origin.

for local origin, it is a bit more complicated because you should for example rotate on z (will inclinate), then, rotate on y turn left or right(resulting in a combinaison of rotations...and rotate on x, up or down...

in absolute rotation, it is like in the formula, but for relative to object, it is not easy.

A few questions...

1. Let's say i have function f(x,y,z)... How exactly would i go about getting all 3 at the same time?

2. How much worse is local origin (doing research i'm finding fancy phrases like quaternion and such)? Do i just apply those equations I see there in series?

3. Is there any way to get this stuff from the glMatrices (and thus allowing me to try to reverse that to understand and optimize)?

To clarify: I'm aiming for a spacial object capable of turning off of any axis after any rotation along with the camera capable of turning aff any axis after any rotation. Although, right now, i'm only asking for something that looks like
Code:
```Rotate(x, y, z);
Move(d);    ```
i'm hoping to eventually understand this enough to make
Code:
```Rotate(x, y, z);
Move(X, Y, Z, curpos[3]);
glTranslatef(curpos[0],curpose[1],curpos[2]);
checkCollide(curpos);    ```
22 Apr 2010, 12:23
baldr

Joined: 19 Mar 2008
Posts: 1651
baldr
edfed wrote:
in absolute rotation, it is like in the formula, but for relative to object, it is not easy.
Why do you think it's not easy? Arbitrary rotation of (x, y, z) around (x0, y0, z0) can be expressed as the same rotation of (x-x0, y-y0, z-z0) around origin (0, 0, 0), translated by (x0, y0, z0). I mean that if (x', y', z') is (x-x0, y-y0, z-z0) rotated some way around (0, 0, 0), then (x'+x0, y'+y0, z'+z0) is (x, y, z) rotated the same way but around (x0, y0, z0).

----8<----
kohlrak,

1. Use structure to define point's coordinates and pass pointer to it as argument for function.

2. Not a much worse. Linear transformations can be combined together easily; however, the order is important (in general case).

3. Appendix F of OpenGL Programming Guide contains explanation of transformation matrices that are generated by glTranslate, glScale and such functions. Basic trigonometry required, though.
22 Apr 2010, 14:17
kohlrak

Joined: 21 Jul 2006
Posts: 1421
kohlrak
baldr wrote:
edfed wrote:
in absolute rotation, it is like in the formula, but for relative to object, it is not easy.
Why do you think it's not easy? Arbitrary rotation of (x, y, z) around (x0, y0, z0) can be expressed as the same rotation of (x-x0, y-y0, z-z0) around origin (0, 0, 0), translated by (x0, y0, z0). I mean that if (x', y', z') is (x-x0, y-y0, z-z0) rotated some way around (0, 0, 0), then (x'+x0, y'+y0, z'+z0) is (x, y, z) rotated the same way but around (x0, y0, z0).

I know what he's talking about, actually. It's called local axis vs world axis. It's instantly complicated after an object gets translated. IIRC, the solution is merely carefully planning your rotates and translates.

Quote:

2. Not a much worse. Linear transformations can be combined together easily; however, the order is important (in general case).

Just like the glRotatef, then.

Quote:
3. Appendix F of OpenGL Programming Guide contains explanation of transformation matrices that are generated by glTranslate, glScale and such functions. Basic trigonometry required, though.

Hm, that might help a bit. I have a feeling though that when i do figure it out, i'll be able to move a translation around 0, but not from an already translated point, but if that's the case i guess i can post again.

Thank you all for your hlep.
22 Apr 2010, 20:25
edfed

Joined: 20 Feb 2006
Posts: 4237
Location: 2018
edfed
i have just a little idea... first, try to do the rotation in 3D, then, only on Zaxis.
manage it the best possible.
and after, it will be easy to go in 3D...

hem...
in fact, for local roations, i think one important thing is to rotate the sin, cos of other angles too.

then, on a Z axis rotation, you will be forced to rotate the X(sin,cos) and Y(sin,cos). i think it is the reason why it is complicated.
22 Apr 2010, 21:17
bitshifter

Joined: 04 Dec 2007
Posts: 764
Location: Massachusetts, USA
bitshifter
Here's a good collection of resources to browse...
http://www.gamedev.net/reference/
23 Apr 2010, 05:48
kohlrak

Joined: 21 Jul 2006
Posts: 1421
kohlrak
bitshifter wrote:
Here's a good collection of resources to browse...
http://www.gamedev.net/reference/

You know, i saw this site before and when i looked for "plane physics" and found nothing i thought it was worthless. Now that i've seen what i need to be looking for instead, she seems much more useful. Thank you.
23 Apr 2010, 09:31
bitshifter

Joined: 04 Dec 2007
Posts: 764
Location: Massachusetts, USA
bitshifter
If i were to write a flight simulator...
I would use vectors such as RIGHT/FRONT/UP
Then just add velocity to FRONT vector and we go forward.
By rotating around FRONT vector we can roll the aircraft.
By rotating around the RIGHT vector we could pitch the aircraft.

Study the CrossProduct and you will see that:
RIGHT = CrossProduct(FRONT,UP)
FRONT = CrossProduct(RIGHT,UP)
UP = CrossProduct(RIGHT,FRONT)

A little research on vectors and matrices is what you will need
23 Apr 2010, 15:40
edfed

Joined: 20 Feb 2006
Posts: 4237
Location: 2018
edfed
pitch, roll, yaw.
tree names for tree rotations types.

a good way to understand these rotations is... bring an object in the hand, and make it rotate.

good luck.
23 Apr 2010, 18:06
kohlrak

Joined: 21 Jul 2006
Posts: 1421
kohlrak
bitshifter wrote:
If i were to write a flight simulator...
I would use vectors such as RIGHT/FRONT/UP
Then just add velocity to FRONT vector and we go forward.
By rotating around FRONT vector we can roll the aircraft.
By rotating around the RIGHT vector we could pitch the aircraft.

Study the CrossProduct and you will see that:
RIGHT = CrossProduct(FRONT,UP)
FRONT = CrossProduct(RIGHT,UP)
UP = CrossProduct(RIGHT,FRONT)

A little research on vectors and matrices is what you will need

This is elementary. I can figure out the Rotate and Translate functions, the part that's getting to me is how to rotate a translate. How to move off that rotation, since once i use the Rotatef function, i can no longer get the world coordinates for the object moved. So, i have to go farther than that and move manually. With time, i'll have this figured out (and maybe i'll update this post with some code when i figure out how to do this with quats to avoid gimbal lock).
23 Apr 2010, 19:25
bitshifter

Joined: 04 Dec 2007
Posts: 764
Location: Massachusetts, USA
bitshifter
A quaternion based system would be nice and easy for flight simulation.
Here are the two that i remember learning much from...
http://www.gamedev.net/reference/programming/features/quatcam/default.asp
http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=Quaternion_Camera_Class

Also some more good reference i liked...
http://www.codecolony.de/OpenGL/
See last lesson especially (Looking at the camera)

But when i think of minimal instructions to get-er-done
i always think that a rotation based system is the best way...
23 Apr 2010, 23:13
kohlrak

Joined: 21 Jul 2006
Posts: 1421
kohlrak
bitshifter wrote:
A quaternion based system would be nice and easy for flight simulation.
Here are the two that i remember learning much from...
http://www.gamedev.net/reference/programming/features/quatcam/default.asp

Quote:
http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=Quaternion_Camera_Class

Looked at it before, but got this:

Quote:
kohlrak@kohlrak-laptop:~/Desktop/firefoxdump/quaternion_camera_class\$ make
g++ -c Quaternion_Camera_Class.cc -I/usr/X11R6/include -O2
Quaternion_Camera_Class.cc:52: error: ‘<anonymous>’ has incomplete type
Quaternion_Camera_Class.cc:52: error: invalid use of ‘GLvoid’
Quaternion_Camera_Class.cc:84: error: ‘<anonymous>’ has incomplete type
Quaternion_Camera_Class.cc:84: error: invalid use of ‘GLvoid’
Quaternion_Camera_Class.cc: In function ‘int main(int, char**)’:
Quaternion_Camera_Class.cc:52: error: too few arguments to function ‘int InitGL(<type error>)’
Quaternion_Camera_Class.cc:196: error: at this point in file
Quaternion_Camera_Class.cc:207: error: invalid conversion from ‘void (*)(<type error>)’ to ‘void (*)()’
Quaternion_Camera_Class.cc:207: error: initializing argument 1 of ‘void glutDisplayFunc(void (*)())’
make: *** [Quaternion_Camera_Class.o] Error 1

Does the windows version run? I tend to look for runnable source code before i read the tutorial (when available, when not i try to find a way to take what i can from it and run it to see if i can get something i can understand from it), just to ensure that i won't learn the wrong thing due to something lost (which tends to come out in the form of errors or obviously erratic behavior).

I'll read the provided code, though, but i'm curious why those types no longer work and throw that message.

Quote:
Also some more good reference i liked...
http://www.codecolony.de/OpenGL/
See last lesson especially (Looking at the camera)

But when i think of minimal instructions to get-er-done
i always think that a rotation based system is the best way...

I managed to get it to work (in linux), but i do notice it's using the gluLookAt function, which makes me wonder whether how much math it'd take to get the position and rotation for use with a collision detection system (then again, aside from sphere and rectangles [in 2d only] i really have no idea how collision works, so understand this may suffice). At least with this, i have something to play around with (and some other tutorials to go on). However, aside from the lookat for the camera instead of a rotation system, it does do exactly what i need, so this is definitely a good starting point for me (and others). Any particular thoughts in response?

Edit: Well, actually, it does fall short in that i need other things to also be able to move in the same ways the main camera does.

Edit2: Ah, it's all coming together now. A misinterpretation of a strange practice in one of NeHe's tutorials put me under the incorrect assumption that the only way to keep track of x, y, and z coordinates was to figure them out manually. I assumed that they could not be extracted from the matrices involved.

Now, i have to find a way to rotate without the use of the Rotatef functions, since they clearly lead to Gimbel Lock. I think i have all the material i need, so i just need to go ahead and learn how to apply without using anything behind the scenes (otherwise i can't optimize).

Thank you all for all your help.
24 Apr 2010, 01:24
bitshifter

Joined: 04 Dec 2007
Posts: 764
Location: Massachusetts, USA
bitshifter
Yeah, the Visual C++ code compiles with my version 6.0.
And also i have compiled the Dev C++ version with no error.
It seems like you have to tweak the source a bit for g++.
But i say its worth fixing (its one of the better quat demo's around)

Simply try fiddling around until you fix each compiler error.
Maybe try to remove the GLvoid type first...
So int InitGL(GLvoid) becomes int InitGL()

Then i would try remove it here also...
void DrawGLScene(GLvoid) becomes void DrawGLScene()

C-compilers are finicky little bitches that constantly complain...
You just have to figure out how to rub them the right way

Let us know how it goes...
24 Apr 2010, 05:08
kohlrak

Joined: 21 Jul 2006
Posts: 1421
kohlrak
bitshifter wrote:
Yeah, the Visual C++ code compiles with my version 6.0.
And also i have compiled the Dev C++ version with no error.
It seems like you have to tweak the source a bit for g++.
But i say its worth fixing (its one of the better quat demo's around)

Simply try fiddling around until you fix each compiler error.
Maybe try to remove the GLvoid type first...
So int InitGL(GLvoid) becomes int InitGL()

Then i would try remove it here also...
void DrawGLScene(GLvoid) becomes void DrawGLScene()

C-compilers are finicky little bitches that constantly complain...
You just have to figure out how to rub them the right way

Let us know how it goes...

Well, the easier solution is to replace it with void (i'm surprised, i thought i'd have to do something about "anonymous" too, which is why i didn't try this before). It'll take a bit for me to simplify the camera to a simple Rotate, but if i accomplish it i'll post it here.

Edit: It appears that reversing the sign of the added x if Y gets between 90 and 270 is inevitable, thus making the original idea of mine (rotate(x,y,z)) impossible (unless i can come up with a way to get around this).

Edit2: Or maybe not... the codecolony program doesn't seem to have any code that forces the numbers to certain limits. It seems the lookat function might be easy to produce, too, which means it can be reproduced and simplified...
24 Apr 2010, 07:14
Borsuc

Joined: 29 Dec 2005
Posts: 2466
Location: Bucharest, Romania
Borsuc
You always rotate around the origin, i.e where the "0,0,0" is relative to your vertices. Translation merely modifies the origin.

Just imagine a vector coming from the origin TO the vertex in question, it's very easy. Because it's this vector that you rotate, not the vertices. (rotation HAS an origin)

Whenever you rotate, you rotate around the origin. Therefore the order is important, and easy to realize which you need to do first, once you imagine this.

If you rotate first, then you rotate around the world's origin -- i.e the "world" axis, if you keep the vertices as absolute values in the world (rather than relative to the object's origin!). Let's say you then want to rotate around the camera. The first thing you do, is get the difference between the object's vertices and the camera's position (origin). This difference vector is used as the new "origin" to rotate around.

Now you have a vector coming FROM the camera TO the object's vertices. You will now rotate around the camera. After this, add the camera's world position again to get the "world coordinates".

You can see the order is important but easy to visualize.

_________________
Previously known as The_Grey_Beast
24 Apr 2010, 15:57
edfed

Joined: 20 Feb 2006
Posts: 4237
Location: 2018
edfed
3D object should be represented with a local origin, then, it will be simple to rotate this object.

Code:
```cube:
x dd 43235
y dd 6654
z dd 524356

P1 dd 100,100,100
P2 dd 100,-100,100
P3 dd -100,-100,100
P4 dd -100,100,100

P5 dd 100,100,-100
P6 dd 100,-100,-100
P7 dd -100,-100,-100
P8 dd -100,100,-100
```

then, to translate, just add to x,y and z
and to rotate, play just on P1 to P8
and to rotate over the world axis, play with x,y and z

it is mainly a problem of object representation i think.
24 Apr 2010, 16:21
 Display posts from previous: All Posts1 Day7 Days2 Weeks1 Month3 Months6 Months1 Year Oldest FirstNewest First

 Jump to: Select a forum Official----------------AssemblyPeripheria General----------------MainDOSWindowsLinuxUnixMenuetOS Specific----------------MacroinstructionsCompiler InternalsIDE DevelopmentOS ConstructionNon-x86 architecturesHigh Level LanguagesProgramming Language DesignProjects and IdeasExamples and Tutorials Other----------------FeedbackHeapTest Area
Goto page 1, 2  Next

Forum Rules:
 You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot vote in polls in this forumYou can attach files in this forumYou can download files in this forum