Vektorrechnung

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
needpython
User
Beiträge: 10
Registriert: Donnerstag 10. Juli 2014, 19:21

ich möchte diese Zickzack-kette aus Vektoren bilden

Bild

Alle Vektoren im Bild haben die selben Beträge und der Winkel zwischen ihnen ist der selbe. und sie liegen alle in der yz-ebene

ich denke mir den Startvektor AB aus, indem ich mir den Startpunkt und Endpunkt ausdenke. Daraus bilde ich dann den Vektor AB. Diesen Vektor multipliziere ich mit eine Drehmatrix mit entsprechendem winkel und addiere den endpunkt des Vektors AB. Somit hätte ich dann den Vektor P1 im Bild. P1 multipliziere ich ebenfalls mit der Drehmatrix, aber mit negativen winkel und addiere wieder den endpunkt von P1, dann hätte ich den Vektor P2

so mein Problem ist, dass der endpunkt im folgenden code in der for-schleife fest ist. Der endpunkt ist der endpunkt des Vektors Ab im folgenden Code, ABER es soll immer der Endpunkt des neues Vektors sein. also eine variabel. wie mache ich das am besten?

hier der code (nur ein ausschnitt). tmp ist im code nur eine liste, bei der ich auf die koordinaten des vektors zugreifen muss. die liegen im 5,6 und 7 element der liste

Code: Alles auswählen

def drehmatrix(winkel):
  
  Drehmatrix = numpy.array([[1,0,0],[0, math.cos(winkel),-math.sin(winkel)],[0,-math.sin(winkel),math.cos(winkel)]])
  return Drehmatrix

startpunkt = numpy.array([0,1,2])
endpunkt = numpy.array([0,4,6])
startvektor = endpunkt - startpunkt

tmp.append(["HETATM", len(tmp)+1, "C", "POP" , "L", 1, startvektor[0], startvektor[1], startvektor[2]])

print tmp[31]

for ii in range(Anzahl_der_C):

	letzter_vektor = numpy.array([float(tmp[len(tmp)-1][6]),float(tmp[len(tmp)-1][7]),float(tmp[len(tmp)-1][8])])
	
	if letzter_vektor[1]>=0:
		gedrehter_vektor = numpy.dot(drehmatrix(numpy.radians(180-104)), letzter_vektor)
	if letzter_vektor[1]<0
		gedrehter_vektor = numpy.dot(drehmatrix(numpy.radians(-(180-104))), letzter_vektor)

	new_vektor = numpy.add(gedrehter_vektor, endpunkt)

	Liste_der_C = ["HETATM", len(tmp)+1, "C", "POP" , "L", 1, new_vektor[0], new_vektor[1], new_vektor[2]]
	
	tmp.append(Liste_der_C)
BlackJack

@needpython: Na offensichtlich musst Du nachdem der neue Vektor berechnet ist `endpunkt` an den neuen Endpunkt binden.

Der Quelltext lässt sich übrigens nicht compilieren. Lauffähige Beispiele sind immer ganz nett/praktisch, aber wenigsten sollten sie keine Syntaxfehler enthalten, also tatsächlich verwendeten Quelltext enthalten. Sonst rätselt man am Ende an Quelltext herum der gar nicht wirklich dem entspricht der das Problem aufweist.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Du musst "endpunkt" einfach an einen neun Wert binden. Also das Ende des neuen Vektors. Das wars.

Dein Code ist aber noch stark verbesserungswürdig. Als erstes sollte die drehmatrix-Funktion einen vernünftigen Namen bekommen. Da Funktionen typischerweise Aktivitäten beschreiben, sollte darin ein Verb enthalten sein. Außerdem kann man noch viel zusammenfassen:

Code: Alles auswählen

def drehmatrix_erstellen(alpha):
    ca, sa = math.cos(alpha), math.sin(alpha)

    return np.matrix(
        [[1,   0,    0],
         [0,  ca, -sa],
         [0, -sa,  ca]])
Auch solltest du dich an PEP 8 halten. Namen, welche mit einem Großbuchstaben beginnen, sind ein Hinweis auf einen Typ. "Drehmatrix" ist aber kein Typ. Lies dir das Dokument einfach mal durch, damit wird dein Code für alle verständlich.

Bis auf Importe, Klassen, Funktionen und Konstanten sollte auch kein Code auf modulebene stehen. Packe das in eine main-Funktion, dann kannst du dein Modul auch in anderen Modulen importieren.

"ii" in Zeile 14 ist ein äußerst schlechter Name. In drei Tagen weißt du doch schon nicht mehr, was der eigentlich bedeuten soll. Verwende sprechende Bezeichner. Selbes gilt für "Anzahl_der_C". Was soll dieses ominöse "C" sein?

In Zeile 16 wiederholt sich extrem viel Code, das solltest du alles zusammenfassen. Besonders die ganzen doppelten Berechnungen. Sind die float-Aufrufe wirklich notwendig?

Wenn du ein Konstrukt wie in Zeile 18 und 20 hast, dann solltest du das umschreiben.

Code: Alles auswählen

if letzter_vektor[1] >= 0:
    ...
else:
    ...
Zeile 19 und 20 sind quasi identisch, das lässt sich leicht zusammenfassen:

Code: Alles auswählen

sign = 1.0 if letzter_vektor[1] >= 0 else -1.0
gedrehter_vektor = numpy.dot(erstelle_drehmatrix(sign*winkel), letzter_vektor)
Das Leben ist wie ein Tennisball.
needpython
User
Beiträge: 10
Registriert: Donnerstag 10. Juli 2014, 19:21

danke euch beiden für die antwort
EyDu hat geschrieben:Du musst "endpunkt" einfach an einen neun Wert binden. Also das Ende des neuen Vektors. Das wars.
meinst du so?

Code: Alles auswählen

endpunkt = endpunkt+new_vektor
EyDu hat geschrieben:Selbes gilt für "Anzahl_der_C". Was soll dieses ominöse "C" sein?
C steht hier für Kohlenstoff. ja ich werde meinen code nochverbessern

Kann ich mein Ergebnis irgendwie visualisieren? ich möchte überprüfen ob die vektoren auch richtig gebildet werden
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

needpython hat geschrieben:meinst du so?
Manchmal geht selbst ausprobieren schneller und einfacher als nachfragen ;-)
needpython hat geschrieben:Kann ich mein Ergebnis irgendwie visualisieren? ich möchte überprüfen ob die vektoren auch richtig gebildet werden
Dazu kannst du matplotlib verwenden. Auf der dazugehörigen Seite gibt es eine schöne Gallerie. Schau dir die am besten mal an und orientiere dich dann an einem passendem Beispiel.
Das Leben ist wie ein Tennisball.
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

Wenn Du nur 2D Grafik machen möchtest, d.h. nur Drehungen und Verschiebungen in der xy-Ebene, dann kannst Du das viel einfacher mit komplexen Zahlen als mit 3D-Vektoren und 3x3 Matrizen hinbekommen:

Code: Alles auswählen

import numpy as np

v1 = 2.2 + 3.5j # x: 2.2, y: 3.5

# Drehoperator:
# dreht einen Vektor in der xy-Ebene (d.h. komplexe Zahl)
# um die Z-Achse um den Winkel 35 GRAD
rotOp = np.exp(1j * np.radians(35))

v2 = rotOp*v1 # x: -0.205, y: 4.129
print(v2)
a fool with a tool is still a fool, www.magben.de, YouTube
needpython
User
Beiträge: 10
Registriert: Donnerstag 10. Juli 2014, 19:21

Hallo,

kann es sein, dass oben im meinem Code ein mathematischer fehler ist? bei mir ändern sich die beträge der Vektoren(sie werden größer) und das kann ja nicht sein.
wenn ich einen vektor mit der drehmatrix multipliziere, dann ändert sich nicht die länge der Vektoren, sondern nur die richtig.
ich finde den fehler nicht. kann jemand helfen?
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Du darfst nicht immer an dem letzten Vektor drehen. Da du diesen schrittweise aufaddierst, ändert sich auch dessen Länge. Entweder verschiebst du also den Vektor zum Ursprung, rotierst ihn ahnschließend und schiebst ihn dann wieder zurück, oder du berechnest die Vektoren einmal und addierst dann Vektor für Vektor. Die sind ja immer gleich.

Bedenke einfach, dass immer um den Ursprung des Koordinatensystems gedreht wird, egal wo sich der Startpunkt deines Vektors befindet. Am besten zeichnest du dir das per Hand auf ein Stück Papier auf, dann kannst du das sehr gut nachvollziehen.
Das Leben ist wie ein Tennisball.
needpython
User
Beiträge: 10
Registriert: Donnerstag 10. Juli 2014, 19:21

EyDu hat geschrieben:Bedenke einfach, dass immer um den Ursprung des Koordinatensystems gedreht wird, egal wo sich der Startpunkt deines Vektors befindet. Am besten zeichnest du dir das per Hand auf ein Stück Papier auf, dann kannst du das sehr gut nachvollziehen.
aber ein vektor ist ortsunabhängig. ist es dann nicht egal ob der Vektor vom Ursprung startet oder irgendwo in der ebene steht, um es zu drehen? oder ich habe gerade einen denkfehler

ich habe einen weiteren fehler gefunden. die drehmatrix hat einen vorzeichenfehler. das minus in der dritten zeile bei sinus gehört da nicht hin.

So ich habe nun den nachfolgenden Code. ich habe vor der for-schleife einen drehvektor festgesetzt. ich drehe immer um diesen vektor abwechselend mit positiven und negativen winkel.

Code: Alles auswählen

import math
import numpy
import matplotlib.pyplot as plt

Anzahl_der_C = int(raw_input("Gib Anzahl der C-Atome an"))

tmp = []

def drehmatrix(winkel):
  
  Drehmatrix = numpy.array([[1,0,0],[0, math.cos(winkel),-math.sin(winkel)],[0,math.sin(winkel),math.cos(winkel)]])
  return Drehmatrix

startpunkt = numpy.array([0,0,0])
endpunkt = numpy.array([0,1,math.sqrt(3)])
startvektor = endpunkt - startpunkt

tmp.append([startvektor[0], startvektor[1], startvektor[2]])

dreh_vektor = numpy.array([float(tmp[len(tmp)-1][0]),float(tmp[len(tmp)-1][1]),float(tmp[len(tmp)-1][2])])

for ii in range(Anzahl_der_C):

	letzter_vektor = numpy.array([float(tmp[len(tmp)-1][0]),float(tmp[len(tmp)-1][1]),float(tmp[len(tmp)-1][2])])
	
	if letzter_vektor[1]>=0:
		gedrehter_vektor = numpy.dot(drehmatrix(numpy.radians(180-104)), dreh_vektor)
	if letzter_vektor[1]<0:
		gedrehter_vektor = numpy.dot(drehmatrix(numpy.radians(-(180-104))), dreh_vektor)
		

	new_vektor = numpy.add(gedrehter_vektor, letzter_vektor)
	
	print new_vektor

	Liste_der_C = [ new_vektor[0], new_vektor[1], new_vektor[2]]
	
	tmp.append(Liste_der_C)
new_vektor ist falsch, da sich die länge des Vektors ändert. ich verstehe nicht wieso. Wenn ich den Vektore drehe, ändert sich die länge nicht. also alles ok soweit.
bei new_vektor = numpy.add(gedrehter_vektor, letzter_vektor) versuche ich den gedrehten vektor zur spitze des letzten Vektors zu verschieben, aber dann ändert sich die länge des vektors. Wie verschiebe ich den gedrehten Vektor zur Spitze des letzten Vektors ohne die länge zu verändern?
Sirius3
User
Beiträge: 17748
Registriert: Sonntag 21. Oktober 2012, 17:20

@needpython: Du benutzt Richtungsvektoren und Ortsvektoren, ohne zu wissen was Du da tust? Was soll den das hin und her konvertieren von Listen und Arrays? tmp ist auch nicht gerade ein guter Name. Wenn ein if genau die gegenteilige Bedinung des vorherigen if hat, kannst Du auch else benutzen; hier ließe sich das ganze aber einfacher mit numpy.sign schreiben.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

needpython hat geschrieben:aber ein vektor ist ortsunabhängig. ist es dann nicht egal ob der Vektor vom Ursprung startet oder irgendwo in der ebene steht, um es zu drehen? oder ich habe gerade einen denkfehler
Ich habe es doch schon geschrieben: Male es auf einem Blatt Papier auf.

needpython hat geschrieben:new_vektor ist falsch, da sich die länge des Vektors ändert. ich verstehe nicht wieso.
Weil du Vektoren addierst. Was glaubst du, was da sonst passieren soll? Wie gesagt, Zeichne es auf einem Blatt Papier auf.
needpython hat geschrieben:bei new_vektor = numpy.add(gedrehter_vektor, letzter_vektor) versuche ich den gedrehten vektor zur spitze des letzten Vektors zu verschieben, aber dann ändert sich die länge des vektors. Wie verschiebe ich den gedrehten Vektor zur Spitze des letzten Vektors ohne die länge zu verändern?
Das habe ich in meinem letzten Beitrag schon geschrieben.

Du könntest auch die von mir genannten Änderungsvorschläge einbauen, dein Code ist noch immer gruselig. Man hat das Gefühl, dass du gar keine Hilfe möchtest, sondern nur eine Lösung.
Das Leben ist wie ein Tennisball.
needpython
User
Beiträge: 10
Registriert: Donnerstag 10. Juli 2014, 19:21

ich habe nun folgenden code. im ersten lauf der for schleife bekomme ich richtige koordinaten, aber im zweiten lauf kommt unsinn raus.
Wo liegt der fehler? meines wissens nach addiere ich die vektoren jetzt nicht schrttweise auf, weil ich es immer zum ursprung verschiebe, bevor ich es drehe.

Code: Alles auswählen

# startvektor bilden
startpunkt = numpy.array([0,10,10])
endpunkt = numpy.array([0,11,9])
startvektor = startpunkt + (endpunkt - startpunkt)

# startvektor in tmp anhaengen
tmp.append([startvektor[0], startvektor[1], startvektor[2]])

for ii in range(anzahl_der_C):
	
	# auf den letzten Vektor zu greifen
	letzter_vektor = numpy.array([float(tmp[len(tmp)-1][0]),float(tmp[len(tmp)-1][1]),float(tmp[len(tmp)-1][2])])
	
	# vektor zum ursprung verschieben
	ursprung = letzter_vektor - startpunkt
	
	# Vektor drehen
	if letzter_vektor[2]>=0:
		gedrehter_vektor = numpy.dot(drehmatrix(numpy.radians(90)), ursprung)
	else:
		gedrehter_vektor = numpy.dot(drehmatrix(numpy.radians(-(90))), ursprung)

	# vektor verschieben
	new_vektor = gedrehter_vektor + endpunkt
	
	Liste_der_C = [ new_vektor[0], new_vektor[1], new_vektor[2]]
	
	# start und endpunkt aktualisieren
	startpunkt = startpunkt + letzter_vektor
	endpunkt = endpunkt + new_vektor
	
	tmp.append(Liste_der_C)
needpython
User
Beiträge: 10
Registriert: Donnerstag 10. Juli 2014, 19:21

die frage hat sich erstma erledigt

der start und endpunkt binde ich am ende an die falschen werte
Antworten