Public Group

# Rotating towers

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

## Recommended Posts

Hi guys. I´m studying computer engineering and i have to make a little game.

In the game, i need to have towers and a character.

I need the towers to face and focus the player, wen he enters their range zone.

i keep track of the position of the tower (i use post[3]) and the position of the player(i use posb[3]) with an array wish post[0] is the x coordinate the post[1] the y and the post[2] the z .
i use the function (sqrt(pow(a[0]-b[0],2)+pow(a[2]-b[2],2))) to calculate the distance between the 2 points, and if it is lower than the range, the tower needs to turn..... and that is my problem. I dont know how to face the tower to the player. I already tried some function, but i cant calculate that. :S

Can someone help plz????i will order you a pizza lol.

I´m using vs with c++. ty guys

##### Share on other sites
There's a few different ways you can orient the tower. One would be to build an orthonormal basis from the normalized direction from the tower position to the player position. Another method (which might be a little more immediately intuitive) is to use atan2() to compute an angle of rotation for the tower that will align it as desired, e.g. (untested):

y_angle = atan2(posb[2] - post[2], posb[0] - post[0]);
Depending on the conventions you're using, you may need to swap and/or negate the arguments to atan2(), or modify the angle that it returns.

##### Share on other sites
Slightly off topic: I have bad experience with pow in c++. Multiplying the number with itself &&/|| creating your own pow function seems faster.

##### Share on other sites

There's a few different ways you can orient the tower. One would be to build an orthonormal basis from the normalized direction from the tower position to the player position. Another method (which might be a little more immediately intuitive) is to use atan2() to compute an angle of rotation for the tower that will align it as desired, e.g. (untested):

y_angle = atan2(posb[2] - post[2], posb[0] - post[0]);
Depending on the conventions you're using, you may need to swap and/or negate the arguments to atan2(), or modify the angle that it returns.

Only 1 question. What is atan2()?
tried your tip(the coded one ) but it dont work, i´m so pissed, cause i need to deliver the work in the next 2 days, and this is the only think not working xD

first i tried to use the product between 2 vectors doing rotatef(post[0]*posb[0]+post[1]*posb[1]+post[2]*posb[2],0,1,0);
then i tried to swap the angle argument for your atan2() function but it still dont work :\.I googled a lot already, but i think this forum is my last hope :\

##### Share on other sites
"still don't work"

Could you be more specific? What are you using? OpenGL? Maybe the order of transformations are wrong
Could you show all the code?

##### Share on other sites
Are you #including <cmath> ? And using atn2 from the std -namespace?

##### Share on other sites

"still don't work"

Could you be more specific? What are you using? OpenGL? Maybe the order of transformations are wrong
Could you show all the code?

Sory for the English :\.

I will try.

My tower is done with this:
 void drawTorre(float m,float rtorre,float n){ glColor3f(1.0f, 2.0f, 0.0f); glPushMatrix(); glTranslatef(0, coiso*distancia*escala,-10); //initial position of the tower post[0]=0; post[1]=coiso*distancia*escala; post[2]=-10; float d =calculardistancia(post,posb); //Calculate the distance between the tower and the object if(d<=5) // compare if it is at the desired range { glRotatef(atan2(posb[0]-post[0],posb[2]-post[2]),0,1,0); //rotate the tower to the object } for(int i=0;i<ndonuts;i++){ ///draw the base of the tower glPushMatrix(); glRotatef(90,1*escala,0,0); glutWireTorus(raiointrior,raioexterior,numlados,aneis); glPopMatrix(); glTranslatef(0, coiso*distancia*escala, 0); } //Bule de chá // draw the top of the tower glTranslatef(0, coiso*distancia*escala-0.2, 0); glRotatef(ang,m,rtorre,n); glRotatef(-45,0,0,1*escala);//Incliar bool glColor3f(0.0f, 1.0f, 0.0f); glutSolidTeapot(tamanhobule); //Cria bule glPopMatrix(); } 

and my test object till now is
 void drawTriangolo(){ glTranslatef(x,y,z); // move o objecto // move the object with the keys posb[0]=x; //store position of x posb[1]=y;//store position of y posb[2]=z;//store position of z // ângulo em graus glRotatef(ang2,f,g,h); //ignore glRotatef(ang3,t,u,v); //ignore glPushMatrix(); glBegin(GL_TRIANGLES); glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(1.0f, 1.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 0.0f); glEnd(); glBegin(GL_TRIANGLES); glVertex3f(1.0f, 1.0f, 0.0f); glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 0.0f); glEnd(); glPopMatrix(); } 

ad this is the function that calc the distance

 float calculardistancia(float *a,float*b){ return (sqrt(pow(a[0]-b[0],2)+pow(a[2]-b[2],2))); } 

i want the tower to always be turned to the object (the triangle for now) since he get in the range, and until he get out of the range.:\

I´m using Opengl on visual studio 2010 and with c++

##### Share on other sites

Are you #including <cmath> ? And using atn2 from the std -namespace?

Nope, i never used atn2, so i didnt know that i needed other library beside cmath :\ and i´m using opengl

##### Share on other sites

[quote name='SuperVGA' timestamp='1302693743' post='4797900']
Are you #including <cmath> ? And using atn2 from the std -namespace?

Nope, i never used atn2, so i didnt know that i needed other library beside cmath :\ and i´m using opengl
[/quote]

Well, if you do use cmath, you would have #include <cmath> in the top of your code that uses atn2,
and either a using namespace std below that, or std::tan2 where you make your tan2 - invocation.

Hope this will solve your problem!

##### Share on other sites
Ty all, but still not working :\
my complete code is

 #include <glut.h> #include <cmath> #include <math.h> float x=0,y=0,z=0; float m=0,rtorre=0,n=0; float f=0,g=0,h=0; float t=0,u=0,v=0; float q=1; float ang=0; float ang2=0; float ang3=0; GLenum modo=GL_FILL; float post[3];//posicao da torre float posb[3]={0,0,0};//posicao do boneco float rtb[3]; // raio para rodar float dist=100; //distancia da torre ao boneco float coiso =1; float distancia=0.6; float escala=0.6; float tamanhobule=1*escala; float raiointrior=0.4*escala; float raioexterior=0.6*escala; int numlados=200*escala; int aneis=100*escala; int ndonuts=3;//número de dónuts void changeSize(int w, int h) { // Prevent a divide by zero, when window is too short // (you cant make a window with zero width). if(h == 0) h = 1; // compute window's aspect ratio float ratio = w * 1.0 / h; // Set the projection matrix as current glMatrixMode(GL_PROJECTION); // Load Identity Matrix glLoadIdentity(); // Set the viewport to be the entire window glViewport(0, 0, w, h); // Set perspective gluPerspective(45.0f ,ratio, 0.1f ,1000.0f); // return to the model view matrix mode glMatrixMode(GL_MODELVIEW); } float calculardistancia(float *a,float*b){ return (sqrt(pow(a[0]-b[0],2)+pow(a[2]-b[2],2))); } void drawTriangolo(){ glTranslatef(x,y,z); // move o objecto posb[0]=x; posb[1]=y; posb[2]=z; // ângulo em graus glRotatef(ang2,f,g,h); glRotatef(ang3,t,u,v); glPushMatrix(); glBegin(GL_TRIANGLES); glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(1.0f, 1.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 0.0f); glEnd(); glBegin(GL_TRIANGLES); glVertex3f(1.0f, 1.0f, 0.0f); glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 0.0f); glEnd(); glPopMatrix(); } void drawTorre(float m,float rtorre,float n){ using namespace std; glColor3f(1.0f, 2.0f, 0.0f); glPushMatrix(); glTranslatef(0, coiso*distancia*escala,-10); post[0]=0; post[1]=coiso*distancia*escala; post[2]=-10; float d =calculardistancia(post,posb); if(d<=5) { glRotatef(atan2(posb[2]-post[2],posb[0]-post[0]),0,1,0); } for(int i=0;i<ndonuts;i++){ glPushMatrix(); glRotatef(90,1*escala,0,0); glutWireTorus(raiointrior,raioexterior,numlados,aneis); glPopMatrix(); glTranslatef(0, coiso*distancia*escala, 0); } //Bule de chá glTranslatef(0, coiso*distancia*escala-0.2, 0); glRotatef(ang,m,rtorre,n); glRotatef(-45,0,0,1*escala);//Incliar bool glColor3f(0.0f, 1.0f, 0.0f); glutSolidTeapot(tamanhobule); //Cria bule glPopMatrix(); } void drawScene() { drawTorre(m,rtorre,n); drawTriangolo(); } void renderScene(void) { // clear buffers glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // set the camera glLoadIdentity(); gluLookAt(0.0,0.0,5.0, 0.0,0.0,-1.0, 0.0f,1.0f,0.0f); drawScene(); // End of frame glutSwapBuffers(); } // escrever função de processamento do teclado void teclado(unsigned char tecla, int a, int b){ switch (tecla){ case 'w': z+=0.1; break; case 's': z-=0.1; break; case 'a': x-=0.1; break; case 'd': x+=0.1; break; case 'i': ang+=5;rtorre=1;m=0; break; case 'k': ang-=5;rtorre=1;m=0; break; case 'j': ang2+=5;f=0;g=1; break; case 'l': ang2-=5;f=0;g=1; break; case 'o': ang3+=5;t=0;u=0;v=1; break; case 'p': ang3-=5;t=0;u=0;v=1; break; case 'r': q+=0.1; break; case 't': q-=0.1; break; } glutPostRedisplay(); } // escrever função de processamento do menu void menu(int id_op){ switch(id_op){ case 1 : modo=GL_FILL; break; case 2 : modo=GL_LINE; break; case 3: modo=GL_POINT; break; } glutPostRedisplay(); } void main(int argc, char **argv) { // pôr inicialização aqui glutInit(&argc, argv); glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA); glutInitWindowPosition(100,100); glutInitWindowSize(800,800); glutCreateWindow("CG@DI"); // pôr registo de funções aqui glutDisplayFunc(renderScene); glutReshapeFunc(changeSize); glutIdleFunc(renderScene); // pôr aqui registo da funções do teclado e rato glutKeyboardFunc(teclado); // pôr aqui a criação do menu glutCreateMenu(menu); glutAddMenuEntry("Vermelho",1); glutAddMenuEntry("Vermelho1",2); glutAddMenuEntry("Vermelho2",3); glutAttachMenu(GLUT_RIGHT_BUTTON); // alguns settings para OpenGL glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); // entrar no ciclo do GLUT aqui glutMainLoop(); } 

The only think that i want to be working is the damn tower facing for the object.
:| i´m beginning to panic xD

• 9
• 9
• 13
• 41
• 15