// Ball Simulation.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung.
//
#include "stdafx.h"
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <Windows.h>
#include <GL/glew.h>
#include <GL/freeglut.h>
#define Pi 3,14159265358979323846
using namespace std;
//Bildschirmauflösung ermitteln
unsigned int blänge = GetSystemMetrics(SM_CXSCREEN), bbreite = GetSystemMetrics(SM_CYSCREEN);
struct kugel
{
float position[2];
float geschwindigkeit[2];
unsigned int radius;
}ball1, ball2;
void ballinit()
{ //Klasse initialisieren Ball1
ball1.position[0]=110;
ball1.position[1]=110;
ball1.geschwindigkeit[0]=0;
ball1.geschwindigkeit[1]=5;
ball1.radius=50;
//Ball2
ball2.position[0]=500;
ball2.position[1]=500;
ball2.geschwindigkeit[0]=10;
ball2.geschwindigkeit[1]=0;
ball2.radius=100;
};
void ballupdate()
{
for(int stelle = 0; stelle<=1; stelle++)
{
ball1.position[stelle] = ball1.position[stelle] + ball1.geschwindigkeit[stelle];
ball2.position[stelle] = ball2.position[stelle] + ball2.geschwindigkeit[stelle];
}
}
void kollision()
{
//Kollision Bildschirmrand
//Ball1
//rechts /links kollidieren
if( (ball1.position[0] >= (blänge-ball1.radius)) || (ball1.position[0] <= ball1.radius) )
{
ball1.geschwindigkeit[0] = ball1.geschwindigkeit[0] * (-1);
//Debug
cout << "****************************************" << endl << "***" << endl << endl << endl << "***********" << endl;
}
//oben /unten
else if( (ball1.position[1] >= (bbreite-ball1.radius)) || (ball1.position[1] <= ball1.radius) )
{
ball1.geschwindigkeit[1] = ball1.geschwindigkeit[1] * (-1);
}
//Ball2
//rechts /links
if( (ball2.position[0] >= (blänge-ball2.radius)) || (ball2.position[0] <= ball2.radius) )
{
ball2.geschwindigkeit[0] = ball2.geschwindigkeit[0] * (-1);
}
//oben /unten
else if( (ball2.position[1] >= (bbreite-ball2.radius)) || (ball2.position[1] <= ball2.radius) )
{
ball2.geschwindigkeit[1] = ball2.geschwindigkeit[1] * (-1);
}
//Kollision untereinander /Abstand ausrechnen
if( sqrt( pow( ball2.position[0]-ball1.position[0], 2) + pow( ball2.position[1]-ball2.position[1], 2) ) <= (ball1.radius+ball2.radius) )
{
//atan((x1-x2)/(y2-y1))
//Kollisionsgerade
float gerade=0;
gerade = atan( (ball1.geschwindigkeit[0]-ball2.geschwindigkeit[0])/(ball2.geschwindigkeit[1]-ball1.geschwindigkeit[1]) );
//Spiegelungsmatrix
//vx' = vx cos(2*gerade) + vy sin(2*gerade)
//vy' = vx sin(2*gerade) - vy cos(2*gerade)
//Vektoren spiegeln /x
ball1.geschwindigkeit[0] = ball1.geschwindigkeit[0]*cos(2*gerade) + ball1.geschwindigkeit[0]*sin(2*gerade);
ball2.geschwindigkeit[0] = ball2.geschwindigkeit[0]*cos(2*gerade) + ball2.geschwindigkeit[0]*sin(2*gerade);
//y
ball1.geschwindigkeit[1] = ball1.geschwindigkeit[1]*sin(2*gerade) - ball1.geschwindigkeit[1]*cos(2*gerade);
ball2.geschwindigkeit[1] = ball2.geschwindigkeit[1]*sin(2*gerade) - ball2.geschwindigkeit[1]*cos(2*gerade);
}
};
void ball(float x, float y, int radius, float rot, float grün, float blau)
{
glBegin(GL_LINE_LOOP);
glColor3d(rot,grün,blau);
for(float s=0;s<=360;s++)
{
glVertex2f( (x + (radius*cos(s*(Pi/180)))), (y + (radius*sin(s*(Pi/180)))) );
}
glEnd();
}
void fenster()
{
//Glut aufrufen und initialisieren
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(0,0);
glutInitWindowSize(blänge, bbreite);
glutCreateWindow("Ball Simulation");
//Farbe fürs löschen festlegen
glClearColor(0,0,0,0);
}
void zeichnen()
{
//Bildschirm bereinigen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
//Bälle zeichnen
ball(ball1.position[0],ball1.position[1],ball1.radius,1,1,1);
ball(ball2.position[0],ball2.position[1],ball2.radius,0,0,1);
//Alles anzeigen
glutSwapBuffers();
//Position aktualisieren
ballupdate();
//Debug in Konsole
//Bildschirmgröße
cout << blänge << bbreite << endl;
//Position der Bälle
cout << "Ball1: (" << ball1.position[0] << ", " << ball1.position[1] << ")" << endl;
cout << "Ball2: (" << ball2.position[0] << ", " << ball2.position[1] << ")" << endl;
}
void änderung(int länge, int breite)
{
double verhältnis;
//Nicht durch 0 teilen
if(breite == 0)
{
breite = 1;
}
verhältnis = 1.0*länge/breite;
//Projektionsmodus
glMatrixMode(GL_PROJECTION);
//Reset
glLoadIdentity();
//Sichtfeld fürs ganze Fenstere
glViewport(0,0,länge,breite);
//Korrekte Perspektive
gluPerspective(0,verhältnis,1,100);
//Zeichenbereich an Bildschirm anpassen
glOrtho(0,blänge,0,bbreite,0,1);
//Wieder Szene anzeigen
glMatrixMode(GL_MODELVIEW);
}
int _tmain(int argc, char *argv[])
{
//Bälle initialisieren
ballinit();
//Glut aufrufen
glutInit(&argc, argv);
//Fenster zeichnen
fenster();
//Renderfunktion festlegen
glutDisplayFunc(zeichnen);
//Fenster darf verändert werden
glutReshapeFunc(änderung);
//immer auf neuen Event warten;
glutMainLoop();
return(0);
}