Jump to content
  • Advertisement
Sign in to follow this  
cbastien

quaternion "SpheriqueToQuat"

This topic is 4230 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello everybody ! I'm drawing a sphere in C++/opengl using quaternion to turn around it. But i have difficulties to implement a correct function to transform sperical coordinate (latitude,longitude) to a quaternion First, i do not understand why i need an angle to convert latitude and longitude to a quaternion ( i thought it only was for the up vector ) I used the quaternion faq to make my function
void Quaternion::SpheriqueToQuat(const float latitude, const float longitude, const float angle)
{

double sin_a = sin(angle / 2);
double cos_a = cos(angle / 2);

double sin_lat = sin(latitude);
double cos_lat = cos(latitude);

double sin_long = sin(longitude);
double cos_long = cos(longitude);


this->w = float(cos_a);

this->x = float(sin_a * cos_lat * sin_long);
this->y = float(sin_a * sin_lat);
this->z = float(sin_a * sin_lat * cos_long);

Normalize();

return;
}


The result is really bad : If i put the angle value to 1, latitude to 0 and i increase the longitude with a timer, the resulting movement draw a eight on my sphere instead of turning around the equator.

Thanks in advance for any advice. Sébastien. [Edited by - cbastien on May 16, 2007 4:27:59 AM]

Share this post


Link to post
Share on other sites
Advertisement
here a temporary version i made, it is not really accurate but it works !



void Quaternion::SpheriqueToQuat(const float latitude, const float longitude, const float angle)
{

//this is a temporary version // do NOT work Accurately
if( longitude>=-180 && longitude<=0 ){

float longi=-(longitude+90);
float lati=-latitude;

if( latitude <= 0){
this->x = float(longi/90);
this->y = float( lati / 180 );
this->z = float(1 - ( lati / 180 ) );
this->w = float(longi/90 * ( lati / 180 ) * 2 );
} else {
this->x = float(longi/90);
this->y = float( lati / 180 );
this->z = float(1 + ( lati / 180 ) );
this->w = float(longi/90 * ( lati / 180 ) * 2 );
}
}else{
float longi=(longitude-90);
float lati=-latitude;

if(longitude<90){
this->x = float( 1 + ( longi / 180 ));
this->y = float( (longi/180) * (lati / 90) );
this->z = float( longi / 180 );
this->w = float( ( lati / 90 ) * (1+longi/180 ) );
}else{
this->x = float( 1 - ( longi / 180 ));
this->y = float( (longi/180) * (lati / 90) );
this->z = float( longi / 180 );
this->w = float( ( lati / 90 ) * (1-longi/180 ) );
}
}
}



any advice to help me in a better way to do that ?

[Edited by - cbastien on May 16, 2007 4:41:54 AM]

Share this post


Link to post
Share on other sites
hi again !

i found an accurate solution for my problem using axisTOangle from the quaternion faq :

[source="cpp"]

longi=138;
lati=36;

longi=(longi)/180*PI;
lati=(lati)/180*PI;


q1.AxisToQuat(Vector3D(0,1,0),longi);
q2.AxisToQuat(Vector3D(1,0,0),lati);

camera_quat=q1*q2;






So now i have a new problem, Quaternion to latitute/longitude

i will try to obtain angle with this kind (1,0,0)of vector 3D from this function

[source="cpp"]

void Quaternion::GetAxisAngle(Vector3D &v, float &angle) const
{
double temp_angle; // temp angle
double scale; // temp vars

temp_angle = acos(w);

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// Another version where scale is sqrt (x2 + y2 + z2)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
scale = (float)sqrt(SQR(x) + SQR(y) + SQR(z));
// scale = (float)sin(temp_angle);

assert(0 <= temp_angle); // make sure angle is 0 - PI
assert(PI >= temp_angle);

if (FLOAT_EQ(0.0f, scale)) // angle is 0 or 360 so just simply set axis to 0,0,1 with angle 0
{
angle = 0.0f;

v.SetValues(0.0f, 0.0f, 1.0f); // any axis will do
}
else
{
angle = (float)(temp_angle * 2.0); // angle in radians

v.SetValues(float(x / scale), float(y / scale), float(z / scale));
v.Normalize();

assert(0.0f <= angle); // make sure rotation around axis is 0 - 360
assert(2*PI >= angle);
assert(v.IsUnit()); // make sure a unit axis comes up
}

return;
} // end void GetAxisAngle(..)



Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!