Registriert: Sa Dez 30, 2006 17:01 Beiträge: 22 Wohnort: NRW/Fröndenberg
Hi,
Ich bin vor kurzem über einen Algorithmus gestoßen, der den Weg eines Objektes so ändert, dass es nicht mit den anderen Objekten in der Umgebung zusammenstößt. Dazu wurden im Kern einfach die gesamten Vektoren der Objekte addiert um so den neuen Zielvektor zu berechnen. Ich hab mir dann ein wenig Beispielcode gesucht und erkannte dabei, dass die meisten Objekte auf irgendwelchen Vektorklassen basierten.
Bisher habe ich meine Objekte immer so aufgebaut (zur Vereinfachung erstmal 2D), dass ich ihnen die Eigenschaft XPos/YPos/Speed/Winkel gegeben habe und daraus dann immer die neuen Position berechnet habe. Im Prinzip gleicht sich das ja zum Teil.
Nun meine Frage: Ist es sinnvoller mit Vektoren zu rechnen oder ist das schon gänig so wie ich das Thema angegangen bin?
Wenn Vektoren besser sind: Wie implementiere ich die Geschickt? Ich wollte eigentlich keine vorgefertigte Vektorklasse nehmen,sondern das wenn selber programmieren. Aber dafür habe ich gerade irgendwie keinen Ansatz.
Danke!
P.S. Hab mich noch nicht viel mit Vektoren beschäftigt, hab heute morgen den Wikipedia und ein paar andere Artikel im Internet durchgearbeitet, aber in der Schule hatte ich das Thema z.B. noch nicht.
Registriert: Sa Aug 18, 2007 18:47 Beiträge: 694 Wohnort: Köln
Programmiersprache: Java
Das was du mit XPos und YPos gemacht hast ist (wenn mans nicht so genau nimmt) eigentlich ein Vektor, zwar nur ein 2-dimensionaler, aber immerhin ein Vektor.
z.b.
Code:
type
TVector2f : record
x, y : single;
end;
wobei Vector.X deinem XPos und Vector.Y deinem YPos entspricht.
dreidimensional dann etwa so:
Code:
type
TVector3f : record
x, y, z : single;
end;
und mal ein Beipielobjekt:
Code:
type
TObjectRec = record
Position,
Speed,
Rotation : TVector3f;
end;
Zusätzlich brauchst du noch ein paar Funktionen um mit den Vektoren zu rechnen. Addieren, subtrahieren, etc... Findest du hier
_________________ Es werde Licht. glEnable(GL_LIGHTING); Und es ward Licht.
Zitat aus einem Java Buch: "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off"
Registriert: Sa Dez 30, 2006 17:01 Beiträge: 22 Wohnort: NRW/Fröndenberg
Ja sowas dachte ich mir auch - ich habe ja eigentlich schon einen Vektor umgesetzt. Nun ist die Addition etc. ja auch nicht sonderlich schwer. Nur was ich komisch, bzw. fraglich finde ist die Tatsache, dass in den meisten Beispielquellcodes der Winkel nicht zum Tragen kommt und die Geschwindigkeit ebenfalls als Vektor aufgefasst wird.
Ich brauche in meinem Programm keinen 2. Vektor für die Geschwindigkeit, da sich die nächste Position ja eindeutig mit Winkelfunktionen (sind/cos) aus dem gegebenen Winkel und der Geschwindigkeit berechnen lässt.
Das bringt mich halt zum dem Problem, dass der Algo. nicht mehr richtig funktioniert. Habe ich da nun was falsch verstanden oder den Algo. einfach falsch implementiert?
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Du hast bei 2D im prinzip das Ergebnis deiner sin/cos operationen im Vektor gespeichert (meist normalisiert). Wenn du dann die neue Position berechnest, multiplizierst du den Richtungsvektor mit der Geschwindigkeit (verlängerst ihn also) und addierst das auf den Positionsvektor.
Richtungsänderungen führst du durch, indem du den Vektor drehst, z.B. mit Sin/Cos oder einer Matrix (die aber letzendlich auch mit sinus und cosinus gebildet wird).
Gruß Lord Horazont
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Registriert: Sa Dez 30, 2006 17:01 Beiträge: 22 Wohnort: NRW/Fröndenberg
Das ist doch eigentlich das, was ich die ganze Zeit über mache oder irre ich jetzt total? Ich berechne ja auch die neue Position mit dem Winkel und der Geschwindigkeit und addiere diese dann auf meine derzeitige
Registriert: Di Okt 03, 2006 14:07 Beiträge: 1277 Wohnort: Wien
Zitat:
Das ist doch eigentlich das, was ich die ganze Zeit über mache oder irre ich jetzt total?
JA (also, ich meine Du irrst Dich nicht). Grade bei der Vektorrechnung ist Mathematik und der übliche "gesunde Menschenverstand" nicht weit voneinander weg. Leider ist das nicht immer so
Registriert: Sa Aug 18, 2007 18:47 Beiträge: 694 Wohnort: Köln
Programmiersprache: Java
Ich denke schon. Nur dass du für die Komponenten der Koordinaten einzelne Variablen hast.
Prinzipiell macht z.b. mein Camera Objekt nix anderes...
Aus Tasteneingaben Bewegungsvektor (z.b. (0, 0, -1) entlang Z-Achse/vorwärts ) bilden.
Diesen Vektor um Winkel entsprechend der Mausposition drehen.
Vektor mit Zeit pro Frame multiplizieren.
Vektor mit Geschwindigkeit multiplizieren.
Vektor auf Position addieren.
_________________ Es werde Licht. glEnable(GL_LIGHTING); Und es ward Licht.
Zitat aus einem Java Buch: "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off"
Registriert: Sa Dez 30, 2006 17:01 Beiträge: 22 Wohnort: NRW/Fröndenberg
Joa, wobei das bringt mich zu einem anderen Problem. Gehen wir davon aus, alles sei korrekt implementiert, dann habe ich ein Problem in einem anderen Algo. Ich bin gerade dabei eine eigene Version von Boids schreiben. Hier gibts den Pseudocode für das Programm: http://www.vergenet.net/~conrad/boids/pseudocode.html Meine Version der drei Regeln schaut nun so aus(in java)
Code:
//otherBoids ist ein array, welches alle Boids enthält
private double[] calcSeperation()
{
double pos[] = {0,0};
for (int i = 0; i < otherBoids.length; i++)
{
if (otherBoids[i] != null)
{
if (this == otherBoids[i]) continue;
// schauen welche Boids im Bereich sind
if (calcDistance(otherBoids[i]) < getRadius())
{
pos[0] = pos[0] + otherBoids[i].calcNextXPos(); //calcNextPos berechnet die nächste Position des Boid
pos[1] = pos[1] + otherBoids[i].calcNextYPos();
}
}
}
pos[0] = pos[0]*SEPERATION; //Konstante für die Gewichtung
pos[1] = pos[1]*SEPERATION;
return pos;
}
private double[] calcCohesion()
{
double pos[] = {0,0};
int boidCnt = 0;
for (int i = 0; i < otherBoids.length; i++)
{
if (otherBoids[i] != null)
{
if (this == otherBoids[i]) continue;
if (calcDistance(otherBoids[i]) < getRadius())
{
pos[0] = pos[0] + otherBoids[i].calcNextXPos();
pos[1] = pos[1] + otherBoids[i].calcNextYPos();
boidCnt++;
}
}
}
if (boidCnt != 0)pos[0] = (pos[0]*COHESION)/boidCnt;
if (boidCnt != 0)pos[1] = (pos[1]*COHESION)/boidCnt;
return pos;
}
private double calcAligment()
{
double speed = 0;
int boidCnt = 0;
for (int i = 0; i < otherBoids.length; i++)
{
if (otherBoids[i] != null)
{
if (this == otherBoids[i]) continue;
if (calcDistance(otherBoids[i]) > getRadius())
{
speed = speed + otherBoids[i].getSpeed();
boidCnt++;
}
}
}
if (boidCnt == 0) speed = getSpeed();
else speed = speed/boidCnt;
return speed;
}
private void boidRules()
{
double XPos = 0;
double YPos = 0;
double pos[] = {0,0};
pos = calcCohesion();
XPos = XPos + pos[0];
YPos = YPos + pos[1];
pos = calcSeperation();
XPos = XPos + pos[0];
YPos = YPos + pos[1];
setSpeed(calcAligment());
if (XPos != 0 || YPos != 0) setAngle(Math.toDegrees((Math.atan(Math.abs(YPos - getYPos())/Math.abs(XPos - getXPos()))))); //setzt den Winkel mit tan^-1
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
1. Nur eine Frage pro Thread bitte, der Übersichtlichkeit halber.
2. Andererseits kann man dir nichts vorwerfen. Wo ist deine Frage?
Gruß Lord Horazont
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Mitglieder in diesem Forum: 0 Mitglieder und 7 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.