mikrocontroller.net

Forum: PC-Programmierung Ortsvektor auf Kreisbahn extrapolieren


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Fabian D. (fabian_d790)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ich gruesse euch liebe Community.
Leider kann ich nur anhand meiner Ausbildungsinhalte dieses Problem 
nicht bewerkstelligen.

Daher nun die Frage.
Es geht um ein Spiel in welchem Positionen als Ortsvektoren in einem R^3 
angeordnet sind, bzw. Koordinaten.

Der Spieler 1 befindet sich an der Position, bzw. dem Vektor (3/1/4)
Der Spieler schaut auf den Punkt (3/2/1)
Dabei soll der Spieler um diesen Punkt in 20 Grad schritten rotieren auf 
einer Kreisbahn.
Bisher habe ich folgenden Ansatz.
Ich gehe von dem Mittelpunkt der Kreisbahn aus, das ist (3/2/4)
Dann berechne ich durch folgende Beziehung die Koordinaten um 20 Grad 
versetzt.
Y(phi)=Y_m + r*sin(phi)
X(phi)=X_m + r*cos(phi)

Z bleibt konstant bei 4, also sind X und Y zu ermitteln.

Jedoch will ich den Vektor auf welchem sich der Spieler befindet als 
"Anfang" oder Ausgangsposition fuer die Rotation nehmen, also (3/1/4)
Das ist der bisherige Code den ich dazu entwickelt habe.
new Float:playerPos[]={3.93,2.34,4.0};
new Float:playerLookAt[]={3.0,2.0,1.0};
new Float:circleCenter[]={3.0,2.0,4.0};

new moveAngle=20;

forward Float:GetDistance( Float:a1, Float:b1, Float:c1, Float:a2, Float:b2, Float:c2 );


stock Float:GetDistance( Float:a1, Float:b1, Float:c1, Float:a2, Float:b2, Float:c2 )
{
  return  floatsqroot(((a1-a2)*(a1-a2))+((b1-b2)*(b1-b2))+((c1-c2)*(c1-c2)));
}

new Float:r=1.0;

main()
{
  
  new Float:y,Float:x;
  x=circleCenter[0]+r*floatcos(moveAngle,degrees);
  y=circleCenter[1]+r*floatsin(moveAngle,degrees);
  
  
  printf("New pos on 20 degree X:%f Y:%f Z:%f",x,y,playerPos[2]);


}

Leider konnten mir auch meine ehemaligen Berufsschullehrer bei der 
Problematik nicht ansatzweise helfen.

: Bearbeitet durch User
Autor: Rofl-Tier (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was funktioniert denn genau nicht?

Autor: Rofl-Tier (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Müsste circleCenter nicht gleich playerPos sein?

Autor: Rofl-Tier (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach nee, vergiss den letzten Kommentar. Hab es verstanden.

Autor: Fabian D. (fabian_d790)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Problem ist der mathematische Zusammenhang.
Auf der Grafik habe ich mal einen Punkt B eingetragen, der um einen 
bestimmten Winkel rotiert ist, und sich auf der Kreisbahn befindet.
Wie kriege ich diesen Punkt jedoch berechnet, wenn ich bspw eine 
Rotation von 20 Grad wuensche?

Autor: Rofl-Tier (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du setzt im Prinzip Winkel und Radius in die Kreisgleichungen ein und 
bekommst dann den Punkt auf dem Kreis. Musst ihn dann noch um die 
Mittelpunkt Koordinaten verschieben.

Autor: Rofl-Tier (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bin leider gerade unterwegs und nur am Handy. Ich kann dir nachher mal 
ein paar Beispiele vorrechnen wenn ich Zuhause bin.

Autor: Rofl-Tier (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach dein Problem ist dass der Startpunkt eine beliebige Position des 
Spielers sein soll. Bin wohl noch etwas müde. Das wird echt tricky. Ich 
werd nachher mal ein bisschen rumprobieren.

Autor: Peter Petersson (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der erste Fehler den ich in deiner Rechnung sehe, ist dass du einfach 
20° als Winkel benutzt. Du musst aber neben dem Abstand vom Spieler zum 
Mittelpunkt auch noch den Anfangswinkel (nennen wir ihn phi0) berechnen, 
auf dem sich der Spieler gerade befindet. Der neue Winkel ist dann 
phi0+20°.

Autor: DPA (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Normalerweise ist bei Computerprogrammen die Z Achse nach hinten oder 
forne, und die Y oben, nur in mathe macht man das anders, aber egal, ist 
hier irrelevant.

Ich würde das so machen. Der einfachheit halber betrachten wir jetzt nur 
immer (X,Y):
 1) Erstmal den Kreismittelpunkt, oder um was auch immer du drehen 
willst, zum Nullpunkt des Koordinatensystems machen. In anderen worten, 
alle Punkte um Vektor (-3,-2) verschieben. Eigentlich muss man das nur 
mit den Playerkoordinaten machen, aber so ist es einfacher zu 
visualisieren/erklären.
 2) Rotiere die Koordinaten um den nullpunkt. Ich weiss die Formel mit 
sin und cos grad nichtmehr auswendig. Braucht man aber auch nicht, 
einfach eine Rotationsmatrix nehmen. Ich glaub das war: [(cos 20, -sin 
20),(sin 20, cos 20)], die matrix muss man nur einmal berechnen. Aber 
achtung in den meisten libs sind sin und cos in Bogenmass und nicht in 
deg. Um einen Punkt zu Rotieren, einfach mit der Matrix multiplizieren.
 3) Alles zurückverschieben, also um Vektor (3,2) verschieben. fertig.

Jenachdem kann man bei einer Matrix die Translation gleich mit angeben. 
Ich vergesse da aber immer, welche Reiehnfolge das war, und um welchen 
der Punkte das dann dreht...

Autor: Fabian D. (fabian_d790)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Petersson schrieb:
> Der erste Fehler den ich in deiner Rechnung sehe, ist dass du einfach
> 20° als Winkel benutzt. Du musst aber neben dem Abstand vom Spieler zum
> Mittelpunkt auch noch den Anfangswinkel (nennen wir ihn phi0) berechnen,
> auf dem sich der Spieler gerade befindet. Der neue Winkel ist dann
> phi0+20°.

Genau das Problem habe ich, aber wie finde ich den aktuellen Winkel, 
bzw. Anfangswinkel?
Wo kriege ich da meinen Bezug her?

Ich habe versucht das ganze umzukehren, und sozusagen nach cos bzw. sin 
umzuformen.

Das sollen wohl die arcsin bzw. arccos Werte sein.
kA ob das irgendein sinvoller Ansatz ist.

Habe dann fuer X Winkel 1,01 Grad und Y Winkel 168,51 Grad
  xa=floatpower(floatcos((playerPos[0]-circleCenter[0])/r),-1);
  xy=floatpower(floatsin((playerPos[1]-circleCenter[1])/r),-1);
  

: Bearbeitet durch User
Autor: DPA (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
cos^-1(x) steht nicht für (cos(x))^-1 oder 1/cos(x) sondern für die 
umkehrfunktion. Bei anderen werten als -1 ist das in der regel anders...

Autor: Fabian D. (fabian_d790)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
DPA schrieb:
> cos^-1(x) steht nicht für (cos(x))^-1 oder 1/cos(x) sondern für die
> umkehrfunktion. Bei anderen werten als -1 ist das in der regel anders...

Alles klar, habe nun die Funktionen asin und acos genutzt, und folgendes 
als Ergenis.

Angle X:21.565174 Angle Y:19.876867 fuer die Spielerposition
Angle X:40.000003 Angle Y:40.000003 fuer den neu erstellten Punkt. 
(Deismal 40 Grad verschoben)

Prima! Danke euch, habe es nun zum laufen bekommen.
Erst bestimmte ich X und Y Angle der Spielerkoordinate.
Dann addiere ich auf beide Werte einfach meinen gewuenschten Winkel, und 
schon gings!

  new Float:xa,Float:xy;
  xa=acos((playerPos[0]-circleCenter[0])/r);
  xy=asin((playerPos[1]-circleCenter[1])/r);


  new Float:y,Float:x;
  x=circleCenter[0]+r*floatcos(moveAngle+xa,degrees);
  y=circleCenter[1]+r*floatsin(moveAngle+xy,degrees);

: Bearbeitet durch User
Autor: Peter Petersson (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Perfekto 👍

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.