I have a Ball class which inherits The Body abstract class, this is the draw method of the ball class :
void Ball::draw() const
{
glPushMatrix();
Vector3 b=rotationaxis.begin;//rotationaxis is a Line variable, Line is a struct that has two points : begin and end , both are Vector3 variables
Vector3 e=rotationaxis.end-b;//Vector3 has all the operators needed for vector maths(sum, crossproduct , length , anglebetween two vectors , etc)
glTranslatef(centerofmass.X(),centerofmass.Y(),centerofmass.Z());//centerofmass is inherited from body and it's Vector3, Balls have their centerofmass at their origin
glTranslatef(-b.X(),-b.Y(),-b.Z());
glRotatef(thetarotate*180/pi,e.X(),e.Y(),e.Z());//thetarotate is an attribute calculated by physics , it is zero if you don't apply any angular acceleration
glTranslatef(b.X(),b.Y(),b.Z());
glutSolidSphere(radius,100,100);
glPopMatrix();
}
rotationaxis is the axis I want to rotate the ball around(which is not assumed to be fixed), centerofmass is as its name applies, Balls have their centerofmass in their origin.
The main.cpp file is this :
#include <iostream>
#include <cmath>
#include "ball.h"
using namespace std;
Ball ball(0.3,Vector3(0,0,0),0.5,0.01);//radius=0.3 , origin is in (0,0,0) , mass=0.5, dt(the time step)=0.01 seconds
void init()
{
glClearColor(0,0,0,0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glShadeModel(GL_SMOOTH);
}
void renderScene()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glColor3f(1,1,1);
glPushMatrix();
ball.draw();
glPopMatrix();
glutSwapBuffers();
}
void changeSize(int width,int height)
{
glViewport(0,0,width,height);
}
void idle()
{
glutPostRedisplay();
}
void specialfunc(int key,int x,int y)
{
switch(key)
{
case GLUT_KEY_UP:
ball.applyforce(Force(Vector3(0,0,1),2));//when pressing Up arrow , apply a force to the positive z direction(towards you the watcher of the screen) with strength of 2 newtons
case GLUT_KEY_DOWN:
ball.applyforce(Force(Vector3(0,0,-1),2));//when Down apply force in the opposite direction and the same strength
case GLUT_KEY_LEFT:
ball.applytorque(-4);//apply torque of -4 newton . meter, angularacceleration=torque/rotationalinertia , rotationalinertia of a ball=2*mass*radius*radius/5(from wikipedia) Those calculation are made in applytorque and angular velocity is changed according to angular acceleration and dt(angvel+=angacc*dt) and thetarotate+=angvel*dt, thetarotate is then maintained to be in the interval [-twopi,twopi]
case GLUT_KEY_RIGHT:
ball.applytorque(4);//the same but in the opposite direction
}
}
int main(int argc, char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(320,320);
glutCreateWindow("Lighthouse3D- GLUT Tutorial");
init();
glutSpecialFunc(specialfunc);
glutDisplayFunc(renderScene);
glutReshapeFunc(changeSize);
glutIdleFunc(idle);
glutMainLoop();
return 0;
}
I’m sure the phyisical calculations are right(checked it by debug)
Problem:
the rotation doesn’t work correctly, sometimes it rotate backwards(while I expect it to rotate forward), and when I stop pressing the right key for example it stops rotating, it shouldn’t stop instantly because in real world it slows down due to friction and etc, I didn’t program friction yet so it shouldn’t stop at all until I apply a torque opposite to its rotation direction(By pressing the left button for example).
I know the wrong is with the draw method but I can’t figure it out, what’s the problem ?
Infos:
I’m running linux mint and using Freeglut(not glut), also this is for a physics simulation project at university. I’ll make the ball roll but first it should rotate.
Last thing, applyforce is a function to apply a force on the ball with the specified direction(a Vector) and strength, this works very great, the rotation is the part that doesn’t.