Forum: PC-Programmierung Ortsvektor auf Kreisbahn extrapolieren


von Fabian D. (fabian_d790)


Angehängte Dateien:

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.
1
new Float:playerPos[]={3.93,2.34,4.0};
2
new Float:playerLookAt[]={3.0,2.0,1.0};
3
new Float:circleCenter[]={3.0,2.0,4.0};
4
5
new moveAngle=20;
6
7
forward Float:GetDistance( Float:a1, Float:b1, Float:c1, Float:a2, Float:b2, Float:c2 );
8
9
10
stock Float:GetDistance( Float:a1, Float:b1, Float:c1, Float:a2, Float:b2, Float:c2 )
11
{
12
  return  floatsqroot(((a1-a2)*(a1-a2))+((b1-b2)*(b1-b2))+((c1-c2)*(c1-c2)));
13
}
14
15
new Float:r=1.0;
16
17
main()
18
{
19
  
20
  new Float:y,Float:x;
21
  x=circleCenter[0]+r*floatcos(moveAngle,degrees);
22
  y=circleCenter[1]+r*floatsin(moveAngle,degrees);
23
  
24
  
25
  printf("New pos on 20 degree X:%f Y:%f Z:%f",x,y,playerPos[2]);
26
27
28
}

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

: Bearbeitet durch User
von Rofl-Tier (Gast)


Lesenswert?

Was funktioniert denn genau nicht?

von Rofl-Tier (Gast)


Lesenswert?

Müsste circleCenter nicht gleich playerPos sein?

von Rofl-Tier (Gast)


Lesenswert?

Ach nee, vergiss den letzten Kommentar. Hab es verstanden.

von Fabian D. (fabian_d790)


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?

von Rofl-Tier (Gast)


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.

von Rofl-Tier (Gast)


Lesenswert?

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

von Rofl-Tier (Gast)


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.

von Peter Petersson (Gast)


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°.

von DPA (Gast)


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...

von Fabian D. (fabian_d790)


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
1
  xa=floatpower(floatcos((playerPos[0]-circleCenter[0])/r),-1);
2
  xy=floatpower(floatsin((playerPos[1]-circleCenter[1])/r),-1);

: Bearbeitet durch User
von DPA (Gast)


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...

von Fabian D. (fabian_d790)


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
von Peter Petersson (Gast)


Lesenswert?

Perfekto ?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.