Skip to main content
gamedev.net
🔒 Locked

vectors

Started by bcware 10 replies 850+ views
Original Post
bcware
bcware
ok i am having a little trouble with vectors, what i am trying to do is have 2 vectors one for the y axis and one for the x axis these 2 vectors will each be a force on its respective axis, this force will be as great as the vectors length, now i have 2 vectors lets say the Yaxis vectors length is 4 and the Xaxis vectors length is 3 then the resultant of the two is 5 pictured below, ok now what i want is the angle beween 4 and 5, now how i would do this is: length = (x ^ 2 + y ^ 2) ^ 0.5 degree = cos-1(y / length); problems i have found with this is 1: i cant find this function cos-1 (opposit of cos) on the computer (c++) so i cant even do this, this must exist i just dont know the function name (any help?) and 2: this method seems to suck because it only works correctly if x and y are positive, if one or both are negetive it goes haywire, so in essence what i need is either a better method of finding angles based on force or at least the function for finding cos-1 sin-1 tan-1 in c++ 4    5 |---| | /  | |/   | |---| 3 what the hell do i need this for anyway? well i am trying to make a top down space shooter type thing and i need to rotate and make the ship travel by the user pressing the arrow keys and this is the only way i can think of how to do this, if anyone knows a better way by all means please let me know. bcware@mediaone.net Edited by - bcware on 11/5/00 9:45:22 AM
Phobia
Phobia
The function for the inverse cos is acos. To work out the angle between two vectors use the dot product which is

cos(theta) = U.V / |U|*|V|

Where U.V = Ux*Vx + Uy*Vy.
bcware
bcware
i have a book in which that exact statement was listed as well but i seem to be doing something wrong here

my vectors since they always come from the origin will always be something like (0, 4) and (3, 0) point being they always have zeros in them which when i do

Ux * Vx + Uy * Vy

0 * 3 + 4 * 0 = 0

and even if i replace the zeros with lets say 1...

1 * 3 + 4 * 1 = 7

then i do the same only get the absolute value ?

|7| in this case since it isnt negetive so it would just be 7

U*V / |U|*|V|

7 / 7 = 1

i appear to be doing this wrong since i am doing nothing but canceling myself out or just getting 1 every time
Jumpster
Jumpster
    
/*
***************************************************************************************************
***************************************************************************************************
***
*** Function Name: WF_VECTOR::Angle()
*** Description: This method is used to determine an angle between two vectors.
***
*** result = arccos( v1 * v2 / sqrt(( (v1.x*v1.x) + (v1.y*v1.y) + (v1.z*v1.z) ) *
*** ( (v2.x*v2.x) + (v2.y*v2.y) + (v2.z*v2.z) ) ))
*** Where: v1 * v2 = (v1.x * v2.x) + (v1.y * v2.y) + (v1.z * v2.z) //

***
*** Summary: result = arccos( v1 (dot) v2 / v1.Length() * v2.Length() )
***
*** Parameters: WF_VECTOR& a - [in] - the vector to determine the angle of.
***
*** Returns: float result - the calculated angle result in RADIANS.
***
*** Author: J.W. Heikkila, Jr.
***
***************************************************************************************************
***************************************************************************************************
*/

float __fastcall WF_VECTOR::Angle( const WF_VECTOR& a ) const
{
return acosf( (DotProduct(a) / Length(a)) );
}




Here''s my Vector Angle calculation method. It basically does the same thing as Phobia pointed out but in code form.

Regards,
Jumpster
Regards,JumpsterSemper Fi
Jumpster
Jumpster
quote:

my vectors since they always come from the origin will always be something like (0, 4) and (3, 0) point being they always have zeros in them which when i do

Ux * Vx + Uy * Vy

0 * 3 + 4 * 0 = 0



If that is in-fact your vectors, then you will always be 90-degree angles.

Here''s why:


|
Y +
|
|-----+
X

Where the Y(+) = (0,4) and the X(+) = (3,0). Notice the angle between the two is a Right Angle. Following the formula, you get:

acos( Y(+) dot X(+) / Y(+).Lenght() * X(+).Length())
acos( 0 / ??? )
acos( 0 ) = 1.57079632679489661923132169163975 - radians.
1.57079632679489661923132169163975 * (180/PI) = 90. - degrees.

Regards,JumpsterSemper Fi
bcware
bcware
ok i can see i did that horribly wrong and the . meant dot product not multiply (duh) ok but what i need is just a straight forward way of getting a dot product, as i said before i have a book on this but its seems to be waaay past me it says the same thing that:

cos(theta) = V.W / |V|*|W|

would anyoen be kind enough to do this out the long way for me. because i am not sure exactly what goes in the places of this little formula, and will this work if the vectors have a zero in them?
bcware
bcware
ok i seem to be going about doing this completely wrong here well what i want to make is a top view of a space ship that will have the right and left arrow keys rotate the ship and the forward and back keys thrust in the givin direction so what i need to know is, based on the direction my space ship is pointing in if i thrust in that direction how much do i add or subtract to the x or y coordinate to get it to actually travel in this direction? i am sure there must be some sort of document that covers this, i have seem many games that use this same thing i just can't figure it out.

oh yeah and if anyone knows a thing or two about velocity and the like that would help too, like acceleration and decay and everything: a = f / m

oh yes a good example of exactly what i mean is like in asteroids i am trying to figure out basically this, based on what direction the space shit is pointing in when i fire my bullet which orinates at 0,0 how much do i add to the x and y coordinates to get the bullet to travel in the same direction as the ship is pointing

Edited by - bcware on November 5, 2000 11:54:54 AM
Jumpster
Jumpster
Ok, then you need a way to rotate the vector of the ship.

Check this out:

    
/*
***************************************************************************************************
***************************************************************************************************
***
*** Function Name: WF_VECTOR::Rotate()
*** Description: This method is used to rotate a vector a given angle around the normal passed in.
*** Notes: Here''s the verbose formula...
***
*** result = cos(angle)* (*this) +
*** ((1.0f-cos(angle))*(normal* (*this))) * normal +
*** sin(angle)*(CrossProduct(normal))
***
*** Parameters: float angle - [in] - the amount of angle to rotate the vector.
*** WF_VECTOR& normal - [in] - the vector to rotate around.
***
*** Returns: WF_VECTOR result - the result of rotating the vector.
***
*** Author: J.W. Heikkila, Jr.
***
***************************************************************************************************
***************************************************************************************************
*/

WF_VECTOR __fastcall WF_VECTOR::Rotate( const float angle, const WF_VECTOR& normal ) const
{
WF_VECTOR temp = (*this);

float cosine = cosf(angle);
float sine = sinf(angle);

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

// Added parenthisis to better indicate precedence. Also relocated the multiplications with floats

// because float * vector is not allowed, but vector * float is because it is a recognized
// operator of the vector class.

//

return (temp * cosine) + ((normal * temp) * normal) * (1.0f-cosine) + ((temp ^ normal) * sine);
}




You would also need to take into consideration Velocity which is unfortunately not something I can explain very well except that it it dist/time.

Regards,
Jumpster

Perhaps you would benefit greatly from "Tricks of the Windows Game Programming Gurus" by Andre LaMothe. Virtually everybody in this forum uses it for various things and he covers a good deal of physics modeling in it.
Regards,JumpsterSemper Fi
bcware
bcware
i have the book actually i just happen to have leant it out great timing huh? your math functions are helpful except they assume you already know everything like getting the cross pruduct and the dot product already, which unfortunatly i do not, so i am screwed basically, what i need is a tutorial on this exact subject so i either have to wait to get my book back and find one online, i remeber in the book andré made the exact same game as i am trying to make only it was 2d, mine is 3d but your only allowed to move 2 dimensionally so the same math would work

Edited by - bcware on November 5, 2000 11:59:39 AM
Jumpster
Jumpster
    
void __fastcall WF_VECTOR::Scale(float scaleby)
{
// Multiply all data members by the scaleby value...

x *= scaleby;
y *= scaleby;
z *= scaleby;
}

float __fastcall WF_VECTOR::Length() const
{
return sqrtf( (x*x)+(y*y)+(z*z) );
}


float __fastcall WF_VECTOR::Length( const WF_VECTOR& a ) const
{
return sqrtf( ((x*x)+(y*y)+(z*z)) * ((a.x*a.x)+(a.y*a.y)+(a.z*a.z)));
}


float __fastcall WF_VECTOR::Distance( const WF_VECTOR& a ) const
{
return ((*this) - a).Length();
}


void __fastcall WF_VECTOR::Normalize()
{
// Determine this vector''s Length()
float len = Length();

// We should never have a negative length...

if (len < 0.0) { Clear(); }
else
{
len = 1 / len;
x *= len;
y *= len;
z *= len;
}
}


float __fastcall WF_VECTOR::DotProduct( const WF_VECTOR& a ) const
{
return ((x * a.x) + (y * a.y) + (z * a.z));
}

WF_VECTOR __fastcall WF_VECTOR::CrossProduct( const WF_VECTOR& a ) const
{
return WF_VECTOR( ((y * a.z) - (z * a.y)), ((z * a.x) - (x * a.z)), ((x * a.y) - (y * a.x)) );
}


/*
***************************************************************************************************
***************************************************************************************************
***
*** Function Name: WF_VECTOR::Extrapolate()
*** Description: This method is used to extrapolate a new vector along a line. The (this) vector
*** is considered the origin. The direction and distance will be passed in as
*** parameters to the function.
***
*** Parameters: WF_VECTOR& direction - [in] - the direction of the line to extrapolate from.
*** float distance - [in] - the distance along the line to return the point at.
***
*** Returns: WF_VECTOR result - the calculate vector result.
***
*** Author: J.W. Heikkila, Jr.
***
***************************************************************************************************
***************************************************************************************************
*/
WF_VECTOR __fastcall WF_VECTOR::Extrapolate( const WF_VECTOR& direction, const float distance ) const
{
float a = x + (direction.x * distance);
float b = y + (direction.y * distance);
float c = z + (direction.z * distance);
return WF_VECTOR(a,b,c);
}


float __fastcall WF_VECTOR::Angle( const WF_VECTOR& a ) const
{
return acosf( (DotProduct(a) / Length(a)) );
}


WF_VECTOR __fastcall WF_VECTOR::Rotate( const float angle, const WF_VECTOR& normal ) const
{
WF_VECTOR temp = (*this);

float cosine = cosf(angle);
float sine = sinf(angle);

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

// Added parenthisis to better indicate precedence. Also relocated the multiplications with floats

// because float * vector is not allowed, but vector * float is because it is a recognized
// operator of the vector class.

//

return (temp * cosine) + ((normal * temp) * normal) * (1.0f-cosine) + ((temp ^ normal) * sine);
}


/*
***************************************************************************************************
***************************************************************************************************
***
*** Function Name: WF_VECTOR::operator[]()
*** Description: This method is used to return a value of the vector in a similar way as an
*** array access. The acceptable values of which are 0 for x, 1 for y and any
*** other value for z.
***
*** Parameters: int which - [in] - the array element to grab.
***
*** Returns: float& result - a reference to the result of the retrieval process. By
*** returning a reference, we allow the [] sign to be placed on
*** both the right and left side of an equation/assignment
*** operation.
***
*** Author: J.W. Heikkila, Jr.
***
***************************************************************************************************
***************************************************************************************************
*/
float& __fastcall WF_VECTOR::operator[] ( const int which )
{
if (0 == which) { return x; }
else if (1 == which) { return y; }
else {return z;}
}


/*
***************************************************************************************************
***************************************************************************************************
***
*** Function Name: WF_VECTOR::ConvertTo16BitColor()
*** Description: This method is used to convert a vector to an unsigned short value for a color
*** in the format _5X6X5_ color mode.
***
*** Parameters: None.
***
*** Returns: unsigned short result - the integral color number.
***
*** Author: J.W. Heikkila, Jr.
***
***************************************************************************************************
***************************************************************************************************
*/
unsigned short __fastcall WF_VECTOR::ConvertTo16BitColor() const
{
unsigned short r = (unsigned short) (x * 255); if (r > 255) r = 255;
unsigned short b = (unsigned short) (y * 255); if (b > 255) b = 255;
unsigned short g = (unsigned short) (z * 255); if (g > 255) g = 255;
return (((r & 248) << 8) + ((g & 252) << 3) + (b >> 3));
}


/*
***************************************************************************************************
***************************************************************************************************
***
*** Function Name: WF_VECTOR::ConvertTo15BitColor()
*** Description: This method is used to convert a vector to an unsigned short value for a color
*** in the format _5X5X5_ color mode.
***
*** Parameters: None.
***
*** Returns: unsigned short result - the integral color number.
***
*** Author: J.W. Heikkila, Jr.
***
***************************************************************************************************
***************************************************************************************************
*/
unsigned short __fastcall WF_VECTOR::ConvertTo15BitColor() const
{
unsigned short r = (unsigned short) (x * 255); if (r > 255) r = 255;
unsigned short b = (unsigned short) (y * 255); if (b > 255) b = 255;
unsigned short g = (unsigned short) (z * 255); if (g > 255) g = 255;
return (((r & 248) << 7) + ((g & 248) << 2) + (b >> 3));
}


/*
***************************************************************************************************
***************************************************************************************************
***
*** Function Name: WF_VECTOR::ConvertToColor()
*** Description: This method is used to convert a vector to an unsigned short value for a color
*** in the format _5X5X5_ or _5X6X5_ color mode depending on the parameter passed in.
***
*** Parameters: None.
***
*** Returns: unsigned short result - the integral color number.
***
*** Author: J.W. Heikkila, Jr.
***
***************************************************************************************************
***************************************************************************************************
*/
unsigned short __fastcall WF_VECTOR::ConvertToColor( int colormode ) const
{
// Default to 5x6x5 Color mode...

if (colormode) return ConvertTo16BitColor();
else return ConvertTo15BitColor();
}


/*
***************************************************************************************************
***************************************************************************************************
***
*** Function Name: WF_VECTOR::GammaCorrect()
*** Description: This method is used to adjust the Gamma rays to correct for monitor variances.
***
*** Parameters: None.
***
*** Returns: None.
***
*** Author: J.W. Heikkila, Jr.
***
***************************************************************************************************
***************************************************************************************************
*/

void __fastcall WF_VECTOR::GammaCorrect( float correct )
{
x = powf(x, correct);
y = powf(y, correct);
z = powf(z, correct);
}




Here is basically my entire VECTOR class implementation less extraneaous(sp?) comments. It''s not a tutorial but you should be able to figure out what it happening.

Regards,
Jumpster
Regards,JumpsterSemper Fi
bcware
bcware
that''l work

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.