Rotating towers

Started by
36 comments, last by HelderBorges 13 years ago


However you tried to calculate distance between post and posb with your calculardistancia function when the difference between their y-values are clearly not zero.

How can your assumption for your distance equation be correct when you already broke it in this case?
Please stick to mathematically sound equation. Don't make assumptions when you are going to break it like this.



Ok... you got the point. i have to change that. But i think i already found the solution. i will post it wen i´m done :P

But thanks all guys
Advertisement

No, it1s not the atan stuff. The transformations are mixed up I think, useless pushing popping etc. I can't even follow the code, that's why it would be easier to rewrite the whole stuff.

Or read our openGL books again, especially the transformations part


Thanks szecs. Can you send me the link? i´m using the push pop so many time, because my teacher like it that way xD and i was messing up with the y value. :S i will reset the y value xD

[quote name='SuperVGA' timestamp='1302701242' post='4797932']
[quote name='alvaro' timestamp='1302700176' post='4797929']
g++'s implementation of pow is very impressive.


That's strange. It wasn't impressive the way I remember it....
[/quote]

Well, if you write `pow(x,17)' and look at the assembly output, you'll see that it's doing something like this:
x2 = x*x;
x4 = x2*x2;
x8 = x4*x4;
x16 = x8*x8;
x17 = x16*x;

[/quote]

Aha! Ok, I see now how it would be faster in some cases. However, that would be slower when it comes to squaring and as such, computing distances.
But I get your point, nonetheless. Nice implementation.

Aha! Ok, I see now how it would be faster in some cases. However, that would be slower when it comes to squaring and as such, computing distances.

Please, check your compiler's output carefully. Last time I did, I found that pow(x,2) resulted in the exact same assembly code as x*x.
Ok, i´m not done :\ mi friend told me to try this:



float dotProduct(float x[3],float y[3]){
return x[0]*y[0]+x[1]*y[1]*x[2]+y[2];}

float length(float x[3]){
return sqrtf(x[0]*x[0]+x[1]*x[1]+x[2]*x[2]);
}

float clamp(float v, float i, float s){
if (v<i)
return i;
else if(v>s)
return s;
else return v;
}

float anglbetween(float x[3], float y[3])
{

float xu[3]; //aux array so i can create an unitary vector
float yu[3]; //aux array so i can create an unitary vector

xu[0]=x[0]/(abs(x[0]));
xu[1]=x[1]/(abs(x[1]));
xu[2]=x[2]/(abs(x[2]));

yu[0]=y[0]/(abs(y[0]));
yu[1]=y[1]/(abs(y[1]));
yu[2]=y[2]/(abs(y[2]));

float lp = length(xu) * length(yu);
if(lp<1e-6f)
lp=1e-6f;

float f= dotProduct(xu,yu)/lp;

f=clamp(f,-1,1);
return acosf(f);
}





but it does not work. I used some "printf" for fast debug, and i found a strange thing, first i use calculadistancia() and both parameters have their values right, but wen i passe the same parameters to anglbetween() they have strange values like: 1.#IND000


And i was so close :\ i think xD
I'm not a an OpenGL person, but you might have stumbled on a classic bug with this one (not your most recent snipped, but from earlier posts of yours):

glRotatef(atan2(posb[0]-post[0],posb[2]-post[2]),0,1,0); //rotate the tower to the object
glRotatef wants angles in degrees, but atan2 returns radians. Scale the value with 180.0/Pi before feeding it to glRotatef.

Ok, i´m not done :\ mi friend told me to try this:



float dotProduct(float x[3],float y[3]){
return x[0]*y[0]+x[1]*y[1]*x[2]+y[2];}

float length(float x[3]){
return sqrtf(x[0]*x[0]+x[1]*x[1]+x[2]*x[2]);
}

float clamp(float v, float i, float s){
if (v<i)
return i;
else if(v>s)
return s;
else return v;
}

float anglbetween(float x[3], float y[3])
{

float xu[3]; //aux array so i can create an unitary vector
float yu[3]; //aux array so i can create an unitary vector

xu[0]=x[0]/(abs(x[0]));
xu[1]=x[1]/(abs(x[1]));
xu[2]=x[2]/(abs(x[2]));

yu[0]=y[0]/(abs(y[0]));
yu[1]=y[1]/(abs(y[1]));
yu[2]=y[2]/(abs(y[2]));

float lp = length(xu) * length(yu);
if(lp<1e-6f)
lp=1e-6f;

float f= dotProduct(xu,yu)/lp;

f=clamp(f,-1,1);
return acosf(f);
}





but it does not work. I used some "printf" for fast debug, and i found a strange thing, first i use calculadistancia() and both parameters have their values right, but wen i passe the same parameters to anglbetween() they have strange values like: 1.#IND000


And i was so close :\ i think xD


Inside your anglbetween() function:

xu[0]=x[0]/(abs(x[0]));
xu[1]=x[1]/(abs(x[1]));
xu[2]=x[2]/(abs(x[2]));

yu[0]=y[0]/(abs(y[0]));
yu[1]=y[1]/(abs(y[1]));
yu[2]=y[2]/(abs(y[2]));


is incorrect for calculating unit vector. It does not make any sense if you think about it carefully. x[0]/(abs(x[0]) is going to return you either 1.0f or -1.0f. You are not going to get anything other ones or minus ones for your xu and yu which is obviously wrong.

You should be dividing each component with the magnitude or length of the original vector, like this:

xu[0] = x[0] / length(x);
xu[1] = x[1] / length(x);
xu[2] = x[2] / length(x);

yu[0] = y[0] / length(y);
yu[1] = y[1] / length(y);
yu[2] = y[2] / length(y);


After this step, since you have both unit vectors xu and yu, there is no need to calculate Ip as shown in your code. Just take the dot product of xu and yu and acosf it to get the angle between two vectors. Be careful to note whether acosf returns degree or radians, like what unbird has mentioned.
I'm so sure that the problem is not only with your angle calculating code.

render()
{
angle = caclulateAngle(); // convert to radians as Unbird suggested

glLoadIdentity();

glTranslatef(tower_pos[0],tower_pos[1],tower_pos[2]);

glRotatef(angle, 0,1,0); // maybe -angle

glBegin(GL_TRIANGLES);
......

glEnd();
}
You really should read the documentation of the functions you are using. Just copy the function name into Google, pretty much the first hit is an explanation of the parameters

I'm not a an OpenGL person, but you might have stumbled on a classic bug with this one (not your most recent snipped, but from earlier posts of yours):

glRotatef(atan2(posb[0]-post[0],posb[2]-post[2]),0,1,0); //rotate the tower to the object
glRotatef wants angles in degrees, but atan2 returns radians. Scale the value with 180.0/Pi before feeding it to glRotatef.


you are almost the man xD
After your post, the tower always rotate.
The only prob is that it is not faced to the object xD
You have a radians -vs- degrees problem. Really, do read the documentation instead of relying on trial and error and on the patience of the good people on this forum.

This topic is closed to new replies.

Advertisement