# Thread: c program using opengl for oscillating pendulum

1. ## c program using opengl for oscillating pendulum

need a program for an oscillating pendulum - a sphere suspended to the end of the thread that can oscillate about the fixed point at the other end of the thread. need the code. im creating the sphere by recursive subdivision of a tetrahedron. need help with attaching the string and making it oscillate. thank you.

2. "need the code." Homework task? How exactely is it Windows(R) specific?

How detailed does the simulation have to be? Is the thread supposed to be flexible or rigid?

For the rigid case, I remember having solved the underlying differential equation in school some time. The result can be found here

Regarding the code: If you understand the problem and your programming language (neither is hard), it is fairly easy to write the simulation code yourself (from the post I assume you already have the drawing code).

3. Yes, its a homework task. I've just started working on the drawing code. I don't know much about OpenGL, just a beginner. If not the code for the entire program, I'd at least like an idea on how to go about with it. Like i said, i was able to create a sphere by recursive subdivision of a tetrahedron and the thread I created using GL_LINES from the centre of the sphere to a point outside. I need to get it to rotate about its axis now.

4. You could aproach the rotation picewise: Write down a translation matrix that moves the tip of the line to the origin (and the rest of the pendulum accordingly), a rotation matrix that rotates the pendulum around one of the major axes, a translation matrix that moves it back to it is supposed to be at. Multiply those matrices and you end up with a single matrix that depends on the angle of rotation.

Somewhere, you need a variable to store time passed since the beginning of the program. At the end of every frame, update that variable. At the beginning of the frame, this variable can be used to determine the angle from the formula on the Wikipedia page (or the solution of your differential equation). Once you have the angle, you can determine the value of the matrix and send it to the shader.

5. Well, I understand the multiplication of the 3 matrices to achieve the rotation but I dont understand how to construct a matrix for translation/rotation. Could you please help me with it? This is my code uptil now that just creates a stationary pendulum:
#include<stdio.h>
#include<msclr/glut.h>
#include<math.h>
int n=10;
GLfloat v[4][3]={{0.0,0.0,1.0},{0.0,0.942809,-0.33333},{-0.816497,-0.471405,-0.33333},{0.816497,-0.471405,-0.333333}};
GLfloat a[2][3]={{0.0,0.0,-0.333333},{0.0,10.0,-0.333333}};
void normalize(GLfloat *p)
{
double d=0.0;
int i;
for(i=0;i<3;i++)
d+=p[i]*p[i];
d=sqrt(d);
if(d>0.0)
for(i=0;i<3;i++)
p[i]/=d;
}
void triangle(GLfloat *a,GLfloat *b,GLfloat *c)
{
glBegin(GL_POLYGON);
glNormal3fv(a);
glVertex3fv(a);
glVertex3fv(b);
glVertex3fv(c);
glEnd();
}
void divide_triangle(GLfloat *a,GLfloat *b,GLfloat *c,int n)
{
GLfloat v1[3],v2[3],v3[3];
int j;
if(n>0)
{
for(j=0;j<3;j++)
v1[j]=a[j]+b[j];
normalize(v1);
for(j=0;j<3;j++)
v2[j]=a[j]+c[j];
normalize(v2);
for(j=0;j<3;j++)
v3[j]=c[j]+b[j];
normalize(v3);
divide_triangle(a,v2,v1,n-1);
divide_triangle(c,v3,v2,n-1);
divide_triangle(b,v1,v3,n-1);
divide_triangle(v1,v2,v3,n-1);
}
else
triangle(a,b,c);
}
void tetrahedron(int n)
{
divide_triangle(v[0],v[1],v[2],n);
divide_triangle(v[3],v[2],v[1],n);
divide_triangle(v[0],v[3],v[1],n);
divide_triangle(v[0],v[2],v[3],n);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glClearColor(1.0,1.0,1.0,1.0);
glColor3f(1.0,0.0,0.0);
tetrahedron(n);
glColor3f(0.0,0.0,1.0);
glBegin(GL_LINES);
glVertex3fv(a[0]);
glVertex3fv(a[1]);
glEnd();
glFlush();
}
void myReshape(int w,int h)
{
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
if(w<=h)
glOrtho(-2.0,2.0,-2.0*(GLfloat)h/(GLfloat)w,2.0*(GLfloat)h/(GLfloat)w,-10.0,10.0);
else
glOrtho(-2.0*(GLfloat)w/(GLfloat)h,2.0*(GLfloat)w/(GLfloat)h,-2.0,2.0,-10.0,10.0);
glMatrixMode(GL_MODELVIEW);
}
void main(int argc,char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGB|GLUT_DEPTH);
glutInitWindowSize(500,500);
glutCreateWindow("Pendulum");
glutReshapeFunc(myReshape);
glutDisplayFunc(display);
glEnable(GL_DEPTH_TEST);
glutMainLoop();
}

6. Originally Posted by andre_arjun
Well, I understand the multiplication of the 3 matrices to achieve the rotation but I dont understand how to construct a matrix for translation/rotation. Could you please help me with it?
Homogeneous coordinates
You don't use 3x3 matrices and 3 component vectors, you use 4x4 matrices 4 component vectors. If the last component "happens to be" 1.0, it will result in the last row of the matrix being added to the vector.

I suggest reading a tutorial related to the subject.

7. Alright, I figured the rotating out. Translate the figure to the origin, rotate and translate back. That works. But now I have a problem with limiting the angle of rotation. I declared a global variable theta to rotate by and used the glutIdleFunc to continuously increment theta. The problem is idlefunc is always running so my pendulum rotates in circles. How can I limit my rotation angle to, say, +90 and -90 degrees?
#include<stdio.h>
#include<GL/freeglut.h>
#include<math.h>
//normalize(GLfloat *p)
//triangle(GLfloat *a,GLfloat *b,GLfloat *c)
//divide_triangle(GLfloat *a,GLfloat *b,GLfloat *c,int n)
//void tetrahedron(int n)
GLfloat theta=0.0;
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glClearColor(1.0,1.0,1.0,1.0);
glBegin(GL_LINES);
glVertex3fv(a[0]);
glVertex3fv(a[1]);
glEnd();
glColor3f(1.0,0.0,0.0);
tetrahedron(n);
glColor3f(0.0,0.0,1.0);
glMatrixMode(GL_MODELVIEW);
glTranslatef(0.0,+3.0,-0.333333);
glRotatef(theta,0.0,0.0,1.0);
glTranslatef(0.0,-3.0,+0.333333);
glFlush();
}
//myReshape(int w,int h)
void oscillate()
{
theta+=10.0;
glutPostRedisplay();
}
void main(int argc,char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGB|GLUT_DEPTH);
glutInitWindowSize(1366,768);
glutCreateWindow("Pendulum");
glutReshapeFunc(myReshape);
glutDisplayFunc(display);
glutIdleFunc(oscillate);
glEnable(GL_DEPTH_TEST);
glutMainLoop();
}

8. I tried lot of alternatives.
A for loop in the idlefunc oscillate() to rotate till +90 and then back to -90:
void oscillate()
{
int i;
for(i=0;i<=90;i+=30)
theta+=30;
for(i=0;i<180;i+=30)
theta-=30;
glutPostRedisplay();
}

I tried to use a mouse callback function through which I incremented theta on a right click and decremented it on a left click. I used a global variable as a flag:
float global;
void oscillate()
{
if(global==0.0)
{
theta-=theta;
glutPostRedisplay();
}
else if(global==1.0)
{
theta+=theta;
glutPostRedisplay();
}
}

void mouse(int btn, int state, int x, int y)i
{
if(btn==GLUT_LEFT_BUTTON&&state==GLUT_DOWN)
global==0.0;
if(btn==GLUT_RIGHT_BUTTON&&state==GLUT_DOWN)
global==1.0;
}

9. I don't know what you thought of when writing those functions, but none of them have any relationship to movements of a pendulum. What was that strange for loop supposed to do that only adds constant values without anything being drawn at all? If you subtract theta from itself, the result is 0!!

If you go to that wikipedia article I posted earlier, you would know that the movement of a pendulum is a cosine of some constant multiplied with the current time.

Knowledge of oscillation and a little bit of common sense should actually lead you to something like this:

theta = theta_0 * cos(w*t)

The article mentions how the angular frequency is caclulted. Simply use a global or static variable to accumulate time every frame and calculate theta from that.

10. Im sorry, thats theta+=10.0 and theta-=10.0. I just need to show that the pendulum (or the object that I've created) rotates to a particular angle, say 0 to +90 degrees and back to -90 degrees in a single plane. I just want to show that simple movement visually. I'm still a beginner, i just started studying opengl a month ago. This is a very very basic project. I didn't mean the exact movement of a pendulum scientifically, its just a simple project to show 2D movements, it doesnt need to be accurate physics-wise. As for all the alternatives I tried, they were just ideas I was trying to make work, obviously they were bad ones but I was just trying things out to get a solution.

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•