000
08.06.2012, 09:02 Uhr
~Crymes
Gast
|
Hallo, ich hab ein Programm geschrieben, dass 2 Bälle kollidieren lässt. Das funktioniert soweit auch fehlerfrei, nur bewegen sie sich mit der Zeit immer langsamer. Ich denke das Problem liegt in der Funktion kollisionball(), bin mir aber nicht sicher.
Könnt ihr mir bitte helfen?
Hier ist der Code:
C++: |
// 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]; float radius;
}ball1, ball2; void ballinit() { //Klasse initialisieren Ball1 ball1.position[0]=110; ball1.position[1]=110; ball1.geschwindigkeit[0]=31; ball1.geschwindigkeit[1]=6; ball1.radius=100;
//Ball2 ball2.position[0]=500; ball2.position[1]=500; ball2.geschwindigkeit[0]=3; ball2.geschwindigkeit[1]=9; 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 kollisionrand() { //Nicht über Rand hinaus oben/unten if(ball1.position[1] + ball1.geschwindigkeit[1] < ball1.radius) { ball1.position[1] = ball1.radius; } if(ball1.position[1] + ball1.geschwindigkeit[1] > bbreite - ball1.radius) { ball1.position[1] = bbreite - ball1.radius; }
//links rechts if(ball1.position[0] + ball1.geschwindigkeit[0] < ball1.radius) { ball1.position[0] = ball1.radius; }
if(ball1.position[0] + ball1.geschwindigkeit[0] > blänge - ball1.radius) { ball1.position[0] = blänge - ball1.radius; }
//Ball1 //rechts /links kollidieren if( (ball1.position[0] >= (blänge-ball1.radius)) || (ball1.position[0] <= ball1.radius) ) { ball1.geschwindigkeit[0] = ball1.geschwindigkeit[0] * (-1); }
//oben /unten else if( (ball1.position[1] >= (bbreite-ball1.radius)) || (ball1.position[1] <= ball1.radius) ) { ball1.geschwindigkeit[1] = ball1.geschwindigkeit[1] * (-1); }
//Nicht über den Rand hinaus fliegen oben/unten if(ball2.position[1] + ball2.geschwindigkeit[1] < ball2.radius) { ball2.position[1] = ball2.radius; } if(ball2.position[1] + ball2.geschwindigkeit[1] > bbreite - ball2.radius) { ball2.position[1] = bbreite - ball2.radius; }
//links/rechts if(ball2.position[0] + ball2.geschwindigkeit[0] < ball2.radius) { ball2.position[0] = ball2.radius; }
if(ball2.position[0] + ball2.geschwindigkeit[0] > blänge - ball2.radius) { ball2.position[0] = blänge - ball2.radius; }
//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); } } void kollisionball() { //Gewicht der Bälle errechnen float gball1 = 0, gball2 = 0; gball1 = (ball1.radius*ball1.radius) * Pi; gball2 = (ball2.radius*ball2.radius) * Pi;
//Abstand ausrechnen if( sqrt( pow( ball2.position[0]-ball1.position[0], 2) + pow( ball2.position[1]-ball1.position[1], 2) ) <= (ball1.radius+ball2.radius) ) { //Bälle dürfen sich nicht schneiden if(sqrt( pow( ball2.position[0]-ball1.position[0], 2) + pow( ball2.position[1]-ball1.position[1], 2) ) < (ball1.radius+ball2.radius) ) { do { for(int c=0;c<=1;c++) { ball1.position[c] = ball1.position[c] - 0.01 * ball1.geschwindigkeit[c]; ball2.position[c] = ball2.position[c] - 0.01 * ball2.geschwindigkeit[c]; } } while(sqrt( pow( ball2.position[0]-ball1.position[0], 2) + pow( ball2.position[1]-ball1.position[1], 2) ) < (ball1.radius+ball2.radius) ); }
//Linie zwischen den Mittelpunkten (Zentralvektor) float vlinie[2]; vlinie[0] = ball2.position[0] - ball1.position[1]; vlinie[1] = ball2.position[1] - ball1.position[1];
//Linie auf Einheitsvektor nominieren: vlinie / bertag(vlinie) float vliniee[2]; vliniee[0] = vlinie[0]/sqrt(vlinie[0] * vlinie[0] + vlinie[1] * vlinie[1]); vliniee[1] = vlinie[1]/sqrt(vlinie[0] * vlinie[0] + vlinie[1] * vlinie[1]); //Tangentialvektor errechnen: vt = (-vliniee(y), vliniee(x) ) float vtan[2]; vtan[0] = -1 * vliniee[1]; vtan[1] = vliniee[0];
//Geschwindigkeitsvektoren zerlegen (tangential, normal Richtung), es kommen Skalare raus float gnormb1, gnormb2, gtanb1, gtanb2; gnormb1 = (vliniee[0] * ball1.geschwindigkeit[0]) + (vliniee[1] * ball1.geschwindigkeit[1]); gnormb2 = (vliniee[0] * ball2.geschwindigkeit[0]) + (vliniee[1] * ball2.geschwindigkeit[1]); gtanb1 = (vtan[0] * ball1.geschwindigkeit[0]) + (vtan[1] + ball1.geschwindigkeit[1]); gtanb2 = (vtan[0] * ball2.geschwindigkeit[0]) + (vtan[1] + ball2.geschwindigkeit[1]);
//Neue Geschwindigkeit errechnen //tangentiale Geschwindigkeiten verändern sich nicht! //Geschwindigkeitsvektoren nach Kollision //Masse ist Radius! float gnormb1n, gnormb2n; /*gnormb1n = ( (gnormb1*(gball1 - gball2) + ((2*gball2) * gnormb2))) / (gball1 + gball2); gnormb2n = ( (gnormb2*(gball2 - gball1) + ((2*gball1) * gnormb1))) / (gball1 + gball2); */
//Ander Formel /*gnormb1n = (gball1*gnormb1 + (gball2*(2*gnormb2-gnormb1))) / (gball1 + gball2); gnormb2n = (gball2*gnormb2 + (gball1*(2*gnormb1-gnormb2))) / (gball1 + gball2);*/
//Formel ohne Masse gnormb1n = gnormb2; gnormb2n = gnormb1;
//Einheitsvektoren zu normalvektoren konvertieren (normal richtung) float b1nn[2], b2nn[2], b1tn[2], b2tn[2]; b1nn[0] = gnormb1n * vliniee[0]; b1nn[1] = gnormb1n * vliniee[1]; b2nn[0] = gnormb2n * vliniee[0]; b2nn[1] = gnormb2n * vliniee[1]; b1tn[0] = gnormb1n * vtan[0]; b1tn[1] = gnormb1n * vtan[1]; b2tn[0] = gnormb2n * vtan[0]; b2tn[1] = gnormb2n * vtan[1];
//Finale Geschwindigkeiten ausrechnen ball1.geschwindigkeit[0] = b1nn[0] + b1tn[0]; ball1.geschwindigkeit[1] = b1nn[1] + b1tn[1]; ball2.geschwindigkeit[0] = b2nn[0] + b2tn[0]; ball2.geschwindigkeit[1] = b2nn[1] + b2tn[1]; } } void ball(float x, float y, float radius, float rot, float grün, float blau) { glBegin(GL_LINE_LOOP); glColor3d(rot,grün,blau); for(float s=0;s<=360;s++) { glVertex2d( (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,0,0); ball(ball2.position[0],ball2.position[1],ball2.radius,0,0,1);
//Position aktualisieren kollisionrand(); kollisionball(); 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; cout << "Geschwindigkeit Ball1: " << ball1.geschwindigkeit[0] << " " << ball1.geschwindigkeit[1] << endl; cout << "Geschwindigkeit Ball2: " << ball2.geschwindigkeit[0] << " " << ball2.geschwindigkeit[1] << endl;
//Alles anzeigen glutSwapBuffers(); glutPostRedisplay(); } 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); }
|
Danke für eure Hilfe. |