Mesh von einem Punkt zum nächsten Punkt bewegen mittels Cos

Für allgemeine Fragen zur Programmierung mit PureBasic.
Schoppy
Beiträge: 9
Registriert: 28.03.2009 04:41

Mesh von einem Punkt zum nächsten Punkt bewegen mittels Cos

Beitrag von Schoppy »

Hi,

da ich leider von Sinus uns Cosinus nicht viel Ahnung habe frage ich mal die Spezialisten ;-)

Also ich möchte lediglich ein Mesh von z.b. Position:
x = 100
nach x = 200
befördern.

z.Zt mache ich das mit

Code: Alles auswählen

if x<200 : x+1 : Endif
Sieht aber nicht so schön aus.

Im Forum habe ich mehrere Möglichkeiten gefunden, mittels Sinus etc. Habe eine probiert aber die ist nicht 100% korrekt.
Sprich dieser Wert 200 muss unbedingt erreicht werden ohne Abweichung also kein 201 oder 199.

Da liegt z. zt. mein Problem.

verwendet habe ich folgenden Code:
1) Bei der Zuweisung der neuen soll Position:

Code: Alles auswählen

      fnf(i)\xmove=(fnf(i)\pos_soll.l - fnf(i)\pos_ist.l)/2 
      fnf(i)\xl=fnf(i)\pos_ist.l 
2) die Ausführung:

Code: Alles auswählen

     fnf(i)\winkel.d +8 ; geschwindigkeit
     fnf(i)\bogenmass.f = fnf(i)\winkel.d * 3.1415926/180 
     fnf(i)\x.l = fnf(i)\xl.f - Cos(fnf(i)\bogenmass.f)*fnf(i)\xmove.f+fnf(i)\xmove.f
     fnf(i)\pos_ist.l = fnf(i)\x.l
     
     If fnf(i)\winkel.d = 180
     fnf(i)\winkel.d = 0
     EndIf 
Frage, wie erreiche ich immer den korrekten wert und habe eine sanfte Bewegung ?

Gruss
Schoppy
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7028
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Mesh von einem Punkt zum nächsten Punkt bewegen mittels

Beitrag von STARGÅTE »

Was genau hast du denn überhaupt vor ?
Was soll denn der Cosinus für eine Wirkung haben ?
Der mathematische Hintergrund ist eine Parametrisierung.

Ich gibt dir nun mal ein Beispiele, die den Punkt (x) von 100 nach 200 bewegen,
mit Hilfe der Zeit t von 0 bis 100 !
Also bei t=0 ist x = 100 genau! , bei t=100 ist x = 200 genau!, werte dazwischen haben andere Koordinaten.

Code: Alles auswählen

x = 150-Cos(#Pi*t/100)*50
So sehe das ganze aus (in 2D): (oben linear, unten cos)

Code: Alles auswählen

InitSprite()

IncludePath "C:\Includes\PureBasic"
 IncludeFile "Default.pbi"

xP = 800
yP = 600
xP2 = xP/2
yP2 = yP/2

OpenWindow(0, 0, 0, xP, yP, "SCREEN", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, xP, yP, 0, 0, 0)
 

Repeat
  Event = WindowEvent()
  t = (ElapsedMilliseconds()/20) % 100
  ClearScreen(0)
  StartDrawing(ScreenOutput())
    DrawingMode(1)
   
    Line(100,100,100,1,$808080)
    x1 = 100+t
    Circle(x1, 100, 10, $FFFFFF)
 
    Line(100,200,100,1,$808080)
    x2 = 150-Cos(#PI*t/100)*50
    Circle(x2, 200, 10, $FFFFFF)

  StopDrawing()
  FlipBuffers()
Until Event = #PB_Event_CloseWindow
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Schoppy
Beiträge: 9
Registriert: 28.03.2009 04:41

Re: Mesh von einem Punkt zum nächsten Punkt bewegen mittels

Beitrag von Schoppy »

Ich möchte ein Film Archiv schreiben welches das Coverflow Feature verwendet.

Hier mal mein Code dazu:

Engine ist Irrlicht

Code: Alles auswählen

;############################ STRUCTUREN #############################

Structure folderI
   DVDmesh_ID.l ;node
   name$
   
   pos_ist.l
   pos_soll.l
   
   angel_ist.f
   angel_soll.l
   
   zoom_ist.f
   
   xmove.f
   xl.f

   winkel.l 
   bogenmass.f
   x.l

EndStructure


;############################ ENGINE ################################
; Include files 
IncludePath "includes"   :   IncludeFile "n3xtD_PB.pbi"

;############################ VARIABELN #############################

Global Dim fnf.folderI(255)
Global max = 0

;---------


Global *app.l, Quit.l


Global bewegung = 0

Global anzahl_movies.l = 0
Global path$ = "E:\Movie Archiv\Cover\"

;settings
Global Camera_Z_pos.l = -250;-250
Global Cover_Scalierung_l = 20




Global Spacing.l = 100;abstand mittleres cover zu den schrägen
Global Spacing_move_wert.l = 6
; !!! Spacing ist begrenzt
; 100 = *6
; 200 = * 12
;hier noch formel finden



Global Zoom_MID_cover = 80 ; Zoom des Mittleren Covers
Global Angel.l = 55 ;Drehung der Schrägen Cover

Global Fall_Distanz.l = 20; ;abstand zwischen den Covern
Global move_geschwindigkeit.l = 2



Global rotate_berechnung.f =  Angel.l * move_geschwindigkeit.l / Fall_Distanz.l  ; berechne Synchonität zwischen Move und Rotate
Global zoom_berechnung.f = move_geschwindigkeit.l / Fall_Distanz.l * Zoom_MID_cover ; berechne zoom multiplikator

;############################ FUNCTIONEN #############################
Procedure pos_Cover_START(wegi) ;wird nur 1 mal aufgerufen am Start um alle cover zu platzieren

     For i = 0 To anzahl_movies.l-1 Step 1
   
     
     ;Lege neue Poitionen fest 
     fnf(i)\pos_ist.l = wegi + i * Fall_Distanz.l ;Überall ist der position Soll wert hibnterlegt
          
          
          
           ;Lege Rotation fest    
           If  fnf(i)\pos_ist.l = 0  
           fnf(i)\angel_ist.f =  0
           iPositionNode(fnf(i)\DVDmesh_ID.l,fnf(i)\pos_ist.l,0,0)
           EndIf 
           
           If  fnf(i)\pos_ist.l > 0 
           fnf(i)\angel_ist.f =  Angel.l
           iPositionNode(fnf(i)\DVDmesh_ID.l,fnf(i)\pos_ist.l+Spacing.l,0,0)
           EndIf 
           
           If  fnf(i)\pos_ist.l < 0  
           fnf(i)\angel_ist.f =  -Angel.l
           iPositionNode(fnf(i)\DVDmesh_ID.l,fnf(i)\pos_ist.l-Spacing.l,0,0)
           EndIf 

           
iRotateNode(fnf(i)\DVDmesh_ID.l,0, fnf(i)\angel_ist.f,0)



    
      Next    


EndProcedure



Procedure pos_update(wert) ;lege neue soll und ist werte fest

     For i = 0 To anzahl_movies.l-1 ;Step 1
   
        fnf(i)\pos_soll.l = wert + i * Fall_Distanz.l 
              
        
      ;fnf(i)\xmove=(fnf(i)\pos_soll.l - fnf(i)\pos_ist.l)/2 
      ;fnf(i)\xl=fnf(i)\pos_ist.l 
        
        
        
           If  fnf(i)\pos_soll.l = 0  
           fnf(i)\angel_soll.l =  0
           EndIf 
           
           If  fnf(i)\pos_soll.l > 0 
           fnf(i)\angel_soll.l =  Angel.l
           EndIf 
           
           If  fnf(i)\pos_soll.l < 0  
           fnf(i)\angel_soll.l =  -Angel.l
           EndIf 
       
     Next  
     

EndProcedure




;------ Antialliasing
iSetAntiAlias (1)  ; Schalte Anti Aliasing ein

;+++++++++++++++++++++++++++++++ Open Screen +++++++++++++++++++++++++++++++
 ;open n3xt-D screen ----> DirectX 9
*app=iCreateGraphics3D(1024,768, 32, #False, #True, #EDT_DIRECT3D9)
If *app= #Null
  End
EndIf




;############ LADE 3D ############

; DVD Hülle 1x Laden danach davon das Mesh erstellen
  Global *obj.IObject = iLoad3DObject("dvd_hülle.3DS")



;############ LADE 2D ############
;-----------------------------------
; load font png
iLoadFont("courriernew.png")
Global *font.IGUIFont = iGetFont()


 ;###################### LESE Cover Verzeichniss ein #####################

ExamineDirectory(0, path$, "*.*")
NextDirectoryEntry(0):NextDirectoryEntry(0)

While NextDirectoryEntry(0)

      If GetExtensionPart(DirectoryEntryName(0)) = "jpg"
           ; Speicher den jpg namen
           fnf(anzahl_movies.l)\name$ = DirectoryEntryName(0)
           
           ; Erstelle für jedes cover ein Mesh
           *DVD= iCreateMesh(*obj)
           fnf(anzahl_movies.l)\DVDmesh_ID.l = *DVD
           iScaleNode(*DVD,Cover_Scalierung_l,Cover_Scalierung_l,Cover_Scalierung_l)
           ;teile dem Mesh direkt das cover zu
           iLoadTextureNode(*DVD, path$ + fnf(anzahl_movies.l)\name$,1)  ; der letzte wert gibt den layer an 


           anzahl_movies.l + 1
           

      EndIf
   
Wend

max = anzahl_movies.l - 1

;##########################################################################


; create a camera und positioniere ein stück nach hinten
Define *cam.ICamera = iCreateCamera( )
iPositionNode(*cam, 0,0,Camera_Z_pos.l);-10)


pos_Cover_START(0) ; Um das Bild nach dem Laden und positionieren zu zeigen


; ------------------------------------------------------------------------------------------------------------------------------------------------------------
;           main loop
; ------------------------------------------------------------------------------------------------------------------------------------------------------------
Repeat

;Delay(100)
;**************** Schaffe eine glatte bewegung **********************************

If schalter_bewegung = 1

For i = 0 To anzahl_movies.l-1 Step 1


            If fnf(i)\pos_ist.l > fnf(i)\pos_soll.l
            
            ; M O V E          
           
       If fnf(i)\pos_soll.l < 0
            
            ;Spacing verarbeiten
            If fnf(i)\pos_soll.l = -Fall_Distanz.l ; geht von der Mitte
            If fnf(i)\angel_ist.f > -Angel.l
                 If Spacing.l > 0
                  If b = 0
                  fnf(i)\pos_ist.l + Spacing.l
                  ;fnf(i)\pos_soll.l + Spacing.l
                  b=1
                  EndIf
                 fnf(i)\pos_ist.l - move_geschwindigkeit.l * Spacing_move_wert.l
                 
             ;------ Zoom back MID Cover
             If fnf(i)\zoom_ist.f > 0
             fnf(i)\zoom_ist.f - zoom_berechnung.f
             ;Debug "wieder weg:  " + Str(fnf(i)\zoom_ist.f)
             EndIf
             ;---------------  
               
                Else
                  fnf(i)\pos_ist.l - move_geschwindigkeit.l            
                EndIf 

            EndIf     
            EndIf
            
  
            ;------------------
            fnf(i)\pos_ist.l - move_geschwindigkeit.l
            iPositionNode(fnf(i)\DVDmesh_ID.l,fnf(i)\pos_ist.l-Spacing.l,0,-fnf(i)\zoom_ist.f);Zoom_MID_Cover_ist.f)  

        EndIf 
            
                        
      
      
      
            If fnf(i)\pos_soll.l > 0
            fnf(i)\pos_ist.l - move_geschwindigkeit.l
            iPositionNode(fnf(i)\DVDmesh_ID.l,fnf(i)\pos_ist.l+Spacing.l,0,0)
            EndIf 
            
            
            
      
            If fnf(i)\pos_soll.l = 0 ; wird mittleres cover
            
            ;Spacing verarbeiten
                If Spacing.l > 0
                  If a = 0
                  fnf(i)\pos_ist.l + Spacing.l
                  a=1
                  EndIf
                  fnf(i)\pos_ist.l - move_geschwindigkeit.l * Spacing_move_wert.l
                Else
                  fnf(i)\pos_ist.l - move_geschwindigkeit.l            
                EndIf 
             ;------------------
             ;------ Zoom MID Cover
             If fnf(i)\zoom_ist.f < Zoom_MID_cover
             fnf(i)\zoom_ist.f +zoom_berechnung.f
             ;Debug "zur mitte:  " +Str( fnf(i)\zoom_ist.f)
             EndIf
             ;---------------
            
            iPositionNode(fnf(i)\DVDmesh_ID.l,fnf(i)\pos_ist.l,0,-fnf(i)\zoom_ist.f);Zoom_MID_cover)
            EndIf 
            
            

            
            
            
            
            ; R O T A T I O N
            
            If fnf(i)\pos_soll.l = 0  ; Mittleres Cover

               If fnf(i)\angel_soll.l = 0 
               If fnf(i)\angel_ist.f > 0
 
               fnf(i)\angel_ist.f -  rotate_berechnung.f   
               ;Debug fnf(i)\angel_ist.f
               
               EndIf 
               EndIf 
                           
            EndIf
            
            ;-------
            
            If fnf(i)\pos_soll.l < 0 ;linke Seite
            
                If fnf(i)\pos_soll.l = - Fall_Distanz.l
                ;Debug fnf(i)\name$
                If fnf(i)\angel_ist.f > -Angel.l
                
                fnf(i)\angel_ist.f - rotate_berechnung.f
                
                EndIf
                EndIf 
            
            EndIf 
            
            ;-------
  
            If fnf(i)\pos_soll.l > 0;rechte Seite
            
               If fnf(i)\pos_soll.l = Fall_Distanz.l
               If fnf(i)\angel_ist.f > Angel.l
               
               fnf(i)\angel_ist.f + rotate_berechnung.f
               
               EndIf
               EndIf
               

            EndIf 
  
            
            iRotateNode(fnf(i)\DVDmesh_ID.l,0, fnf(i)\angel_ist.f,0)
            

            
            EndIf ;------------------------------


Next




EndIf 
;********************************************************************************
 

  
  
   If iGetKeyDown(#KEY_ARROW_RIGHT)

    If start = 0
         
       schalter_bewegung = 1 ; Starte ablauf
       a = 0
       b = 0
       
       pos_update(bewegung - Fall_Distanz.l)
       
            
            
            If bewegung = (anzahl_movies.l - 1) * -Fall_Distanz.l 

            Else
               bewegung - Fall_Distanz.l  

            EndIf
            
            
            
            
     EndIf      
            start = 1
    EndIf 
  

  
  
  
 	; move camera with dir key and mouse (left click)
  If iGetKeyDown(#KEY_ARROW_UP)
  start = 0
  EndIf

	; if Escape Key, exit	
  If iGetKeyDown(#KEY_ESCAPE)
    Quit=1
  EndIf

  	

  	
; ---------------
;      Render
; ---------------
iBeginScene()
     iDrawScene()
     
     iDrawText(*font, Str(iFPS()),  10,10,0,0)

iEndScene()



Until Quit=1
; end
iFreeEngine()
Antworten