#include <math.h> // For math routines (such as sqrt & trig).
#include <stdio.h>
#include <GL/glut.h> // OpenGL Graphics Utility Library
#include "GluCylinders.h"
void ani(float , float , float );
void renderCylinder(float x1, float y1, float z1, float x2,float y2, float z2, float radius,int subdivisions,GLUquadricObj *quadric);
void renderCylinder_convenient(float x1, float y1, float z1, float x2,float y2, float z2, float radius,int subdivisions);
// The next global variable controls the animation's state and speed.
float RotateAngle = 0.0f; // Angle in degrees of rotation around y-axis
float Azimuth = 0.0; // Rotated up or down by this amount
float AngleStepSize = 3.0f; // Step three degrees at a time
const float AngleStepMax = 10.0f;
const float AngleStepMin = 0.1f;
int WireFrameOn = 1; // == 1 for wire frame mode
//points
float Geometry[9][3] = {
{ 4,2.0,0},
{ 4,2.0,0}, // Point1
{-1.5,0.2,0},
{-2,0.3,0},
{-2.5,0.6,0},
{-3,0.8,0},
{-3.5,1.0,0},
{ -5.5,1.8,0},//point 2
{ -5.5,1.8,0}
};
int x2[5],y2[5],z2[5];
unsigned int LOD=20;
// glutKeyboardFunc is called below to set this function to handle
// all "normal" key presses.
void myKeyboardFunc( unsigned char key, int x, int y )
{
switch ( key ) {
case 'w':
WireFrameOn = 1-WireFrameOn;
if ( WireFrameOn ) {
glPolygonMode ( GL_FRONT_AND_BACK, GL_LINE ); // Just show wireframes
}
else {
glPolygonMode ( GL_FRONT_AND_BACK, GL_FILL ); // Show solid polygons
}
glutPostRedisplay();
break;
case 'R':
AngleStepSize *= 1.5;
if (AngleStepSize>AngleStepMax ) {
AngleStepSize = AngleStepMax;
}
break;
case 'r':
AngleStepSize /= 1.5;
if (AngleStepSize<AngleStepMin ) {
AngleStepSize = AngleStepMin;
}
break;
case 27: // Escape key
exit(1);
}
}
// glutSpecialFunc is called below to set this function to handle
// all "special" key presses. See glut.h for the names of
// special keys.
void mySpecialKeyFunc( int key, int x, int y )
{
switch ( key ) {
case GLUT_KEY_UP:
Azimuth += AngleStepSize;
if ( Azimuth>80.0f ) {
Azimuth = 80.0f;
}
break;
case GLUT_KEY_DOWN:
Azimuth -= AngleStepSize;
if ( Azimuth < -80.0f ) {
Azimuth = -80.0f;
}
break;
case GLUT_KEY_LEFT:
RotateAngle += AngleStepSize;
if ( RotateAngle > 180.0f ) {
RotateAngle -= 360.0f;
}
break;
case GLUT_KEY_RIGHT:
RotateAngle -= AngleStepSize;
if ( RotateAngle < -180.0f ) {
RotateAngle += 360.0f;
}
break;
}
glutPostRedisplay();
}
/*
* drawScene() handles the animation and the redrawing of the
* graphics window contents.
*/
void drawScene(void)
{int i,j,k=0,m=0;
float b0,b1,b2,b3,t,x3,y3,z3,n1,n2,n3;
//Clear the rendering window
//for( i=0;i<5;i++)
//{
//x2[i]=0.5*(G[i+1][0]-G[i-1][0]);
//y2[i]=0.5*(G[i+1][1]-G[i-1][1]);
//z2[i]=0.5*(G[i+1][2]-G[i-1][2]);
//}
// Clear the rendering window
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Rotate the image
glMatrixMode( GL_MODELVIEW ); // Current matrix affects objects positions
glLoadIdentity(); // Initialize to the identity
glTranslatef( -0.5, 0.0, -35.0 ); // Translate from origin (in front of viewer)
glRotatef( RotateAngle, 0.0, 1.0, 0.0 ); // Rotate around y-axis
glRotatef( Azimuth, 1.0, 0.0, 0.0 ); // Set Azimuth angle
//------------------------------------------------------------
glDisable( GL_CULL_FACE );
glPushMatrix();
glTranslatef( -4.5, 0.5, 0.0 );
glRotatef( -90.0, 1.0, 0.0, 0.0 );
glColor3f( 1.0, 0.2, 0.2 ); // Reddish color x<=4.5 0.5=<y<=2.5
// Parameters: height, radius, slices, stacks
drawGluCylinder(1.5, 0.2, 8, 8 );
glPopMatrix();
glEnable( GL_CULL_FACE );
glPushMatrix();
glTranslatef( -4.5, 0.0, 0.0 );
glRotatef( -90.0, 1.0, 0.0, 0.0 );
glColor3f( 0.2, 1.0, 0.2 ); // Greenish color
// Parameters: height, base radius, top radius, slices, stacks
drawGluSlantCylinderWithCaps( 0.5, 0.01, 0.2, 28, 28 );
glPopMatrix();
//------------------------------------------------------------------1st wicket
glDisable( GL_CULL_FACE );
glPushMatrix();
glTranslatef( -4.5, 0.5, 0.6 );
glRotatef( -90.0, 1.0, 0.0, 0.0 );
glColor3f( 1.0, 0.2, 0.2 ); // Reddish color
// Parameters: height, radius, slices, stacks
drawGluCylinder(1.5, 0.2, 8, 8 );
glPopMatrix();
glEnable( GL_CULL_FACE );
glPushMatrix();
glTranslatef( -4.5, 0.0, 0.6 );
glRotatef( -90.0, 1.0, 0.0, 0.0 );
glColor3f( 0.2, 1.0, 0.2 ); // Greenish color
// Parameters: height, base radius, top radius, slices, stacks
drawGluSlantCylinderWithCaps( 0.5, 0.01, 0.2, 28, 28 );
glPopMatrix();
//wills
glDisable( GL_CULL_FACE );
glPushMatrix();
glTranslatef( -4.5, 2.05, 0.6 );
glRotatef( -180.0, 1.0, 0.0, 0.0 );
glColor3f( 1.0, 0.2, 0.2 ); // Reddish color
// Parameters: height, radius, slices, stacks
drawGluCylinder(0.6, 0.05, 18, 18 );
glPopMatrix();
//---------------------------------------------------------------------------2nd
glDisable( GL_CULL_FACE );
glPushMatrix();
glTranslatef( -4.5, 0.5, 1.2 );
glRotatef( -90.0, 1.0, 0.0, 0.0 );
glColor3f( 1.0, 0.2, 0.2 ); // Reddish color
// Parameters: height, radius, slices, stacks
drawGluCylinder(1.5, 0.2, 8, 8 );
glPopMatrix();
glEnable( GL_CULL_FACE );
glPushMatrix();
glTranslatef( -4.5, 0.0, 1.2 );
glRotatef( -90.0, 1.0, 0.0, 0.0 );
glColor3f( 0.2, 1.0, 0.2 ); // Greenish color
// Parameters: height, base radius, top radius, slices, stacks
drawGluSlantCylinderWithCaps( 0.5, 0.01, 0.2, 28, 28 );
glPopMatrix();
//wills
glDisable( GL_CULL_FACE );
glPushMatrix();
glTranslatef( -4.5, 2.05, 1.3 );
glRotatef( -180.0, 1.0, 0.0, 0.0 );
glColor3f( 1.0, 0.2, 0.2 ); // Reddish color
// Parameters: height, radius, slices, stacks
drawGluCylinder(0.6, 0.05, 18, 18 );
glPopMatrix();
//--------------------------------------------------3rd wicket
// glDisable( GL_CULL_FACE );
//glPushMatrix();
//glTranslatef( -4.5, 0.5, 0.0 );
//glRotatef( -90.0, 1.0, 0.0, 0.0 );
//glColor3f( 1.0, 0.2, 0.2 ); // Reddish color
//// Parameters: height, radius, slices, stacks
//drawGluCylinder(1.5, 0.2, 8, 8 );
//glPopMatrix();
// glEnable( GL_CULL_FACE );
//glPushMatrix();
//glTranslatef( -4.5, 0.0, 0.0 );
//glRotatef( -90.0, 1.0, 0.0, 0.0 );
//glColor3f( 0.2, 1.0, 0.2 ); // Greenish color
//// Parameters: height, base radius, top radius, slices, stacks
//drawGluSlantCylinderWithCaps( 0.5, 0.05, 0.2, 28, 28 );
//glPopMatrix();
// glDisable( GL_CULL_FACE );
//glPushMatrix();
//glTranslatef( -4.5, 0.5, 1.0 );
//glRotatef( -90.0, 1.0, 0.0, 0.0 );
//glColor3f( 1.0, 0.2, 0.2 ); // Reddish color
//// Parameters: height, radius, slices, stacks
//drawGluCylinder(1.5, 0.2, 8, 8 );
//glPopMatrix();
//-------------------------------
glDisable( GL_CULL_FACE );
glPushMatrix();
glTranslatef( 4.5, 0.5, 0.0 );
glRotatef( -90.0, 1.0, 0.0, 0.0 );
glColor3f( 1.0, 0.2, 0.2 ); // Reddish color
// Parameters: height, radius, slices, stacks
drawGluCylinder(1.5, 0.2, 8, 8 );
glPopMatrix();
glEnable( GL_CULL_FACE );
glPushMatrix();
glTranslatef( 4.5, 0.0, 0.0 );
glRotatef( -90.0, 1.0, 0.0, 0.0 );
glColor3f( 0.2, 1.0, 0.2 ); // Greenish color
// Parameters: height, base radius, top radius, slices, stacks
drawGluSlantCylinderWithCaps( 0.5, 0.01, 0.2, 28, 28 );
glPopMatrix();
glDisable( GL_CULL_FACE );
glPushMatrix();
glTranslatef( 4.5, 0.5, 0.6 );
glRotatef( -90.0, 1.0, 0.0, 0.0 );
glColor3f( 1.0, 0.2, 0.2 ); // Reddish color
// Parameters: height, radius, slices, stacks
drawGluCylinder(1.5, 0.2, 8, 8 );
glPopMatrix();
glEnable( GL_CULL_FACE );
glPushMatrix();
glTranslatef( 4.5, 0.0, 0.6 );
glRotatef( -90.0, 1.0, 0.0, 0.0 );
glColor3f( 0.2, 1.0, 0.2 ); // Greenish color
// Parameters: height, base radius, top radius, slices, stacks
drawGluSlantCylinderWithCaps( 0.5, 0.01, 0.2, 28, 28 );
glPopMatrix();
//wills
glDisable( GL_CULL_FACE );
glPushMatrix();
glTranslatef( 4.5, 2.05, 0.6 );
glRotatef( -180.0, 1.0, 0.0, 0.0 );
glColor3f( 1.0, 0.2, 0.2 ); // Reddish color
// Parameters: height, radius, slices, stacks
drawGluCylinder(0.6, 0.05, 18, 18 );
glPopMatrix();
glDisable( GL_CULL_FACE );
glPushMatrix();
glTranslatef( 4.5, 0.5, 1.2 );
glRotatef( -90.0, 1.0, 0.0, 0.0 );
glColor3f( 1.0, 0.2, 0.2 ); // Reddish color
// Parameters: height, radius, slices, stacks
drawGluCylinder(1.5, 0.2, 8, 8 );
glPopMatrix();
glEnable( GL_CULL_FACE );
glPushMatrix();
glTranslatef( 4.5, 0.0, 1.2 );
glRotatef( -90.0, 1.0, 0.0, 0.0 );
glColor3f( 0.2, 1.0, 0.2 ); // Greenish color
// Parameters: height, base radius, top radius, slices, stacks
drawGluSlantCylinderWithCaps( 0.5, 0.01, 0.2, 28, 28 );
glPopMatrix();
glDisable( GL_CULL_FACE );
glPushMatrix();
glTranslatef( 4.5, 0.5, 0.0 );
glRotatef( -90.0, 1.0, 0.0, 0.0 );
glColor3f( 1.0, 0.2, 0.2 ); // Reddish color
// Parameters: height, radius, slices, stacks
drawGluCylinder(1.5, 0.2, 8, 8 );
glPopMatrix();
//wills
glDisable( GL_CULL_FACE );
glPushMatrix();
glTranslatef( 4.5, 2.05, 1.3 );
glRotatef( -180.0, 1.0, 0.0, 0.0 );
glColor3f( 1.0, 0.2, 0.2 ); // Reddish color
// Parameters: height, radius, slices, stacks
drawGluCylinder(0.6, 0.05, 18, 18 );
glPopMatrix();
glBegin(GL_LINE_STRIP);
// use the parametric time value 0 to 1
for( j=1;j<=2;j++)
{
for(i=0;i!=LOD;++i) {
//glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
t = (float)i/(LOD-1);
x3 = 0.5*((-Geometry[j-1][0] + 3*Geometry[j][0] -3*Geometry[j+1][0] + Geometry[j+2][0])*t*t*t+
(2*Geometry[j-1][0] -5*Geometry[j][0] +4*Geometry[j+1][0] -Geometry[j+2][0])*t*t +(-Geometry[j-1][0] + Geometry[j+1][0])*t + 2*Geometry[j][0]);
y3 = 0.5*((-Geometry[j-1][1] + 3*Geometry[j][1] -3*Geometry[j+1][1] + Geometry[j+2][1])*t*t*t+
(2*Geometry[j-1][1] -5*Geometry[j][1] +4*Geometry[j+1][1] -Geometry[j+2][1])*t*t +(-Geometry[j-1][1] + Geometry[j+1][1])*t + 2*Geometry[j][1]);
z3 = 0.5*((-Geometry[j-1][2] + 3*Geometry[j][2] -3*Geometry[j+1][2] + Geometry[j+2][2])*t*t*t+
(2*Geometry[j-1][2] -5*Geometry[j][2] +4*Geometry[j+1][2] -Geometry[j+2][2])*t*t +(-Geometry[j-1][2] + Geometry[j+1][2])*t + 2*Geometry[j][2]);
// specify the point
glVertex3f( x3,y3,z3);
glColor3f(1,0,0);
// specify the point
glVertex3f( x3,y3,z3 );
ani(x3,y3,z3);
//for(i=0;i<=2;i++);3
glColor3f(1,1,0);
if(i==0)
renderCylinder_convenient(Geometry[j][0],Geometry[j][1],Geometry[j][2],x3,y3,z3,0.3,32);
else
renderCylinder_convenient(n1,n2,n3,x3,y3,z3,0.3,32);
n1=x3; n2=y3; n3=z3;
glutSwapBuffers();
}
}
glEnd();
// glFlush();
//glutSwapBuffers();
}
// Initialize OpenGL's rendering modes
void initRendering()
{
glEnable( GL_DEPTH_TEST ); // Depth testing must be turned on
glCullFace( GL_BACK );
glPolygonMode ( GL_FRONT_AND_BACK, GL_LINE ); // Just show wireframes at first
}
// Called when the window is resized
// w, h - width and height of the window in pixels.
void resizeWindow(int w, int h)
{
double aspectRatio;
// Define the portion of the window used for OpenGL rendering.
glViewport( 0, 0, w, h ); // View port uses whole window
// Set up the projection view matrix: perspective projection
// Determine the min and max values for x and y that should appear in the window.
// The complication is that the aspect ratio of the window may not match the
// aspect ratio of the scene we want to view.
w = (w==0) ? 1 : w;
h = (h==0) ? 1 : h;
aspectRatio = (double)w / (double)h;
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 15.0, aspectRatio, 25.0, 45.0 );
}
// Main routine
// Set up OpenGL, define the callbacks and start the main loop
int main( int argc, char** argv )
{
glutInit(&argc, argv);
// We're going to animate it, so double buffer
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );
// Window position (from top corner), and size (width% and hieght)
glutInitWindowPosition( 10, 60 );
glutInitWindowSize( 360, 360 );
glutCreateWindow( "GluCylinders" );
// Initialize OpenGL as we like it..
initRendering();
// Set up callback functions for key presses
glutKeyboardFunc( myKeyboardFunc ); // Handles "normal" ascii symbols
glutSpecialFunc( mySpecialKeyFunc ); // Handles "special" keyboard keys
// Set up the callback function for resizing windows
glutReshapeFunc( resizeWindow );
// Call this for background processing
// glutIdleFunc( myIdleFunction );
// call this whenever window needs redrawing
glutDisplayFunc( drawScene );
fprintf(stdout, "Arrow keys control viewpoint.\n");
fprintf(stdout, "Press \"w\" to toggle wireframe mode.\n");
fprintf(stdout, "Press \"R\" or \"r\" to increase or decrease rate of movement (respectively).\n");
// Start the main loop. glutMainLoop never returns.
glutMainLoop( );
return(0); // This line is never reached.
}
// ************************************************************************
// These are four general purpose routines for generating
// cylinders, with or without caps.
// See the OpenGL redbook or other glu documentation for more information.
// These generate normals, but not texture coordinates.
// To generate texture coordinates, you need to modify the code to
// call gluQuadricTexture();
// For higher performance, you should consider putting your cylinders into
// a display list.
// Please note these routines do not do all possible error checking, and
// thus should not be used in a production or other critical environment.
// ************************************************************************
// A Reusable gluQuadric object:
GLUquadricObj* myReusableQuadric = 0;
void drawGluCylinder( double height, double radius, int slices, int stacks ) {
drawGluSlantCylinder( height, radius, radius, slices, stacks );
}
void drawGluSlantCylinder( double height, double radiusBase, double radiusTop, int slices, int stacks )
{
if ( ! myReusableQuadric ) {
myReusableQuadric = gluNewQuadric();
// Should (but don't) check if pointer is still null --- to catch memory allocation errors.
gluQuadricNormals( myReusableQuadric, GL_TRUE );
}
// Draw the cylinder.
gluCylinder( myReusableQuadric, radiusBase, radiusTop, height, slices, stacks );
}
void drawGluCylinderWithCaps( double height, double radius, int slices, int stacks ) {
drawGluSlantCylinderWithCaps( height, radius, radius, slices, stacks );
}
void ani(float x, float y, float z)
{int i, j;
glLoadIdentity();
glTranslatef(-0.5, 0.0, -35.0);
glRotatef( RotateAngle, 0.0, 1.0, 0.0 );
glRotatef( Azimuth, 1.0, 0.0, 0.0 );
glPushMatrix();
glTranslatef (x, y, z);
glColor3f( 1, 0.0, 0.2 );
glutSolidSphere (0.1, 10, 10);
for(i = 0; i < 1000; i++)
for(j = 0; j < 5000; j++);
glPopMatrix();
//glPushMatrix();
glutSwapBuffers();
}
void renderCylinder(float x1, float y1, float z1, float x2,float y2, float z2, float radius,int subdivisions,GLUquadricObj *quadric)
{ float v,rx,ry,ax,vx = x2-x1;
float vy = y2-y1;
float vz = z2-z1; //handle the degenerate case of z1 == z2 with an approximation
if(vz == 0)
vz =.00000001;
v = sqrt( vx*vx + vy*vy + vz*vz );
ax = 57.2957795*acos( vz/v );
if ( vz < 0.0 )
ax = -ax;
rx = -vy*vz;
ry = vx*vz;
glPushMatrix(); //draw the cylinder body
glTranslatef( x1,y1,z1 );
glRotatef(ax, rx, ry, 0.0);
gluQuadricOrientation(quadric,GLU_OUTSIDE);
gluCylinder(quadric, radius, radius, v, subdivisions, 1); //draw the first cap
gluQuadricOrientation(quadric,GLU_INSIDE);
gluDisk( quadric, 0.0, radius, subdivisions, 1);
glTranslatef( 0,0,v ); //draw the second cap
gluQuadricOrientation(quadric,GLU_OUTSIDE);
gluDisk( quadric, 0.0, radius, subdivisions, 1);
glPopMatrix();
}
void renderCylinder_convenient(float x1, float y1, float z1, float x2,float y2, float z2, float radius,int subdivisions){
//the same quadric can be re-used for drawing many cylinders
GLUquadricObj *quadric=gluNewQuadric();
gluQuadricNormals(quadric, GLU_SMOOTH);
renderCylinder(x1,y1,z1,x2,y2,z2,radius,subdivisions,quadric);
gluDeleteQuadric(quadric);}
void drawGluSlantCylinderWithCaps( double height, double radiusBase, double radiusTop, int slices, int stacks )
{
// First draw the cylinder
drawGluSlantCylinder( height, radiusBase, radiusTop, slices, stacks );
// Draw the top disk cap
glPushMatrix();
glTranslated(0.0, 0.0, height);
gluDisk( myReusableQuadric, 0.0, radiusTop, slices, stacks );
glPopMatrix();
// Draw the bottom disk cap
glPushMatrix();
glRotated(180.0, 1.0, 0.0, 0.0);
gluDisk( myReusableQuadric, 0.0, radiusBase, slices, stacks );
glPopMatrix();
}