ich versuche hier gerade ein Objekt auszurichten. Mein Objekt ist ein STL-File und besteht damit aus vielen Dreiecken. Das Objekt ist auf den Schwerpunkt zentriert und ich fälle nun zu jedem Dreieckspunkt eine Gerade auf x. Damit kann ich den Punkt bestimmen, der die größte Entfernung hat (l^2 = x^2+y^2). Und daraus kann ich dann den Winkel herleiten, um den ich mein Objekt verdrehen müsste RadToDeg(alpha = y / wurzel(x^2+y^2)). Nun sollte ich damit eine Drehmatrix erzeugen können:
Aus x', y' und z wird ein Vektor erstellt und das Dreieck verschoben. x' und y' werden bei jedem Dreieck berechnet, so dass die Werte richtig sein sollten.
Das sieht soweit auch schon gar nicht schlecht aus, allerdings wird dabei mein Objekt etwas verzehrt und vergrößert und ich hab keinen Plan, wodran das liegt. Habe ich dabei etwas übersehen? Oder gibt es vielleicht eine elegantere Weise?
Ok, den 2. Teil habe ich inzwischen hinbekommen, aber beim 1. hängts noch...der Winkel ist leider nicht der Richtige. Aber eigentlich dürfte das nicht passieren.
mmh ich weiß nicht ob ich dich richtig verstehe, aber wenn du das in 3D machst, dann weiß ich nicht wo deine z-komponente geblieben ist.
Vielleicht kannst du nochmal genau erläutern was dein ziel ist?
willst du die längste kante entlang irgendeiner camera achse plotten?
Nein, es ist nicht die Kameraachse, sondern es geht um den Schwerpunkt des Koordinatensystems. Als Beispiel mein Objekt ist ein Rohr, welches irgendwo im Raum liegt. Als erstes wird es zentriert, sprich die Boundingbox liegt zentriert auf dem Schwerpunkt. Nun kann das Rohr aber im Winkel von 45° über dem Schwerpunkt (x,y) liegen. z ist hierbei nicht von Interesse, da ich die so weit schon ausgerichtet bekomme. Nun soll es aber nicht im Winkel von 45° liegen, sondern die längste Seite soll im Winkel von 0° auf x ausgerichtet werden.
Registriert: Di Okt 03, 2006 14:07 Beiträge: 1277 Wohnort: Wien
Das ist eine typische Aufgabe für einen Modeller.
1. Wenn der Schwerpunkt des Rohr-Objekts noch nicht im Koordinatenursprung liegt, dann muss es zunächst dorthin verschoben werden. Translationsvektor ist der Vektor vom aktuellen Schwerpunkt zum Koordinatenursprung, mit diesem Vektor müssen alle Punkte verschoben werden (glTranslate).
2. Annahme: das Rohr-Objekt ist jetzt waagrecht ausgerichtet (nur um die Y-Achse rotiert). Es soll jetzt so rotiert werden, dass es parallel zur X-Achse liegt. Der richtige Drehwinkel ist daher der Winkel zwischen der Hauptachse des Rohr-Objekts und der X-Achse. Mit diesem Winkel müssen alle Punkte rotiert werden (glRotate). Es ist immer günstig, bei Rotationen für die Rotationsachse einen Einheitsvektor zu nehmen, sonst können Verzerrungen auftreten (glRotate ist aber glaub ich ziemlich gutmütig, eine Rotationsmatrix ist nicht so tolerant).
3. Wie findet man die Hauptachse des Objekts? Wenn es ein regelmäßiges Objekt ist, wie ein Zylinder oder eine Kugel, so ergibt sich der Richtungsvektor der Hauptachse als Durchschnitt der oberen (oder unteren) Hälfte aller Punkte (soll heißen: der RICHTUNGSVEKTOREN aller Punkte). Man darf nicht alle nehmen, sonst kommt ein Nullvektor raus. Vielleicht kannst Du die Hauptachse auch mittels Deiner Bounding Box finden.
4. Der Drehwinkel ist das Skalarprodukt der beiden beteiligten (EINHEITS-!!)Vektoren und zwar in Radiant. Zu den Grad kommst Du, wenn Du das Ergebnis noch mit 180/Pi multiplizierst.
Traude
Zuletzt geändert von Traude am Di Mär 06, 2007 08:54, insgesamt 1-mal geändert.
Was meinst du mit Einheitsvektor, bzw wie soll ich das verstehen?
Es sind leider keine regelmäßigen Objekte, das Beispiel sollte es nur verdeutlichen tut mir leid. Die Hauptachse versuche ich über ein rechtwinkliges Dreieck herauszufinden, da es die längste Strecke durch das Objekt ist. Oder habe ich da einen Denkfehler?
Hey Peter,
also ich weiß nicht ob ich es jetzt gerallt hab aber ich würd das glaub ich so machen:
d = sqrt(x^2+y^2+z^2) soll maximal sein
hiermit ermittelst du die distanz zu deinem am weitesten entfernten punkt. ist dieser ermittelt, haust du den vektor v = (x y z)^T einfach in eine Rotationsmatrix, ganz ähnlich wie du es in deinem ersten posting gemacht hast. nur da ich immer noch nicht ganz weiß warum z nicht von interesse ist, sag ich einfach mal: nimm einer rotationsmatrix für den 3D-Raum, dann bist du auf der sicheren seite. (Du hattest nur eine 2d-rotationsmatrix benutzt).)
Die winkel für die matrix ermittelst du entweder über trigonoetrische verhältnisse oder dem skalarprodukt.
ich hoffe ich konnte dir helfen, vielleicht stell ich mich auch einfach nur zu blöd an dein prob zu verstehen.
anyhow viel glück beim lösen des problems
cherio Woltan
Also das Rotieren ist nicht das Problem, auch wenn ich mit einer Translation arbeite und eine Kreisbahn verwende. Was mir mehr Sorgen macht, ist, dass ich nicht immer den richtigen Winkel habe und das in einer Schleife mache, damit sich Alpha 0 annähert. Hast du da vielleicht auch eine Idee zu?
@Woltan Mein Objekt muss nur in 2D verdreht werden, da Z optimal für mich ausgerichtet ist. Und im Moment ist mein Problem den richtigen Winkel zu finden.
Es geht im Endeffekt darum, die minimal Boundingbox herauszufinden. Deswegen komme ich wohl auch nicht um einen iterativen Vorgang herum, aber vielleicht habt ihr ja auch die Lösung, nur ich verstehs nicht Im nachhinein hätte ich mal besser in Mathe aufpassen sollen
y ist die Kathete und l die Hypothenuse. Ich durchlaufe zuerst alle Dreiecke und fälle vom Punkt eine Lotrechte auf die x-Achse. Damit habe ich ein rechtwinkliges Dreieck und dann ist P[x]^2+P[y]^2=Hypothenuse^2. Dabei suche ich die längste Hypethenuse und die ist P1. Nun durchlaufe ich wieder alle Dreiecke und bilde ein rechtwinkliges Dreieck aus (P1[x]-P[x])^2+(P1[y]-P[y])^2=Hypothenuse^2. Somit habe ich die längste Strecke über das gesamte Objekt. Dann ist P1[x]-P2[x]=x, P1[y]-P2[y]=y und x^2+y^2=l^2. Sin(Ankathete/Hypothenuse) = Alpha.
Verständlich? Und danke für die Aufmunterung
Das Objekt kannst du dir wie eine Aneinanderreihung von Kegeln vorstellen. Unterschiedliche Höhe und Breite eingeschlossen. Wobei die Idee mit dem Gesamtvektor vielleicht gar nicht so schlecht ist. Mal sehen, ob ich das umsetzen kann.
Registriert: Di Okt 03, 2006 14:07 Beiträge: 1277 Wohnort: Wien
Ich hoffe, ich hab Dich verstanden.
Wenn Du die Punkte in einem Array hast (das nehme ich mal an), musst Du sie, um den weitest entfernten zu finden, nicht zweimal durchlaufen. Du merkst Dir einfach den bisher längsten, indem Du die Punkteliste durchläufst und immer die Länge des Vektor des aktuellen Punktes mit dem bisher längsten Vektor vergleichst und Dir den längeren merkst:
Code:
Type
TVector3D =Record x,y,z:Single;End;
Function PointWithLongestDistance(PointList:ArrayOf TVector3D):Integer;
Var
Range,RangeOld:Single;
CountPoints:Integer;
Begin
Result:=0;
Range:=0;
CountPoints:=Length(PointList);
For I:=0To CountPoints-1DoBegin
RangeOld:= Range;
Range:=Max(Range,VectorValue(PointList[I]));
If Range > RangeOld
Then Result:= I;
End;
End;
Function VectorValue(AVector: TVector3D): TSingle;
Begin
With AVector Do Result:=Sqrt(X*X+Y*Y+Z*Z);
End;
Das Ergebnis der Funktion "PointWithLongestDistance" sagt Dir, welches Dein Punkt mit der größten Distanz zum Koordinatenursprung ist (bzw. welchen Index er hat) und Du kannst jetzt immer leicht drauf zugreifen.
Fürs Ausrechnen des Winkels (zwischen dem ausgerechneten längstenVektor und der X-Achse) würd ich Dir heftig zum Skalarprodukt raten und auch dazu, Deinen Z-Wert immer mitzurechnen. Für die Rotation brauchst Du das auf jeden Fall: wenn Du ein Objekt um die Y-Achse rotierst, ändert sich der Z-Wert.
Allerdings ist noch zu beachten: das Ganze funktioniert z.B. bei einem regelmäßigen Objekt gar nicht (was ist der längste Vektor eines Würfels?)
GANZ WICHTIG: es ganz klang mir danach, als ob Du jeden Punkt einzeln rotieren willst (vielleicht habe ich das falsch verstanden). Selbst wenn Du noch so genau rechnest, wirst Du Rundungsdifferenzen haben und das Objekt wird dadurch verzerrt. Man sollte also alle Punkte mit dem gleichen Winkel rotieren.
Die Funktion funktioniert schon einmal sehr gut! Vielen dank! Ich habe mir das jetzt noch einmal wirklich genauer angeschaut und festgestellt, dass mein Winkel falsch berechnet wird. Denn wo eigentlich ~ 80° sein sollten, bin ich nur bei 45°, aber da muss ich mir erstmal ein paar Dinge anzeigen lassen, damit ich weiß, was da falsch läuft.
Das mit dem Z-Wert finde ich verblüffend, denn ich bin fest davon ausgegangen, dass Z eben absolut ist. Beim Drehen um X verändert sich die Höhe eines Punktes doch eigentlich nicht. Und ihr sagt mir jetzt, dass es doch so ist. Da stellt sich mir die Frage: Warum? Eine Verzerrung habe ich so nicht feststellen können. Und ich berechne nur einmal Alpha und für die neue Position verwende ich auch nur diesen einen Alpha. Tut mir leid, da habe ich den Code zu weit geschrumpft.
Dann schaue ich jetzt mal nach dem Skalarprodukt (das kann mir an einer anderen Stelle vielleicht auch helfen) und melde mich dann wieder. Das kann allerdings eine ganze Weile dauern
Also ich habe da einen Fehler in der Formel gehabt, denn nicht Sin(y/l)=Alpha, sondern ArcSin(y/l)=Alpha. Damit habe ich jetzt den richtigen Drehwinkel und die Rotation sieht auch sehr gut aus! Bleibt noch ein kleiner Rest, aber wenn ich das nicht schaffe, mache ich ein neues Thema aus, weil es nicht direkt damit zusammenhängt
Mitglieder in diesem Forum: 0 Mitglieder und 2 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.