Vektoren- und Winkelberechnung

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
mayx
User
Beiträge: 71
Registriert: Sonntag 3. Mai 2009, 02:51

Hallo,

ich wollte eine Vektoren- und Winkelberechnung machen, um die Eingabe
eines stufenlosen Joystick schöner zu gestalten. Mein Objekt bewegt sich
derzeit mit den gleichen x- und y-Werten wie der Joystick. Die Strecke, die
das Objekt sich bewegt, ist dann aber leider unterschiedlich lang.
- nur Rechts => x = 5
- Rechts und Oben => x = 5 und y= 5

Ich habe es folgendermassen versucht:
- Ich habe einen festen Vektor1 der gerade auf X liegt
- diesen Vergleiche ich mit Vektor2 um den Winkel zwischen beiden heraus zu bekommen (alpha) (Skalarprodukt)
- dann nehme ich den Winkel und schau wie lang einen Einheit nach x und y ist
- nun multipliziere ich den wert des Joysticksausschlages mit der Einheit


Code: Alles auswählen

#        |
#        |
#-------------------x
#        |
#        | y

# Winkel zwischen zwei Vektoren:
# Vektor 1 = 10 0   -------------
x1 = 10 
y1 = 0   

print ' '
print 'x 5 y 5 ---'

# Vektor 2 = User Eingabe = x 5  y 5
x2 = 5   
y2 = 5

import math

if (math.sqrt(x1*x1+y1*y1) * math.sqrt(x2*x2+y2*y2)) == 0:
    x = 0
    y = 0
else:
    cosAlpha = (x1*x2 + y1*y2) / (math.sqrt(x1*x1+y1*y1) * math.sqrt(x2*x2+y2*y2))
    print 'cosAlpha'
    print cosAlpha

    alpha = math.cos(cosAlpha)
    print 'alpha'
    print alpha

    x = math.cos(alpha) * x2 
    y = math.sin(alpha) * y2

print 'x = cos von alpha und y = sin von alpha'
print x
print y
Ergebnisse:
x 5 y 5
cosAlpha
0.707106781187
alpha
0.760244597076
x = cos von alpha und y = sin von alpha
3.62333740445
3.44549358635

hmm x und y sollten eigentlich gleich sein.

x 10 y 0
cosAlpha
1.0
alpha
0.540302305868
x = cos von alpha und y = sin von alpha
8.57553215846
0.0

hmm x sollte 10 sein.


Kann mir jemand n tipp geben?

- Ich denke es liegt am cos von Alpha, wenn der 1 ist sollte Alpha = 0.9999 sein.
-> alpha = math.cos(math.radians(cosAlpha)) ;) wieder in Grad gedacht

aber leider immer noch nicht richtig...
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

mayx hat geschrieben:- Ich denke es liegt am cos von Alpha, wenn der 1 ist sollte Alpha = 0.9999 sein.
Nein, cos(n*2pi) = 1.

Ich glaube dein Problem liegt bei

Code: Alles auswählen

alpha = math.cos(cosAlpha)
Der Kosinus vom Kosinus von alpha ist nicht alpha. Versuchs mal mit acos(der Umkehrfunktion von cos mit: x = acos(cosx)) ).
mayx
User
Beiträge: 71
Registriert: Sonntag 3. Mai 2009, 02:51

ah, ja super acos bzw. asin!

hab es noch weiter vereinfacht.
Jetzt rechne ich erstmal nur den Winkel des Vektors aus:

Code: Alles auswählen

import math

x = 5  # a
y = 0  # b

cqu = x*x + y*y
print cqu
c = math.sqrt(cqu)
print c
sinAlpha = x/c
print sinAlpha
alpha = math.asin(sinAlpha)
print math.degrees(alpha)
Ergebnis:
cQuadrat = 25
c = 5.0
sinAlpha = 1.0
alpha = 90.0
mayx
User
Beiträge: 71
Registriert: Sonntag 3. Mai 2009, 02:51

und hier nun die Lösung:
- erst anhand von x und y den Winkel ausrechnen
- die Strecke c auf den gewünschten Radius setzten
- zum Schluß x und y erneut mit c und winkel ausrechnen

Code: Alles auswählen

import math

x = 5  # a
y = 5  # b

cqu = x*x + y*y
print 'cqu'
print cqu
c = math.sqrt(cqu)
print 'c'
print c
sinAlpha = x/c
print 'sinAlpha'
print sinAlpha
alpha = math.asin(sinAlpha)
print 'alpha%f'%alpha
print math.degrees(alpha)

# c neusetzen // c = Radius
c = 5

print '----xy'

x = math.sin(alpha) * c
yqu = c*c - x*x
y = math.sqrt(yqu)

print x
print y
Ergebnis:
cqu 50
c 7.07106781187
sinAlpha 0.707106781187
alpha 0.785398
alphadegree 45.0
----xy
3.53553390593
3.53553390593



Danke Darii
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

So richtig schlau geworden bin ich aus deinen ganzen Ausführungen nicht; vor allem habe ich nicht so recht verstanden, was du *eigentlich* erreichen willst. Wenn es dir nur um die neuen x-/y-Werte geht, dann sollte das hier genügen:

Code: Alles auswählen

>>> x, y, r = 5, 5, 5   # alter x- und y-Wert, Zielradius
>>> q = r/(x*x+y*y)**.5
>>> print q*x, q*y
3.53553390593 3.53553390593
mayx
User
Beiträge: 71
Registriert: Sonntag 3. Mai 2009, 02:51

wow, in zwei Zeilen!

wie ich anfangs beschrieb hab ich eine Eingabe vom Joystick, die stufenlos ist.
Mein Objekt bewegt sich derzeit mit den gleichen x- und y-Werten wie der Joystick. Die Strecke,
die das Objekt sich dann bewegt, ist aber leider unterschiedlich lang oder anders ausgedrückt das Objekt
wird schneller. Für eine gleichmäßige Bewegung in alle Richtungen müssen x und y angepasst werden.


Ich hab jetzt noch die Stufenlosigkeit ;) eingebaut, sprich der Radius passt sich an, jenachdem wie stark x und y sind.

Code: Alles auswählen

print ' ' 
print '...2.2...'

x = 2  # a
y = 2  # b

cqu = x*x + y*y
print 'cqu'
print cqu
c = math.sqrt(cqu)
print 'c'
print c
sinAlpha = x/c
print 'sinAlpha'
print sinAlpha
alpha = math.asin(sinAlpha)
print 'alpha%f'%alpha
print math.degrees(alpha)

# c neusetzen // c = Radius
if not x == 0 and not y == 0:
    cqu = x*y
    c = math.sqrt(cqu)

    print '----xy'

    x = math.sin(alpha) * c
    yqu = c*c - x*x
    y = math.sqrt(yqu)

print x
print y

Wie ich das in deine zwei zeilen integriere weiß ich nicht. leider verstehe ich sie auch, nicht ganz. **.5 ist die Wurzel, oder? statt math.sqrt().
Vielleicht magst du mir noch eine Zeile dazu schreiben, damit ich sie besser verstehe.

so?

Code: Alles auswählen

x, y = 1, 5
r =(x*y)**.5
q = r/(x*x+y*y)**.5
print q*x, q*y 

Danke!
Zuletzt geändert von mayx am Dienstag 1. Dezember 2009, 23:50, insgesamt 1-mal geändert.
Ronnie
User
Beiträge: 73
Registriert: Sonntag 21. März 2004, 17:44

Python unterstützt doch komplexe Zahlen:

Code: Alles auswählen

from cmath import polar
point = (5+5j)
r, phi = polar(point)
print(r, phi/pi*180)
Achtung: User ist ein Python-Lehrling!
mayx
User
Beiträge: 71
Registriert: Sonntag 3. Mai 2009, 02:51

so ;)

Code: Alles auswählen

x, y = 2, 2
if not x == 0 and not y == 0:
    r =(x*y)**.5
    q = r/(x*x+y*y)**.5
    x, y = q*x, q*y 
print x, y
das mit den Komma ist Cool. kannte ich noch gar nicht! Danke!!!

Ronnie du hängst mich ab ;) schau ich mir gleich mal an.
-> from cmath import polar // ImportError: cannot import name polar
ab welcher Pythonversion?
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

New in version 2.6.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

@mayx: Du hast meine Frage noch nicht klar beantwortet: Brauchst du nur die neuen x- und y-Werte oder brauchst du tatsächlich auch irgendwelche Winkel?

Meine "Lösung" (falls sie eine ist - das hängt eben davon ab, welche Daten du tatsächlich brauchst) ist nichts anderes als die Anwendung des 2. Strahlensatzes. Mach dir mal 'ne Skizze dazu ...
Antworten