#include #include #include #include #include const int windowWidth = 1200; const int windowHeight = 800; struct Ball { float x, y, z; float vx, vy, vz; float r, g, b; }; // Ustawienia rzutu ukośnego dla każdej kuli (kąt startowy, prędkość początkowa) std::vector balls; void initializeBalls() { for (int i = 0; i < 10; ++i) { float angle = 15 + i * 6; // Kąty między 15 a 75 stopni float speed = 10 + i; // Prędkości początkowe Ball ball = { .x = 0.0f, .y = 0.0f, .z = 0.0f, .vx = static_cast(speed * cos(angle * M_PI / 180.0f)), .vy = static_cast(speed * sin(angle * M_PI / 180.0f)), .vz = 0.0f, .r = static_cast(rand()) / RAND_MAX, .g = static_cast(rand()) / RAND_MAX, .b = static_cast(rand()) / RAND_MAX }; balls.push_back(ball); } } // Funkcja do integracji Rungego-Kutty void rungeKuttaStep(Ball &ball, float dt) { float k1vx = -0.1f * ball.vx; float k1vy = -9.8f - 0.1f * ball.vy; float k2vx = -0.1f * (ball.vx + 0.5f * dt * k1vx); float k2vy = -9.8f - 0.1f * (ball.vy + 0.5f * dt * k1vy); float k3vx = -0.1f * (ball.vx + 0.5f * dt * k2vx); float k3vy = -9.8f - 0.1f * (ball.vy + 0.5f * dt * k2vy); float k4vx = -0.1f * (ball.vx + dt * k3vx); float k4vy = -9.8f - 0.1f * (ball.vy + dt * k3vy); ball.vx += (dt / 6.0f) * (k1vx + 2.0f * k2vx + 2.0f * k3vx + k4vx); ball.vy += (dt / 6.0f) * (k1vy + 2.0f * k2vy + 2.0f * k3vy + k4vy); ball.x += ball.vx * dt; ball.y += ball.vy * dt; } void drawSphere(float radius, int slices, int stacks) { for (int i = 0; i <= stacks; ++i) { float V = i / (float) stacks; float phi = V * M_PI; glBegin(GL_TRIANGLE_STRIP); for (int j = 0; j <= slices; ++j) { float U = j / (float) slices; float theta = U * (M_PI * 2); float x = cosf(theta) * sinf(phi); float y = cosf(phi); float z = sinf(theta) * sinf(phi); glVertex3f(x * radius, y * radius, z * radius); } glEnd(); } } void display() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(30, 0, 40, 15, 0, 0, 0, 1, 0); for (const auto &ball : balls) { glPushMatrix(); glTranslatef(ball.x, ball.y, ball.z); glColor3f(ball.r, ball.g, ball.b); drawSphere(0.5, 20, 20); // Zastąpienie glutSolidSphere funkcją drawSphere glPopMatrix(); } glfwSwapBuffers(glfwGetCurrentContext()); } void update() { float dt = 0.01f; for (auto &ball : balls) { rungeKuttaStep(ball, dt); // Diagnostyka aktualizacji pozycji std::cout << "Ball position: (" << ball.x << ", " << ball.y << ", " << ball.z << ")\n"; } } void setupOpenGL() { glEnable(GL_DEPTH_TEST); glClearColor(0.1f, 0.1f, 0.1f, 1.0f); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0, (double)windowWidth / (double)windowHeight, 0.1, 100.0); } void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods) { if (action == GLFW_PRESS) { switch (key) { case GLFW_KEY_ESCAPE: glfwSetWindowShouldClose(window, GLFW_TRUE); break; // Dodaj inne przypadki obsługi klawiszy tutaj } } } int main() { if (!glfwInit()) { std::cerr << "Failed to initialize GLFW" << std::endl; return -1; } GLFWwindow* window = glfwCreateWindow(windowWidth, windowHeight, "Animacja 10 kul - Rzut ukośny", nullptr, nullptr); if (!window) { std::cerr << "Failed to create GLFW window" << std::endl; glfwTerminate(); return -1; } glfwMakeContextCurrent(window); glfwSetKeyCallback(window, keyCallback); // Rejestracja callbacku klawiatury glewExperimental = GL_TRUE; if (glewInit() != GLEW_OK) { std::cerr << "Failed to initialize GLEW" << std::endl; return -1; } initializeBalls(); setupOpenGL(); while (!glfwWindowShouldClose(window)) { display(); update(); glfwPollEvents(); } glfwDestroyWindow(window); glfwTerminate(); return 0; }