Amiga.org

Operating System Specific Discussions => Amiga OS => Amiga OS -- Development => Topic started by: GreatLor on May 21, 2004, 01:25:21 PM

Title: My Amos-vector question moved here
Post by: GreatLor on May 21, 2004, 01:25:21 PM
First I must say that yesterday I came up with a quicker way to do the rotation (no use of square-roots - boy was that STUPID ?! :-) )

If anyone has any experience with vector-programming please give your opinions, here fallows; first the intit for the base-vectors:

ax#=50
ay#=0
az#=0

bx#=0
by#=-50
bz#=0

cx#=0
cy#=0
cz#=50

here is the main loop:

do
gosub rotate_ab
gosub rotate_bc
gosub rotate_ca
wait vbl
cls 0  ; Double-buffering is not important right now
loop

Here's the 'rotate_ab' subroutine:
; I use array 'siin#()' to store some sinus values (it's faster)

rotate_ab:

;two coordinate vectors for base vector a's new pos. (rotation)

a1x#=siin#(91)*ax#
a1y#=siin#(91)*ay#
a1z#=siin#(91)*az#
b1x#=siin#(1)*bx#
b1y#=siin#(1)*by#
b1z#=siin#(1)*bz#

;two coodinate vectors for base vector b's new pos.

b2x#=siin#(91)*bx#
b2y#=siin#(91)*by#
b2z#=siin#(91)*bz#
a2x#=siin#(1)*-ax#
a2y#=siin#(1)*-ay#
a2z#=siin#(1)*-az#

; now adding the two vectors of each base vector to them

; vector a

ax#=a1x#+b1x#
ay#=a1y#+b1y#
az#=a1z#+b1z#

; vector b

bx#=b2x#+a2x#
by#=b2y#+a2y#
bz#=b2z#+a2z#

return

; and two similar subroutines for the rotations around the two other axis (which I will not include here).

So is THIS the way others do vector rotations or are there faster (and more complicated) ways ?

Thanx in advance ! (hope somebody answers this :-D )
Title: Re: My Amos-vector question moved here
Post by: bloodline on May 21, 2004, 01:56:56 PM
If I were you I'd probably make a generalised function to do the Matrix math, and use it on your data.

I can't remember if AMOS handles functions properly or not though :-(
Title: Re: My Amos-vector question moved here
Post by: GreatLor on May 21, 2004, 02:06:27 PM
by 'generalised function' do you mean a a subroutine that takes input parameters (function) ? in that case, sure I know how to the most elegant and fast functions, but my question was if the actual vector rotations I do are THE way everyone did/do or not.
Title: Re: My Amos-vector question moved here
Post by: bloodline on May 21, 2004, 03:32:13 PM
Quote

GreatLor wrote:
by 'generalised function' do you mean a a subroutine that takes input parameters (function) ? in that case, sure I know how to the most elegant and fast functions, but my question was if the actual vector rotations I do are THE way everyone did/do or not.


-
A function is a unit of code, that takes variables and returns a result. "Sin(x)" is an example of a fuinction.
-

I can't follow what you have done, there are far to many variables all over the place, if you turned it into a function then it would be easier to see...

If you used C (or even Blitz Basic) you could make a verctor data type that would add clarity to your code.
Title: Re: My Amos-vector question moved here
Post by: GreatLor on May 21, 2004, 05:03:35 PM
Please give an example of what you mean.

You mean like: (in c)

//*********************************************

// vectors a,b and c

float a[3]={50,0,0}
float b[3]={0,-50,0}
float c[3]={0,0,50}

int main() {
  rot(a,b,1)  // rotate a and b (around c) +1 postion
  rot(b,c,2)  // rotate b and c (around a) +2 postions
  rot(c,a,3)  // rotate c and a (around b) +3 postions
}

void rot(float *vec1,float *vec2,int degr) {
  ....
  ....
}

//**********************************************

Is that what you ment ? however I dont remember the functions for mathematic operations in C, so I cant go further in that language, but if that is what you ment I then will get back to you with appropriate function(s) in AMOS.


*EDIT*

I'll read your post tomorrow.
Title: Re: My Amos-vector question moved here
Post by: bloodline on May 21, 2004, 06:50:15 PM
I was thinking that you could make a vector data type:

struct vector {
float x;
float y;
float z;
};

struct vector a;
struct vector b;
struct vector c;

int main() {
c=rot(a,b,1);
a=rot(b,c,2);
b=rot(c,a,3);

return 0;
};

vector rot(struct vector fist_vec , struct vector second_vec , int position) {

/* Do something to the two vectors*/

struct vector return_vec;

return_vec.x = first_vec.x * second_vec.x / position;


return return_vec;
};


I can't really see what you are trying to do though :-/ (as demonstrated by my random example). Whatever, data structures and function will make you code far easier to read and optimise than procedures and arrays.

Blitz Basic supports data types and functions, use that instead of AMOS.
Title: Re: My Amos-vector question moved here
Post by: GreatLor on May 22, 2004, 01:55:49 PM
Well, I dont have any problems whatsoever with not using structures, simply because the languages I'm playing with right now doesnt support them, anyway, I didnt get what "return_vec.x = first_vec.x * second_vec.x / position;" is supposed to do, will "return_vec.x = first_vec.x * second_vec.x / position;" give the ROTATED x position ??? :-?

Its a shame that others do not contribute in this thread, I find vector-programming quite intresting, anyone who knows of any forum(s) (doesnt matter what platform - although Amiga is preferable) about this subject ? If yes then link, if no then dont bother  :-D
Title: Re: My Amos-vector question moved here
Post by: mdwh2 on May 22, 2004, 05:34:50 PM
Firstly, was there a previous thread - you seemed to refer to earlier things, I wasn't sure if there was another thread I should be looking at. If not, what is it you are actually trying to achieve?

Secondly, there appear to be two issues here: what algorithms should be used to do vector maths, and how to actually code it (in that you don't know C that well, but the rest of us get totally confused by AMOS - I mean yes, I know what it means, but it's very unreadable code;)

Your way of doing things is quite reasonable - you have an orthonormal axis (ie, the 3 vectors) which completely define the rotation, and then you're doing rotations with respect to this local axis. This is certainly a lot better in general than say using Euler angles (which suffer from "Grimbol lock").

For some simple speed ups, it depends on what you're trying to do. Maybe the three rotations in each loop can be combined into a single rotation? It's easiest to work this out by expressing the three rotations as matrices, and multiplying them together. If you're doing the same rotation each time, then the 9 elements of the matrix can then be precomputed.

Each of the 9 elements in the set of 3 vectors then requires 3 multiplys and 2 additions, so multiplying the 3 vectors by the rotation matrix costs 27 multiplys and 18 additions.

Where as in your method, each individual rotation costs 12 multiplys and 6 additions, which gives a total of 36 multiplys and 18 additions.

I think that's right..

One thing to be careful is numerical instability - due to inaccuracies in floating point calculations, your 3 vectors will drift from being orthogonal and normalised vectors, so this may have to be corrected every so often.

Now, if you want a faster way of doing things, I suggest you look up about "Quaternions". Basically, they represent a rotation by only 4 numbers (they are actually 4-dimensional equivalents of complex numbers, but don't let that put you off;) instead of 9, so this means less calculations are required. A knowledge of vector operations such as cross product and dot product is highly recommended before you start learning about Quaternions.

Some good information on these is available at http://www.j3d.org/matrix_faq/matrfaq_latest.html (A warning - a lot of tutorials and FAQs on Quaternions have mistakes in some of the calculations! This FAQ as far as I can tell seems to be correct).
Title: Re: My Amos-vector question moved here
Post by: mdwh2 on May 22, 2004, 05:41:03 PM
Quote

GreatLor wrote:
Well, I dont have any problems whatsoever with not using structures, simply because the languages I'm playing with right now doesnt support them, anyway, I didnt get what "return_vec.x = first_vec.x * second_vec.x / position;" is supposed to do, will "return_vec.x = first_vec.x * second_vec.x / position;" give the ROTATED x position ??? :-?
No it won't - he said "I can't really see what you are trying to do though :-/ (as demonstrated by my random example)."

Quote
Its a shame that others do not contribute in this thread, I find vector-programming quite intresting, anyone who knows of any forum(s) (doesnt matter what platform - although Amiga is preferable) about this subject ? If yes then link, if no then dont bother  :-D
As I sort of said in my first reply, it's probably better to separate into the two issues of "algorithms" and "how to write this in AMOS". This forum may be good for AMOS programming, but isn't particularly suited towards 3D programming. I'd recommend going to a more general forum, and either just writing out the maths, or using pseudo code (eg, a1.x = sin(91) * a.x). That way people who have never used AMOS (and even those who have but still find it hard to read;) will understand, and hopefully be able to help:)

Some good forums for 3D programming are:

http://www.gamedev.net/
http://www.gamasutra.com/
http://www.flipcode.com/
Title: Re: My Amos-vector question moved here
Post by: Karlos on May 22, 2004, 05:49:26 PM
I can't tell you anything AMOS specific, but I do know vector mathematics ;-)

Your best bet is to create a Vector type that has x,y,z,1. You can use a 4x4 matrix to perform any transformation on such a vector - rotation, scaling, translation, projection, you name it.

You can multiply these matrices together to create a matrix that can do transformation (scale, rotate, translate, etc.) of your data in a single vector*matrix step.

This is basically what OpenGL does to process polygons.
Title: Re: My Amos-vector question moved here
Post by: GreatLor on May 24, 2004, 01:09:31 PM
Thanx mdwh2, well I just had some 3-4 weeks of experience with C, but I know plenty enough about it to know that bloodline should send to the function a pointer to the structure rather then sending the whole thing, (enough GreatLor, go to your room, you are grounded -  :-D )

Anyway thanx for your infromation, and I will look up those sites, thank you all.
Title: Re: My Amos-vector question moved here
Post by: GreatLor on May 28, 2004, 02:26:43 PM
@mdwh2, hmm, interesting, this cross-product, actually some years back when I was doing my primitive vector rotations (actually before it, when I experimented with 2d-vectors), I noticed that in 2d, for two vectors a and b, orthagonal to eachother, this is the formula to determine vector b's orthagonal position to a (so I only needed to rotate ONE vector):

b.x = a.y
b.y = -a.x

So this envoked me to try to accomplish this in 3d, but after one days failure (and exhausted brain), I totally gave that up and rotated ALL THREE axis instead, what do you think, am I a genious ( :-D ) for being on my path to (re)discover this "cross-product", or a real IDIOT for not understanding it in 3d ?
Title: Re: My Amos-vector question moved here
Post by: Cymric on May 28, 2004, 02:54:52 PM
Quote
Karlos wrote:
Your best bet is to create a Vector type that has x,y,z,1. You can use a 4x4 matrix to perform any transformation on such a vector - rotation, scaling, translation, projection, you name it.

What is the purpose of the fourth element (1) in that type? Someone already mentioned quaternions in this thread, are you mimicking those by any chance?
Title: Re: My Amos-vector question moved here
Post by: mdwh2 on May 29, 2004, 01:40:33 PM
Quote

Cymric wrote:
Quote
Karlos wrote:
Your best bet is to create a Vector type that has x,y,z,1. You can use a 4x4 matrix to perform any transformation on such a vector - rotation, scaling, translation, projection, you name it.

What is the purpose of the fourth element (1) in that type? Someone already mentioned quaternions in this thread, are you mimicking those by any chance?

It's not quaternions. The thing is that with a 3x3 matrix there are some transformations you cannot do - in particular, there is no way you can translate a vector. But using 4x4 matrices allow this. The extra "1" is to make this work - you need a four dimension vector to multiply with a 4x4 matrix.

It typically looks something like:

( R11 R12 R13 Tx )
( R21 R22 R23 Ty )
( R31 R32 R33 Tz )
( 0   0   0   1  )

When you multiply this by the vector with elements {x, y, z, 1}, you get the same as if you'd multiplied by vector {x, y, z} by the 3x3 matrix {Rij}, and then translated by the vector T. The bottom row of the 4x4 matrix is such that the 4th element in the vector remains as 1.

You can also consider values other than 1 to be treated as a scaling factor, which makes it easier to implement more types of transformations.

However, I don't think that all this is any help as far as rotations are concerned - but it's a useful  way of doing things if you want to represent translations in your matrix operations.