kostenloser Webspace werbefrei: lima-city


Kamera um Punkt kreisen lassen.

lima-cityForumProgrammiersprachenJava

  1. Autor dieses Themas

    reimann

    Kostenloser Webspace von reimann

    reimann hat kostenlosen Webspace.

    Ich suche nach einer Formel mit der ich die Kameraposition in einem Kreis bewegen kann.
    Dabei bleibt der Abstand zum Punkt der selbe. Bekannt ist dabei die Position der Kamera, der Punkt um den sie kreist, und ein Vielfaches von Pi mit dem bestimmt wird wie weit sie sich bewegen soll. Außerdem bewegt sie sich dabei in einer Ebene die von dem Vektor zwischen Punkt und Kamera sowie einem bekannten anderen Vektor gespannt wird. Der Abstand zwischen Punkt und Kamera bleibt immer gleich. Eine Vektorklasse ist vorhanden.
    Wie kann ich jetzt mit Java den anderen Punkt, also die neue Position der Kamera, berechnen?
    Ich muss an sich irgendwie die Sehne herausfinden, die durch den Umfangsabschnitt entsteht und dann den neuen Punkt mit den Abständen und der Ebene berechnen aber wie?:confused:

    Beitrag zuletzt geändert: 6.11.2011 18:34:55 von reimann
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. Schnappe dir den Punkt der Kamera an einem beliebigen Ort, beobachte, wie der Abstand zwischen diesem Punkt und dem aktuellen Punkt der Kamera größer wird, und halte dann, bevor der Abstand zwischen den beiden Punkten wieder kleiner wird, an, und merke dir auch diesen Punkt. Dann bestimmst du mittels der Durchschnittswerte der Koordinaten der Punkte in allen Dimensionen den Punkt, um den die Kamera kreist.
  4. Hallo reimann,

    die Bahnkurve sollte doch durch folgende Kurve gegeben sein:
    Formel: \vec{p}(\phi)=r \cdot \sin(\phi) \cdot \vec{b}_1 + r \cdot \cos(\phi) \cdot \vec{b}_2+\vec{c}
    wobei r der Radius, b1, b2 die normierten Basisvektoren der aufgespannten Ebene und c der zu umkreisende Mittelpunkt ist.
    Um bei bekannter Position auf den Winkel zu kommen würde ich ihn in die aufgespannte Ebene projezieren und dann mit atan2() den Winkel berechnen. Dann kannst Du die gewünschte Änderung durchführen und die neue Position berechnen. Die neue Blickrichtung ist ja dann einfach c-p.

    Edit: Vorraussetzung ist natürlich, dass b1 und b2 orthogonal sind.

    Beitrag zuletzt geändert: 6.11.2011 18:33:45 von darkpandemic
  5. Autor dieses Themas

    reimann

    Kostenloser Webspace von reimann

    reimann hat kostenlosen Webspace.

    Ich hab leider grade keine Möglichkeit das zu testen, aber sie sind wahrscheinlich nicht zwangsläufig orhtogonal.
    Zum Verständis:
    x zeigt nach rechts
    y nach oben
    z auf einen selbst
    Dabei wird die seitliche Bewegung als Kreis auf der ebene zwischen b1 (normalisierte Kameraposition) und (1|0|0) und die vertikale Bewegung auf der Ebene b1 und (0|1|0), wobei c momentan noch (0|0|0) entspricht. Dabei stellt sich aber das Problem, dass sie an 2 Stellen rein theoretisch linear abhängig und damit keine Ebene mehr wären. Außerdem wäre damit der Ergebnisvektor auch nicht mehr orthogonal und deshalb versteh ichd as Ganze nicht richtig.

    Beitrag zuletzt geändert: 6.11.2011 19:45:00 von reimann
  6. Hallo reimann,

    das Koordinatensystem klingt für mich nach OpenGL (zumindest wird dort das selbe verwendet).
    Ich gehe davon aus, dass sich die Kamera auf einer Kreisbahn mit dem Zentrum c bewegt und es sich tatsächlich um eine Kreisbahn handelt. D.h. es gibt eine zweidimensionale Ebene durch c die die Bahnkurve vollständig enthält. (Mathematisch wäre es ein 2D affiner Unterraum.)
    Nachdem die Ebene zweidimensional ist lässt sich immer ein paar von orthogonalen Vektoren finden, die eine Basis des affinen Unterraumes darstellen. Als Beispiel: Seien (1|1|0) und (1|1|1) zwei Vektoren die den Unterraum aufspannen. Diese sind offensichtlich linear unabhängig. Angenommen, man will den ersten Vektor behalten, dann muss man die Projektion des zweiten Vektors auf den ersten vom zweiten abziehen um den linear unabhängigen orthogonalen Vektor zu erhalten:
    Formel: \left(\begin{array}{c} 1 \\ 1 \\ 1\end{array}\right)-\frac{\left\langle\left(\begin{array}{c} 1 \\ 1 \\ 0\end{array}\right) , \left(\begin{array}{c} 1 \\ 1 \\ 1\end{array}\right)\right\rangle}{\left\langle\left(\begin{array}{c} 1 \\ 1 \\ 0\end{array}\right), \left(\begin{array}{c} 1 \\ 1 \\ 0\end{array}\right)\right\rangle}\left(\begin{array}{c} 1 \\ 1 \\ 0\end{array}\right)=\left(\begin{array}{c} 0 \\ 0 \\ 1\end{array}\right)
    Jetzt hat man zwei orthogonale Vektoren, die die Ebene aufspannen( (1|1|0) und (0|0|1) ). Wenn man beide normalisiert, dann können diese jetzt als b1 und b2 verwendet werden. Wenn man diese Vektoren einmal hat, dann darf/muss man sie nicht mehr ändern, da die Bahn der Kamera ja vollständig in der affinen Ebene liegt, weshalb sie auch nicht linear abhängig werden können. Die einzige Variable, die Du jetzt noch hast ist der Winkel.
  7. Autor dieses Themas

    reimann

    Kostenloser Webspace von reimann

    reimann hat kostenlosen Webspace.

    So ich hatte endlich Zeit es zu testen und so recht will es nicht funktionieren. Ich habe die Formeln in Java umgesetzt, aber entweder ist irgendwo einen Fehler, oder aber es klappt so nicht. Übrigens ist es auch OpenGL bzw. die jmonkeyengine, die das Koordinatensystem verwendet.
    Hier mal der Quelltext:
    if( mode == 2 || mode == 3 ) value = value * -1;
    if( mode < 2 ) {
        ebev = Vector3f.UNIT_Y;
    }
    else {
        ebev = Vector3f.UNIT_X;
    }
    ebev = ebev.subtract( camv.mult( camv.dot( ebev ) / camv.dot( camv ) ) );
    move = camv.multLocal( radius * (float) Math.sin( value ) ).addLocal( ebev.multLocal( radius * (float) Math.cos( value ) ) );

    Dabei ist mode 1 hoch, mode 2 runter, mode 3 links und mode 4 rechts.
    value ist die Grad Anzahl.
    camv (normalisierter Vektor zur Kameraposition), ebev und move sind Vektoren, wobei die Kamera an die Position von move gesetzt wird.

    Beitrag zuletzt geändert: 10.11.2011 19:58:40 von reimann
  8. Hallo reimann,

    das erste was mir auffällt ist, dass Du ebev (=b2) jedesmal neu berechnest. Vermutlich machst Du das mit camv ebenso. Wenn dem so ist, dann kommen falsche Sachen raus, weil sich ständig (in jedem Schritt) das Bezugssystem (b1, b2) ändert.
    Das Bezugssystem soll aber am Anfang aus den Startbedingungen hergeleitet werden und dann beibehalten werden. D.h. camv und ebev sollten konstant bleiben.
    Desweiteren schließe ich jetzt mal aus mode=1 und mode=2, dass Du auch die Ebene verlassen willst. Dann wäre die Kamera auf einer Kugeloberfläche und nicht mehr auf einem Kreis.
    Der Einfachheit halber bleibe ich jetzt erst mal bei dem Kreis:
    Als erstes kannst Du ja folgendes ausprobieren:
    Definiere in Deiner Klasse eine Variable um den Winkel zwischenzuspeichern und setze einen Würfel in den Koordinatenursprung (z.B. Kantenlänge = 1).
    Dann wählst Du b1 = (1,0,0) und b2 = (0,1,0). Damit sollte die Kamera um die z-Achse kreisen. Als Radius ist dann vielleicht 3 oder 4 gut.
    In der Rendering-Schleife kannst Du dann ungefähr folgendes machen:
    angle += increment; // z.B. ein Grad. Ich weiß ja nicht ob Du Bogenmaß oder Grad hast.
    move = b1.multLocal( radius * (float) Math.sin( angle ) ).addLocal( b2.multLocal( radius * (float) Math.cos( angle ) ) );
    Als Blickrichtung für die Kamera solltest Du dann move*(-1) setzen. Eigentlich solltest Du dann einen rotierenden Würfel sehen.

    Edit: Da Du den Winkel in Math.sin() und Math.cos() einsetz muss es sich um Bogenmaß handeln. Also z.B. increment = Math.PI/180.0.

    Beitrag zuletzt geändert: 10.11.2011 21:27:02 von darkpandemic
  9. Autor dieses Themas

    reimann

    Kostenloser Webspace von reimann

    reimann hat kostenlosen Webspace.

    Achso hab vergessen dazu zu schreiben, dass die Bewegung per Taste ausgelöst wird.
    Es sollte immer nur eine Bewegungsrichtung gleichzeitig ausgelöst werden und beim Test habe ich auch nur eine Richtungspfeiltaste gedrückt, weshalb es immer noch bei einem Kreis bleibt.:wink:
    camv wird einfach aus der derzeitigen Position der Kamera abgeleitet bzw. normalisiert und ebev damit neu berechnet, da die Kamera in der Ebene liegen sollte und der andere Vektor ist dazu da, dass sich die richtige Ebene aufspannt. Für mich war der normalisierte Positionsvektor des derzeitigen Ortes der Kamera b1.
    Aber ich glaube, du meinst, dass von vornherein schon ein Winkel da ist und nicht eine Position, was mir jetzt auch anhand des ersten Posts klar wird. Trotzdem werde ich aus dem atan2 etc. nicht schlau. Wie kann ich den derzeitigen Winkel auf der Ebene bestimmen?.
    (Sry aber Vektorrechnung ist bei mir schon 1,25 Jahre her.:biggrin:)
  10. Hallo reimann,

    ich bin davon ausgegangen, dass der Kreis fest ist. Das würde bedeuten, dass man nur auf dem Kreis vor oder zurückwandern kann. Dieses wäre dann einfach eine Vergrößerung bzw. Verkleinerung des Winkels, wobei alle anderen Sachen gleich bleiben.
    Zu atan2():
    Wenn man einen Vektor (x,y) hat und wissen will, welchen Winkel dieser mit der x-Achse einschließt, dann liefert atan2(y ,x) (x und y müssen vertauscht werden!) den Winkel als Wert zwischen -pi und pi.
    Welches Koordinatensystem zugrunde gelegt wird ist dem atan2() egal, solange es rechtwinklig ist. Daher kann man b1 als x-Achse und b2 als y-Achse verwenden. Die Koordinaten einer Kameraposition ergibt sich dann zu:
    x' = <b1;(p-c)> und y'=<b2;(p-c)>
    Dabei ist p die Kameraposition, c das Kreiszentrum, (b1, b2) die Basis der Kreis- bzw. Bahnebene und (x', y') die Koordinaten in der Basis (b1, b2). < _ ; _ > soll das Standardskalarprodukt sein.
    Der aktuelle Winkel ist dan atan2(y', x') und der neue Winkel wäre dann der alte +/- Inkrement.
  11. Autor dieses Themas

    reimann

    Kostenloser Webspace von reimann

    reimann hat kostenlosen Webspace.

    Also ich habs so irgendwie immer noch nicht hinbekommen, aber ich habe jetzt einfach ein bisschen an der ChaseCamera herumgebastelt. Sie muss den Würfel zwar nicht verfolgen, da er immer an der selben Stelle bleibt, aber das Rotieren funktioniert bei ihr wunderbar und auch wesentlich einfacher.
    Trotzdem bin ich jetzt um einiges klüger, was Vektorberechnung und dergleichen angeht.
    Danke:thumb:
  12. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!