Zadanie 1 finish pendulum issues
This commit is contained in:
parent
98ac748dbe
commit
9cda311475
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
@ -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;
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user