티스토리 뷰
#include <cmath>
#include <ctime>
#include <cstdlib>
#include <iostream>
#include <sstream>
#include <string>
#include <GL/glut.h>
using namespace std;
const double pi = 4 * atan(1.0);
const double gravity = 9.8;
const int width = 640;
const int height = 480;
const double velocityMax = 1; //Maxium inital speed
class Ball {
public :
double x, y, vx, vy;
double velocity = 0.0;
double acceleration = 0.1;
Ball(double x, double vx, double y, double vy) {
this->x = x;
this->vx = vx;
this->y = y;
this->vy = vy;
}
// Randomly move to any neighboring pixel (or stay in the same spot)
void step() {
x += vx*acceleration;
y += vy*acceleration;
vx = vx;
vy -= gravity*acceleration;
if (x > width) vx = -abs(vx); // x limit(high)
if (x < 0) vx = abs(vx); // x limit(low)
if (y > height) vy = -abs(vy); // y limit(high)
if (y < 0) vy = abs(vy); // y limit(low)
}
};
Ball *ball;
void create_ball() {
double theta = pi * rand() / double(RAND_MAX);
ball = new Ball(0, velocityMax * cos(theta),
0, velocityMax * sin(theta));
}
void drawText(const string &str, double x, double y) {
glRasterPos2d(x, y);
int len = str.find('\0');
for (int i = 0; i < len; i++)
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, str[i]);
}
// move each ball by one time step dt
void step() {
ball->step();
ball->velocity += ball->acceleration;
}
void animation_step() {
double frames_per_second = 30; // for animation in real time
double start = ball->velocity;
clock_t start_time = clock();
step();
double tau = 1.0 / frames_per_second;
while (ball->velocity - start < tau)
step();
while ((double(clock()) - start_time)/CLOCKS_PER_SEC < tau)
;
glutPostRedisplay();
}
// Glut callback function to update the display
void display() {
glClear(GL_COLOR_BUFFER_BIT);
static GLubyte color_table[6][3] =
{{255, 0, 0}, {0, 255, 0}, {0, 0, 255},
{0, 255, 255}, {255, 0, 255}, {255, 255, 0}}; // Red, Green, Blue, Sky, Purple, Yellow
glColor3ubv(color_table[0]);
//glPointSize(10);
glBegin(GL_TRIANGLE_FAN);
glVertex2d(ball->x, ball->y);
double phi = 2 * pi / 24;
for (int j = 0; j < 25; j++)
glVertex2d(ball->x + 10 * cos(phi*j),
ball->y + 10 * sin(phi*j));
glEnd();
glColor3ub(0, 0, 0);
ostringstream os;
os << "velocity: " << ball->velocity << "x pos: " << ball->x << " y pos " << ball->y << ends;
drawText(os.str(), 12, 24);
os.seekp(0);
glutSwapBuffers();
}
// Glut callback function to reset the viewing transformation
void reshape(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho( 0.0, 640.0, 0.0, 480.0, 1.0, -1.0 );
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
bool running = false; // is the animation running
// Glut mouse callback function
void mouse(int button, int state, int x, int y) {
switch (button) {
case GLUT_LEFT_BUTTON:
if (state == GLUT_DOWN) {
if (running) {
glutIdleFunc(NULL);
running = false;
} else {
glutIdleFunc(animation_step);
running = true;
}
}
}
}
int main(int argc, char *argv[]) {
glutInit(&argc, argv);
create_ball();
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(width, height);
glutInitWindowPosition(100, 100);
glutCreateWindow("Walker");
glClearColor(1.0, 1.0, 1.0, 0.0);
glShadeModel(GL_FLAT);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMouseFunc(mouse);
glutMainLoop();
}