Seite 1 von 1

3D Objekt soll elegant um 3d Objekt kreisen

Verfasst: 24.02.2011 00:56
von mpz
Hallo Leute,

für eine Demo von mir suche noch einen einfachen und schönen Algorythmus um ein Objekt elegant um ein anderes Objekt kreisen zu lassen. Dazu werden die Cursortasten benutzt. Ich verwende dazu sin(t1) und cos(t2), aber das Objekt kreist Ungünstigstenfall fast um sich selber. Vermutlich hat dazu jemand noch eine besser Idee.

Hier der Code beispielhaft und das was rauskommt ;)

testdatei für Win XP-7 mit DX9:
http://www.file-upload.net/download-323 ... r.exe.html

Code: Alles auswählen

    test\x = Sin(t1)*1.2  ; 1.2 ist die Maximale Entfernung zum Mittelpunkt
    test\y = Cos(t2)*1.2
    test\z = Cos(t1)*1.2*Sin(t2)
    
    MP_PositionEntity (Sun, test\x, test\y, test\z) ; Setze Objekt auf koordinate, Sun = Objekt , test\x Wert der x Achse...
        
    If MP_KeyDown(#PB_Key_Left)=1 ; Cursor links gedrückt
       t1.f + 0.1       
    EndIf
    If MP_KeyDown(#PB_Key_Right)=1; Cursor rechts gedrückt
       t1.f - 0.1       
    EndIf
    If MP_KeyDown(#PB_Key_Up)=1; Cursor hoch 
       t2.f + 0.1       
    EndIf
    If MP_KeyDown(#PB_Key_Down)=1; Cursor runter
       t2.f - 0.1       
    EndIf
Danke für die Hilfe,
Michael

Re: 3D Objekt soll elegant um 3d Objekt kreisen

Verfasst: 24.02.2011 01:14
von gnasen
Ich finde es so wie es ist okay. Die Bedienung ist bei diesem Bsp wohl eher nebensache, hier gehts ja ums optische und das schaut interessant aus.
Eine alternative die mir spontan einfällt wären Kugelkoordinaten, siehe wiki.

Re: 3D Objekt soll elegant um 3d Objekt kreisen

Verfasst: 09.03.2011 21:15
von kswb73
So ganz spontan würde ich den Code in der ersten Zeile ändern. Grund: Du hast eine Rotation um die y Achse (welche test.x und test.z verändert). Das ganze drehst du dann um die X-Achse. Diese wurde durch die vorherige Rotation aber auch gedreht. (Vom Prinzip Gnasens Kugelkoordinaten). Deshalb muss auch ein Sinus bei test.x hin.

Code: Alles auswählen

        test\x = Sin(t1)*1.2*Sin(t2)  ; 1.2 ist die Maximale Entfernung zum Mittelpunkt
        test\y = Cos(t2)*1.2
        test\z = Cos(t1)*1.2*Sin(t2)
       
        MP_PositionEntity (Sun, test\x, test\y, test\z) ; Setze Objekt auf koordinate, Sun = Objekt , test\x Wert der x Achse...
           
        If MP_KeyDown(#PB_Key_Left)=1 ; Cursor links gedrückt
           t1.f + 0.1       
        EndIf
        If MP_KeyDown(#PB_Key_Right)=1; Cursor rechts gedrückt
           t1.f - 0.1       
        EndIf
        If MP_KeyDown(#PB_Key_Up)=1; Cursor hoch
           t2.f + 0.1       
        EndIf
        If MP_KeyDown(#PB_Key_Down)=1; Cursor runter
           t2.f - 0.1       
        EndIf
Edit Huch. Der Beitrag ist älter als er aussah.

Re: 3D Objekt soll elegant um 3d Objekt kreisen

Verfasst: 10.03.2011 16:38
von mpz
Danke,

aber er war ja noch nicht gelöst trotz seinem "Alter..."

Gruß Michael

Re: 3D Objekt soll elegant um 3d Objekt kreisen

Verfasst: 21.03.2011 11:37
von dige
Da Du in Deinem Bsp. die Erde bei Tag, Nacht und mit Wolken integriert
hast inkl. Beleuchtung... könntest Du da draus nicht einen schicken
Bildschirmschoner machen der das aktuelle Tageslicht anzeigt? ;-)

Re: 3D Objekt soll elegant um 3d Objekt kreisen

Verfasst: 27.07.2011 15:05
von Max_der_Held
[die oberen codes gehen nicht, weil sich die Achse nicht mitdreht wenn du mit sinus rotierst. der sinus orientiert sich IMMER an den X-Y-Z Achsen.]

Hier die mathematische Lösung:
  • zum Kreisen eines Objekts um einen Mittelpunkt:
    du berechnest den Normalenvektor von Erde zu Licht (spitze minus fuß)
    drehst diesen vektor um 90 Grad und bewegst ihn in die gewünschte Richtung.. (mit der Koordinatendarstellung der Normalenebene... siehe Formelsammlung S. 88 von "Barth-Mühlbauer-Nikol-Wörle" )
    [theoretisch kannst du auch gleich mit den Physik- Gravitationsgesetzen arbeiten, die sind u.U. einfacher]
  • die Formel dazu lautet:
    n1 * x + n2*y + n3*z - ( n1*p1 + n2*p2 + n3*p3 ) = 0

    n1, n2 und n3 ist der Vektor vom Erdmittelpunkt hin zum Licht (praktisch der Normalenvektor der Bewegungsebene... . .. .egal..)
    p1,p2 und p3 sind die Koordinaten des Lichtes.
    x, y und z sind die Verschiebungskoordinaten praktisch.. dieser Vektor muss normalisiert werden damit er den Betrag 1 hat (oder welchen du auch willst)
    jetzt x und y einsetzen und z ausrechnen..

Code: Alles auswählen

; INIT:
Structure vector3f
  x.f
  y.f
  z.f
EndStructure

Structure vector2f
  x.f
  y.f
EndStructure

Procedure vec_normalize2f   ( *vec.vector2f)
   Protected lange.f 
   If *vec  <= 0            : ProcedureReturn : EndIf 
   lange    = Sqr( *vec\x   * *vec\x + *vec\y * *vec\y )
   If lange = 0             : ProcedureReturn : EndIf  ; nicht durch 0 teilen!.. 
   *vec\x   / lange
   *vec\y   / lange
EndProcedure 

p.vector3f                  ; das sollen die aktuellen Koordinaten des Lichtes sein.. musst halt noch mit MP_EntityPosition() oder so abfragen.
n.vector3f                  ; unser Richtungsvektor und später die neue Position.
Erde.vector3f               ; die Koordinaten der Erde.. ebenfalls mit MP_EntityPosition () abfragen. 
x.vector3f                  ; die bewegungsRICHtung praktisch.. x, y und z 
Beweg.vector2f              ; um wie viel das Licht bewegt werden soll.
Beweg_normalized.vector2f   ; die Normalisierte Form (mit Betrag 1)
Beweg\x                     = 0.1 ; die Startrichtung.. 

; -----------------------------------------------------------------------------------------
; SCHLEIFFE: 
; -----------------------------------------------------------------------------------------


        MP_GetEntityPosition( Sun, @p )     ; Verändere das so das es läuft....

        If MP_KeyDown   ( #PB_Key_Left)=1   ; Cursor links gedrückt
          Beweg\x       + 0.1       
        EndIf
        If MP_KeyDown   ( #PB_Key_Right)=1  ; Cursor rechts gedrückt
           Beweg\x      - 0.1       
        EndIf
        If MP_KeyDown   ( #PB_Key_Up)=1     ; Cursor hoch
           Beweg\y      + 0.1       
        EndIf
        If MP_KeyDown   ( #PB_Key_Down)=1   ; Cursor runter
           Beweg\y      - 0.1       
        EndIf
        If Beweg\x      >  30               : Beweg\x =  30 : EndIf ; statt beweg x/y kannst du auch auf Winkel umsteigen,
        If Beweg\x      < -30               : Beweg\x = -30 : EndIf ; So ist es gerade leichter.
        If Beweg\y      >  30               : Beweg\y =  30 : EndIf 
        If Beweg\y      < -30               : Beweg\y = -30 : EndIf 
        
With n
   \x = Lichtposition\x - Erde\x
   \y = Lichtposition\y - Erde\y 
   \z = Lichtposition\z - Erde\z 
EndWith 
Beweg_normalized = Beweg

vec_normalize2f ( Beweg_normalized  )   ; damit die Kugel immer mit der gleichen Geschwindigkeit fliegt.

With x
   \x = Beweg_normalized \x             ; also um wie viel er in x richtung verschoben werden soll ( unser vektor )
   \y = Beweg_normalized \y             ; gleiches für y, Z muss berechnet werden. 
   \z = (( n\x * p\x + n\y* p\y + n\z * p\z ) -n\x * p\x  - n\y * p\y ) / n\z 
EndWith 


MP_PositionEntity (Sun, p\x + x\x , p\y + x\y , p\z + x\z ) ; bewegungsrichtung PLUS Koordinaten = neue Koordinaten.
konnte jetzt nicht testen ob sich ein Fehler eingeschlichen hat in meine kranken Gehirnwindungen...
Ich hoffe aber es läuft
Bei Fragen... einfach fragen!.. Es ist vielleicht nicht alles ganz einfach (wir drehen hier das Koordinatensystem und bewegen uns auf der Ebene die direkt unter dem Licht ist in irgendeine Richtung. als würde das Licht auf der Erde stehen und dauernd z.B. geradeaus gehen)

MfG,
Max W. Aigner.