#include <stdlib.h>
#include <stdio.h>
#ifndef WIN32
#include <unistd.h>
#else
#define random rand
#endif
#include <math.h>
#include <GL/glut.h>
#ifndef M_PI
#define M_PI 3.14159265
#endif
#ifndef M_PI_2
#define M_PI_2 1.57079632
#endif
GLboolean moving = GL_FALSE;
#define MAX_UFO 15
#define ADD_UFO 1
#define REMOVE_UFO 2
#define MOTION_ON 3
#define MOTION_OFF 4
#define QUIT 5
struct {
float speed; /* zero speed means not flying */
float theta;
float x, y, z, angle;
} UFO[MAX_UFO];
void draw(void)
{
int i;
glClear(GL_DEPTH_BUFFER_BIT);
/* paint black to smooth shaded polygon for background */
glDisable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
glBegin(GL_POLYGON);
glColor3f(0.0, 0.0,0.0);
glVertex3f(-20, 20, -19);
glVertex3f(20, 20, -19);
glColor3f(0.0, 0.5, 1.0);
glVertex3f(20, -20, -19);
glVertex3f(-20, -20, -19);
glEnd();
glEnable(GL_DEPTH_TEST); /* paint UFO */
glShadeModel(GL_FLAT);
for (i = 0; i < MAX_UFO; i++)
if (UFO[i].speed != 0.0) /*ufo in movement*/
{
glPushMatrix();
glTranslatef(UFO[i].x, UFO[i].y, UFO[i].z);
glRotatef(290.0, 1.0, 0.0, 0.0);
glRotatef(UFO[i].angle, 0.0, 0.0, 1.0);
glScalef(1.0/3.0, 1.0/4.0, 1.0/4.0);
glTranslatef(0.0, -4.0, -1.5);
glColor3f(1.0,1.0,1.0);
glutWireSphere(1.5,15,15);
glPopMatrix();
glPushMatrix();
glTranslatef(UFO[i].x, UFO[i].y, UFO[i].z);
glRotatef(290.0, 1.0, 0.0, 0.0);
glRotatef(UFO[i].angle, 0.0, 0.0, 1.0);
glScalef(1.0/3.0, 1.0 / 4.0, 1.0 / 4.0);
glTranslatef(0.75, -4.0, -1.5);
glColor3f(1.0,0.0,0.0);
glutSolidTeapot(1.15);
glPopMatrix();
glPushMatrix();
glTranslatef(UFO[i].x, UFO[i].y, UFO[i].z);
glRotatef(290.0, 1.0, 0.0, 0.0); /*rotates x axis with 290 degree*/
glRotatef(UFO[i].angle, 0.0, 0.0, 1.0);
glScalef(1.0 /3.0, 1.0 / 4.0, 1.0 / 4.0);
glTranslatef(0.95, -4.0,-1.5);
glColor3f(0.0,0.0,0.0);
glutSolidCone(3.75,0.5,14,5);
glPopMatrix();
}
glutSwapBuffers();
}
/*t positions the ufo with a function that is dependent on theta*/
void tick_per_UFO(int i) /*define the ufo position and speed incrementor*/
{
float theta = UFO[i].theta += UFO[i].speed;
UFO[i].z = -9 + 4 * cos(theta); /* z=length*cos(angle) */
UFO[i].x = 4 * sin(2 * theta);
UFO[i].y = sin(theta / 3.4) * 3;
/* degree=radians*180/pi */
UFO[i].angle = (((2.0) + M_PI_2) * sin(theta) - M_PI_2) * 180 / M_PI; /*calculates nor of degrees using nor of radians*/
if (UFO[i].speed < 0.0)
UFO[i].angle += 180;
}
void add_UFO(void)
{
int i;
for (i = 0; i < MAX_UFO; i++)
if (UFO[i].speed == 0)
{
UFO[i].speed = ((float) (random() % 20)) * 0.0001 + 0.02;
if (random() & 0x1)
UFO[i].speed *= -1;
UFO[i].theta = ((float) (random() % 257)) * 0.1111;
tick_per_UFO(i);
if (!moving)
glutPostRedisplay(); /*Request redisplay*/
return;
}
}
void remove_UFO(void)
{
int i;
for (i = MAX_UFO - 1; i >= 0; i--)
if (UFO[i].speed != 0)
{
UFO[i].speed = 0;
if (!moving)
glutPostRedisplay();
return;
}
}
void tick(void)
{
int i;
for (i = 0; i < MAX_UFO; i++)
if (UFO[i].speed != 0.0)
tick_per_UFO(i);
}
void animate(void)
{
tick();
glutPostRedisplay(); /*Request redisplay*/
}
void visible(int state)
{
if (state == GLUT_VISIBLE)
{
if (moving)
glutIdleFunc(animate);
}
else
{
if (moving)
glutIdleFunc(NULL);
}
}
void keyboard(unsigned char ch, int x, int y)
{
switch (ch)
{
case ' ':if (!moving)
{
tick();
glutPostRedisplay(); /*Request redisplay*/
}
break;
case 27:exit(0); /* ESC */
break;
}
}
void menu(int item)
{
switch (item) {
case ADD_UFO:add_UFO();
break;
case REMOVE_UFO:remove_UFO();
break;
case MOTION_ON:moving = GL_TRUE;
glutIdleFunc(animate);
break;
case MOTION_OFF:moving = GL_FALSE;
glutIdleFunc(NULL);
break;
case QUIT:exit(0);
break;
}
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );
glutCreateWindow("UFO");
glutDisplayFunc(draw); /*Display Callback function*/
glutKeyboardFunc(keyboard); /*Keyboard Callback function*/
glutVisibilityFunc(visible);
glutCreateMenu(menu);
glutAddMenuEntry("Add UFO", ADD_UFO);
glutAddMenuEntry("Remove UFO", REMOVE_UFO);
glutAddMenuEntry("Motion on", MOTION_ON);
glutAddMenuEntry("Motion off",MOTION_OFF);
glutAddMenuEntry("Quit", QUIT);
glutAttachMenu(GLUT_RIGHT_BUTTON); /* setup OpenGL state */
glClearDepth(1.0);
glClearColor(0.0, 0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 20); /*Perspective viewing*/
glMatrixMode(GL_MODELVIEW);
add_UFO(); /* add three initial random UFO */
add_UFO();
add_UFO();
glutMainLoop(); /* start event processing */
return 0;
}
the above code is for 3D object ufo…in this I’m not getting the function void tick_per_UFO(int i) ,explain how it will work and what is the basic formula for those x,y,z axis (i.e, UFO[i].z = -9 + 4 * cos(theta); UFO[i].x = 4 * sin(2 * theta); UFO[i].y = sin(theta / 3.4)