As a way to learn C++ I wanted to make a double pendulum simulation using a graphics framework so I chose Raylib because its the only framework I need. So far I have been able to draw a double pendulum and I am able to modify the angle so that whenever theta is modified it will change the position of the pendulum. However, I cannot animate this whenever I try to update theta1 or theta2 within the main while loop. Before I can actually implement some physics I need to know that I will be able to animate the pendulum based on its separate angles. Only when I set the angle for the first time it will change. I cant re-set the angle anywhere else only initially, I am new to C++.
pendulum.h
#ifndef DOUBLE_PENDULUM_SIM_PENDULUM_H
#define DOUBLE_PENDULUM_SIM_PENDULUM_H
class pendulum {
public:
float pLength{};
float pMass{};
float x{};
float y{};
float pAngle{};
public:
[[nodiscard]] float getX() const ;
[[nodiscard]] float getY() const ;
[[nodiscard]] float getAngle() const ;
void setX(float length, float angle);
void setY(float length, float angle);
void setLength(float length);
void setMass(float mass);
void setAngle(float angle);
pendulum();
pendulum(float length, float mass, float angle) : pLength(length), pMass(mass), pAngle(angle) {}
~pendulum();
};
#endif //DOUBLE_PENDULUM_SIM_PENDULUM_H
pendulum.cpp
#include "includes/pendulum.h"
#include <cmath>
#include <iostream>
#include <raylib.h>
void pendulum::setX(float length, float angle) {
x = length * sin(angle);
}
void pendulum::setY(float length, float angle) {
y = length * cos(angle);
}
float pendulum::getX() const {
return x;
}
float pendulum::getY() const {
return y;
}
void pendulum::setLength(float length) {
pLength = length;
}
void pendulum::setMass(float mass) {
pMass = mass;
}
float pendulum::getAngle() const {
return pAngle;
}
pendulum::~pendulum() {
std::cout << "Pendulum destroyed" << std::endl;
}
void pendulum::setAngle(float angle) {
pAngle = angle * DEG2RAD;
}
//Default constructor
pendulum::pendulum() = default;
main.cpp
#include <iostream>
#include "raylib.h"
#include "includes/pendulum.h"
#include <rlgl.h>
#include <cmath>
void _testPendulum();
pendulum pen1;
pendulum pen2;
int main() {
float theta1 = 0.0f;
float theta2 = 0.0f;
pen1.setMass(20.0f);
pen1.setLength(150.0f);
pen1.setAngle(theta1); //Can only set this once and cant anywhere else, why?
pen1.setX(pen1.pLength,pen1.getAngle());
pen1.setY(pen1.pLength, pen1.getAngle());
std::cout << "X coord: " << pen1.getX() << " Y coord: " << pen1.getY() << std::endl;
pen2.setMass(50.0f);
pen2.setLength(150.0f);
pen2.setAngle(theta2); //Can only set this once and cant anywhere else, why?
pen2.setX( pen2.pLength,pen2.getAngle());
pen2.setY( pen2.pLength,pen2.getAngle());
pen2.x = pen1.getX() + pen2.getX();
pen2.y = pen1.getY() + pen2.getY();
std::cout << "X coord: " << pen2.getX() << " Y coord: " << pen2.getY() << std::endl;
Vector2 origin{0,0};
double screenWidth = 800;
double screenHeight = 800;
float px1 = pen1.getX();
float py1 = pen1.getY();
float px2 = pen2.getX();
float py2 = pen2.getY();
Vector2 rod1{px1,py1};
Vector2 rod2 {px2, py2};
/**--------------------------TEST VARIABLES--------------------------*/
//Pendulum 1 & 2 properties:
float l1 = 150.0f; //Length 1
float l2 = 150.0f; //Length 2
float m1 = 20.0f;
float m2 = 20.0f;
static float angle1 = 0.0f * DEG2RAD;
static float angle2 = 0.0f * DEG2RAD;
//First pendulum x & y
float x1 = l1 * sin(theta1);
float y1 = l1 * cos(theta1);
//Second pendulum x & y
float x2 = x1 + (l2 * sin(theta2));
float y2 = y1 + (l2 * cos(theta2));
/**--------------------------TEST VARIABLES--------------------------*/
InitWindow((int) screenWidth, (int) screenHeight, "Double-Pendulum-Sim");
int state = 0;
int frameCounter = 0;
SetTargetFPS(60);
while (!WindowShouldClose()) {
/**------------------Update------------------*/
if(state == 0) {
frameCounter++;
theta1 = (float) frameCounter;
pen1.setAngle(theta1);
if(frameCounter >= 500) {
frameCounter = 0;
state = 1;
}
} else if(state == 1) {
frameCounter++;
theta2 = (float) frameCounter;
pen2.setAngle(theta2);
if(frameCounter >= 600) {
frameCounter = 0;
state = 2;
}
}
/**---------------------------------Draw-Pendulums---------------------------------- */
BeginDrawing();
ClearBackground(BLACK);
DrawFPS(-350, -200);
rlTranslatef(400,250,0);
DrawLineEx(origin, rod1, 5.0f, RAYWHITE);
DrawCircle(px1,py1,pen1.pMass,RAYWHITE);
DrawLineEx(rod1, rod2, 5.0f, RAYWHITE);
DrawCircle(px2,py2,pen2.pMass,RAYWHITE);
std::cout << "Pendulum 1 X & Y: " << pen1.getX() << " " << pen1.getY() << std::endl;
std::cout << "Pendulum 2 X & Y: " << pen2.getX() << " " << pen2.getY() << std::endl;
EndDrawing();
}
CloseWindow();
return 0;
}
//Test function
void _testPendulum() {
try {
pen1.setMass(20.0f);
pen1.setLength(150.0f);
pen1.setAngle(0.0f);
pen1.setX(pen1.pLength,pen1.getAngle());
pen1.setY(pen1.pLength, pen1.getAngle());
std::cout << "X coord: " << pen1.getX() << " Y coord: " << pen1.getY() << std::endl;
pen2.setMass(50.0f);
pen2.setLength(150.0f);
pen2.setAngle(0.0f);
pen2.setX( pen2.pLength,pen2.getAngle());
pen2.setY( pen2.pLength,pen2.getAngle());
pen2.x = pen1.getX() + pen2.getX();
pen2.y = pen1.getY() + pen2.getY();
std::cout << "X coord: " << pen2.getX() << " Y coord: " << pen2.getY() << std::endl;
} catch (const std::exception & e) {
std::cout << e.what();
}
}