Zadanie 1 finish pendulum issues

This commit is contained in:
Władysław Kuczerenko 2024-06-29 19:10:36 +02:00
parent 98ac748dbe
commit 9cda311475
3 changed files with 115 additions and 83 deletions

View File

@ -5,16 +5,34 @@
#include <vector> #include <vector>
#include "shader.h" #include "shader.h"
// Konstante // Constants
const float g = 9.81f; // przyspieszenie ziemskie const float g = 9.81f; // Gravitational acceleration
const float r = 0.6f; // długość nici const float r = 0.6f; // Length of the string
const float dt = 0.01f; // krok czasowy const float initialDt = 0.01f; // Initial time step
// Zmienne globalne const float initTheta = 0.785f; // Initial angle
float theta = 0.5f; // początkowy kąt const float initOmega = 2.0f; // Initial angular velocity
float omega = 0.0f; // początkowa prędkość kątowa const float initPrevTheta = initTheta - initialDt * initOmega; // Initial previous angle
GLuint VBO, VAO, EBO, shaderProgram;
float dt = initialDt;
float currentT = 0.0f;
// Pendulum state structure
struct Pendulum {
float theta; // Angle
float omega; // Angular velocity
float prev_theta; // Previous angle (for Verlet method)
};
// Pendulums
Pendulum pendulums[3] = {
{initTheta, initOmega, initPrevTheta}, // Pendulum 1 (Euler)
{initTheta, initOmega, initPrevTheta}, // Pendulum 2 (Verlet)
{initTheta, initOmega, initPrevTheta}, // Pendulum 3 (Runge-Kutta)
};
GLuint VBO, VAO, shaderProgram;
void compileShaders(){ void compileShaders(){
Shader shader("pendulum_vs.glsl", "pendulum_fs.glsl"); Shader shader("pendulum_vs.glsl", "pendulum_fs.glsl");
@ -32,12 +50,16 @@ void initOpenGL()
glBindVertexArray(VAO); glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO); glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 4, nullptr, GL_DYNAMIC_DRAW); glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 40, nullptr, GL_DYNAMIC_DRAW); // 4 pendulums * 2 vertices * (2 positions + 3 colors)
// Pozycja // Position attribute
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
// Color attribute
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(2 * sizeof(float)));
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0); glBindVertexArray(0);
} }
@ -46,64 +68,82 @@ float f(float theta){
return -(g / r) * sin(theta); return -(g / r) * sin(theta);
} }
// Metoda Eulera // Euler method
void updateEuler() void updateEuler(Pendulum& p)
{ {
float alpha = f(theta); // przyspieszenie kątowe p.theta = p.theta + dt * p.omega;
omega += alpha * dt; // aktualizacja prędkości kątowej p.omega = p.omega + f(p.theta) * dt;
theta += omega * dt; // aktualizacja kąta
} }
// Metoda Verleta // Verlet method
void updateVerlet() void updateVerlet(Pendulum& p)
{ {
static float prev_theta = theta; float new_theta = 2 * p.theta - p.prev_theta + f(p.theta) * dt * dt;
float alpha = f(theta); // przyspieszenie kątowe float old_theta = p.theta;
float new_theta = 2 * theta - prev_theta + alpha * dt * dt; // aktualizacja kąta p.theta = new_theta;
prev_theta = theta; p.prev_theta = old_theta;
theta = new_theta;
// Aktualizacja omega
p.omega = (p.theta - p.prev_theta) / (2 * dt);
} }
// Metoda Rungego-Kutty rzędu 4 // Runge-Kutta 4th order method
void updateRungeKutta() void updateRungeKutta(Pendulum& p)
{ {
float k1_theta = omega; float k1_theta = p.omega;
float k1_omega = f(theta); float k1_omega = f(p.theta);
float k2_theta = omega + 0.5f * dt * k1_omega; float k2_theta = p.omega + 0.5f * dt * k1_omega;
float k2_omega = f(theta + 0.5f * dt * k1_theta); float k2_omega = f(p.theta + 0.5f * dt * k1_theta);
float k3_theta = omega + 0.5f * dt * k2_omega; float k3_theta = p.omega + 0.5f * dt * k2_omega;
float k3_omega = f(theta + 0.5f * dt * k2_theta); float k3_omega = f(p.theta + 0.5f * dt * k2_theta);
float k4_theta = omega + dt * k3_omega; float k4_theta = p.omega + dt * k3_omega;
float k4_omega = f(theta + dt * k3_theta); float k4_omega = f(p.theta + dt * k3_theta);
theta += (dt / 6.0f) * (k1_theta + 2.0f * k2_theta + 2.0f * k3_theta + k4_theta); p.theta += (dt / 6.0f) * (k1_theta + 2.0f * k2_theta + 2.0f * k3_theta + k4_theta);
omega += (dt / 6.0f) * (k1_omega + 2.0f * k2_omega + 2.0f * k3_omega + k4_omega); p.omega += (dt / 6.0f) * (k1_omega + 2.0f * k2_omega + 2.0f * k3_omega + k4_omega);
} }
void drawPendulum() void drawPendulums()
{ {
float x = r * sin(theta);
float y = -r * cos(theta);
float vertices[] = {
0.0f, 0.0f, // Punkt zaczepienia
x, y // Punkt masy
};
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram); glUseProgram(shaderProgram);
glBindVertexArray(VAO); glBindVertexArray(VAO);
glDrawArrays(GL_LINES, 0, 2); std::vector<std::vector<float>> colors = {
glDrawArrays(GL_POINTS, 1, 1); {1.0f, 0.0f, 0.0f}, // EULER
{0.0f, 1.0f, 0.0f}, // VERLET
{0.0f, 0.0f, 1.0f}, // RK
{1.0f, 1.0f, 0.0f} // SIMPLE
};
std::vector<float> vertices;
for (int i = 0; i < 3; ++i) {
float x = r * sin(pendulums[i].theta);
float y = -r * cos(pendulums[i].theta);
// Append vertices for the current pendulum
vertices.insert(vertices.end(), {
0.0f, 0.0f, colors[i][0], colors[i][1], colors[i][2], // Attachment point
x, y, colors[i][0], colors[i][1], colors[i][2] // Mass point
});
// Debugging output for each pendulum's vertices
// std::cout << "Pendulum " << i + 1 << ": (" << x << ", " << y << "), Color: ("
// << colors[i][0] << ", " << colors[i][1] << ", " << colors[i][2] << ")" << std::endl;
}
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float) * vertices.size(), vertices.data());
for (int i = 0; i < 3; ++i) {
glDrawArrays(GL_LINES, i * 2, 2);
glDrawArrays(GL_POINTS, i * 2 + 1, 1);
}
glBindVertexArray(0); glBindVertexArray(0);
} }
@ -112,7 +152,7 @@ int main()
{ {
if (!glfwInit()) if (!glfwInit())
{ {
std::cerr << "Nie można zainicjalizować GLFW" << std::endl; std::cerr << "Failed to initialize GLFW" << std::endl;
return -1; return -1;
} }
@ -121,12 +161,10 @@ int main()
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(800, 600, "Mathematical Pendulums", NULL, NULL);
GLFWwindow* window = glfwCreateWindow(800, 600, "Wahadło Matematyczne", NULL, NULL);
if (!window) if (!window)
{ {
std::cerr << "Nie można utworzyć okna GLFW" << std::endl; std::cerr << "Failed to create GLFW window" << std::endl;
glfwTerminate(); glfwTerminate();
return -1; return -1;
} }
@ -135,7 +173,7 @@ int main()
glewExperimental = GL_TRUE; glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK) if (glewInit() != GLEW_OK)
{ {
std::cerr << "Nie można zainicjalizować GLEW" << std::endl; std::cerr << "Failed to initialize GLEW" << std::endl;
return -1; return -1;
} }
@ -144,37 +182,24 @@ int main()
glOrtho(-2, 2, -2, 2, -1, 1); glOrtho(-2, 2, -2, 2, -1, 1);
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glPointSize(10.0f); glPointSize(35.0f);
initOpenGL(); initOpenGL();
int method = 1; // Domyślnie metoda Eulera
std::cout << "Wybierz metodę: (1) Euler, (2) Verlet, (3) Runge-Kutta: ";
std::cin >> method;
while (!glfwWindowShouldClose(window)) while (!glfwWindowShouldClose(window))
{ {
switch (method) updateEuler(pendulums[0]);
{ updateVerlet(pendulums[1]);
case 1: updateRungeKutta(pendulums[2]);
updateEuler();
break;
case 2:
updateVerlet();
break;
case 3:
updateRungeKutta();
break;
default:
updateEuler();
break;
}
drawPendulum(); drawPendulums();
glfwSwapBuffers(window); glfwSwapBuffers(window);
glfwPollEvents(); glfwPollEvents();
currentT += dt;
} }
glDeleteVertexArrays(1, &VAO); glDeleteVertexArrays(1, &VAO);

View File

@ -1,6 +1,8 @@
#version 330 core #version 330 core
out vec4 FragColor; in vec3 fragColor;
out vec4 color;
void main() void main()
{ {
FragColor = vec4(1.0, 1.0, 1.0, 1.0); color = vec4(fragColor, 1.0);
} }

View File

@ -1,6 +1,11 @@
#version 330 core #version 330 core
layout(location = 0) in vec2 aPos; layout(location = 0) in vec2 position;
layout(location = 1) in vec3 color;
out vec3 fragColor;
void main() void main()
{ {
gl_Position = vec4(aPos, 0.0, 1.0); gl_Position = vec4(position, 0.0, 1.0);
fragColor = color;
} }