Seite 3 von 4

Re: 3D Kugel aus einzelnen Quadraten erstellen

Verfasst: 02.02.2013 13:19
von Nino
Der Fachausdruck dafür heißt "Parkettierung". Vielleicht findest Du irgendwo im Internet etwas über Parkettierung einer Kugeloberfläche mit Vierecken. Das geht. Aber mit Quadraten geht's nicht ( auch wenn es sich 2-dimensional so darstellen lässt, als ob es ginge -- 2-dimensional kann man bekanntlich z.B. sogar einen Fluß darstellen, der im Kreis fleßt. :-) ).

Re: 3D Kugel aus einzelnen Quadraten erstellen

Verfasst: 02.02.2013 13:45
von Danilo
dige hat geschrieben:Scheint jedenfalls doch nicht so einfach zu sein, Vierecke
räumlich so anzuordnen, das sie eine Kugel ergeben.

Ich glaube mal irgendwo ein Beispiel einer Kugel aus
Punkten gesehen zu haben. Vielleicht kann man über
den Punkt im Raum die Lage für ein Viereck errechnen.
Mit ein bissl Sinus und Cosinus kannst Du doch einen Kreis berechnen, und eine 3D-Kugel
auf dem Bildschirm besteht auch nur aus solchen Kreisen. Einmal in XY-Richtung und einmal
für den Z-Wert.
Gibt bestimmt optimierte Berechnungen, aber das ist wohl am einfachsten zu verstehen.
Die letzten Punkte an den Polen sind dann halt nur Dreiecke.

Schau Dir mal das folgende Beispiel an und spiele mit den Schrittweite (Tasten F1/F2 und F3/F4): Wireframe-Kugel erstellen
Um so mehr Zwischenschritte, desto mehr sieht es wie eine Kugel aus.

EDIT:
Hier nochmal alle Codes meiner damaligen Serie, da es das PureBoard-Archiv nicht mehr gibt:

1.) Einen Kreis auf der Z-Achse zeichnen und alle Punkte mit einem Mittelpunkt verbinden. Ergibt einen Kegel.

Code: Alles auswählen

Procedure.f GSin(winkel.f)
   ProcedureReturn Sin(winkel*(2*3.14159265/360))
EndProcedure 
 
Procedure.f GCos(winkel.f) 
   ProcedureReturn Cos(winkel*(2*3.14159265/360))
EndProcedure 

;-----

#sw = 1280
#sh = 1024
#sn = "Sinus"

#hsw = #sw/2
#hsh = #sh/2


;
; fix for fullscreen multi monitor bug in PB DirectX9
;
; Fullscreen problem with dualscreen monitor:
; http://www.purebasic.fr/english/viewtopic.php?f=4&t=41281
;
CallFunction(OpenLibrary(#PB_Any,"dwmapi.dll"),"DwmEnableComposition",0)


If InitSprite()=0 Or InitKeyboard()=0
  MessageRequester("ERROR","Cant init game engine !"):End
EndIf

If OpenScreen(#sw,#sh,32,#sn)=0
  If OpenScreen(#sw,#sh,24,#sn)=0
    If OpenScreen(#sw,#sh,16,#sn)=0
      If OpenScreen(#sw,#sh,08,#sn)=0
        MessageRequester("ERROR","Cant open screen !"):End
EndIf:EndIf:EndIf:EndIf
 

Procedure Point3Dto2D(x.f,y.f,z.f,*pt.POINT)
  ;If x < 0.0 : x2.f = -0.9 : Else : x2.f = 0.9 : EndIf
  ;If y < 0.0 : y2.f = -0.9 : Else : y2.f = 0.9 : EndIf
;   z = -z
;   *pt\x = ((#hsw + x * #hsw)*0.998999)+z*#hsw
;   *pt\y = ((#hsh + y * #hsh))+z*#hsh
  z + 1
  proj.f = 500
  *pt\x = (x/z)*proj+#hsw
  *pt\y = (y/z)*-proj+#hsh
EndProcedure


Procedure Line3D(x1.f,y1.f,z1.f,x2.f,y2.f,z2.f,color)
  Point3Dto2D(x1,y1,z1,p1.POINT)
  Point3Dto2D(x2,y2,z2,p2.POINT)
  If color = -1
    LineXY(p1\x,p1\y,p2\x,p2\y)
  Else
    LineXY(p1\x,p1\y,p2\x,p2\y,color)
  EndIf
EndProcedure


If CreateSprite(1,500,500)=0
  CloseScreen()
  MessageRequester("ERROR","Cant create sprite !"):End
Else
  ;DrawCircle(3,0)
EndIf

schrittweite = 8

Repeat 
    ExamineKeyboard() 
    FlipBuffers()
    If IsScreenActive()
      ;ClearScreen (0, 0, 0)
      ClearScreen(0)


      If StartDrawing(ScreenOutput())
;         Line3D(-0.5,-0.5,z, 0.5,-0.5,z,$00FFFF)
;         Line3D(-0.5,-0.5,z,-0.5, 0.5,z,$00FFFF)
;         Line3D(-0.5, 0.5,z, 0.5, 0.5,z,$00FFFF)
;         Line3D( 0.5, 0.5,z, 0.5,-0.5,z,$00FFFF)
; 
;         Line3D(-0.5,-0.5,z-0.5, 0.5,-0.5,z-0.5,$00FFFF)
;         Line3D(-0.5,-0.5,z-0.5,-0.5, 0.5,z-0.5,$00FFFF)
;         Line3D(-0.5, 0.5,z-0.5, 0.5, 0.5,z-0.5,$00FFFF)
;         Line3D( 0.5, 0.5,z-0.5, 0.5,-0.5,z-0.5,$00FFFF)
; 
;         Line3D(-0.5,-0.5,z,-0.5,-0.5,z-0.5,$00FFFF)
;         Line3D( 0.5,-0.5,z, 0.5,-0.5,z-0.5,$00FFFF)
;         Line3D(-0.5, 0.5,z,-0.5, 0.5,z-0.5,$00FFFF)
;         Line3D( 0.5, 0.5,z, 0.5, 0.5,z-0.5,$00FFFF)

        Point3Dto2D(0.0,0.0,0.0,pt2.POINT)

        FrontColor(RGB($FF,$FF,$00))
        grad.f = 90.0
        Point3Dto2D(gSin(grad)*0.5,-0.7,0-GCos(grad)*0.08,pt.POINT)
        old_x = pt\x
        old_y = pt\y
        While grad =< 360+91
          Point3Dto2D(gSin(grad)*0.5,-0.7,0-GCos(grad)*0.08,pt.POINT)
          ;Plot(pt\x,pt\y)
          LineXY(pt\x,pt\y,pt2\x,pt2\y)
          LineXY(pt\x,pt\y,old_x,old_y)
          old_x = pt\x
          old_y = pt\y
          grad + 360/schrittweite
        Wend
        
        FrontColor(RGB(255, 255, 255)) 
        DrawingMode(1) 
        ;Locate(50,30)
        DrawText(50,30,"Schrittweite (F1/F2): " + Str(Schrittweite))
        StopDrawing()
      EndIf

      If KeyboardPushed(#PB_Key_F1) And keypressed = 0
        Schrittweite + 1
        keypressed = 5
      ElseIf KeyboardPushed(#PB_Key_F2) And keypressed = 0
        Schrittweite - 1
        If Schrittweite < 3 : Schrittweite = 3 : EndIf
        keypressed = 5
      EndIf
      If keypressed : keypressed - 1 : EndIf     

      ;Delay(20)

    EndIf
Until KeyboardPushed(#PB_Key_Escape)
2.) 2 Kreise auf der Z-Achse zeichnen und alle Punkte verbinden. Ergibt einen Zylinder.

Code: Alles auswählen

Procedure.f GSin(winkel.f)
   ProcedureReturn Sin(winkel*(2*3.14159265/360))
EndProcedure 
 
Procedure.f GCos(winkel.f) 
   ProcedureReturn Cos(winkel*(2*3.14159265/360))
EndProcedure 

;-----

#sw = 1024
#sh = 768
#sn = "Sinus"

#hsw = #sw/2
#hsh = #sh/2

If InitSprite()=0 Or InitKeyboard()=0
  MessageRequester("ERROR","Cant init game engine !"):End
EndIf

If OpenScreen(#sw,#sh,32,#sn)=0
  If OpenScreen(#sw,#sh,24,#sn)=0
    If OpenScreen(#sw,#sh,16,#sn)=0
      If OpenScreen(#sw,#sh,08,#sn)=0
        MessageRequester("ERROR","Cant open screen !"):End
EndIf:EndIf:EndIf:EndIf
 

Procedure Point3Dto2D(x.f,y.f,z.f,*pt.POINT)
  #proj = 200 ; gewöhnlich 100
  z + 1
  *pt\x = Round((x/z)* #proj+#hsw,1)
  *pt\y = Round((y/z)*-#proj+#hsh,1)
EndProcedure


Procedure Line3D(x1.f,y1.f,z1.f,x2.f,y2.f,z2.f,color)
  ; draw a line in 3D space
  Point3Dto2D(x1,y1,z1,p1.POINT)
  Point3Dto2D(x2,y2,z2,p2.POINT)
  If color = -1
    LineXY(p1\x,p1\y,p2\x,p2\y)
  Else
    LineXY(p1\x,p1\y,p2\x,p2\y,color)
  EndIf
EndProcedure

schrittweite = 5
z.f     = 0
obj_y.f = 0
obj_x.f = 0
obj_z.f = -0.5

Repeat 
    ExamineKeyboard() 
    FlipBuffers()
    If IsScreenActive()
      ClearScreen (0)

      If StartDrawing(ScreenOutput())
        FrontColor(RGB($FF,$FF,$00))
        grad.f = 90.0
        Point3Dto2D(obj_x+gSin(grad)*0.5,obj_y+0.5,(obj_z+0-GCos(grad)*0.1),pt.POINT)
        old_x1 = pt\x : old_y1 = pt\y
        Point3Dto2D(obj_x+gSin(grad)*0.5,obj_y-0.5,(obj_z-0-GCos(grad)*0.1),pt.POINT)
        old_x2 = pt\x : old_y2 = pt\y
        While grad =< 360+90+360/schrittweite
          Point3Dto2D(obj_x+gSin(grad)*0.5,obj_y+0.5,(obj_z+0-GCos(grad)*0.1),pt.POINT )
          Point3Dto2D(obj_x+gSin(grad)*0.5,obj_y-0.5,(obj_z-0-GCos(grad)*0.1),pt2.POINT)
          LineXY(pt\x ,pt\y ,pt2\x ,pt2\y )
          LineXY(pt\x ,pt\y ,old_x1,old_y1)
          LineXY(pt2\x,pt2\y,old_x2,old_y2)
          old_x1 = pt\x  : old_y1 = pt\y
          old_x2 = pt2\x : old_y2 = pt2\y
          grad + 360/schrittweite
        Wend
        
        FrontColor(RGB(255, 255, 255)) 
        DrawingMode(1) 
        DrawText(50,30, "Schrittweite (F1/F2): " + Str(Schrittweite))
        DrawText(50,50, "Cursor Keys left/right & up/down to move object")
        DrawText(50,70, "Keypad +/- to z00m object")
        StopDrawing()
      EndIf

      If KeyboardPushed(#PB_Key_F1) And keypressed = 0
        Schrittweite + 1
        keypressed = 5
      ElseIf KeyboardPushed(#PB_Key_F2) And keypressed = 0
        Schrittweite - 1
        If Schrittweite < 3 : Schrittweite = 3 : EndIf
        keypressed = 5
      ElseIf KeyboardPushed(#PB_Key_Up)
        obj_y + 0.01
      ElseIf KeyboardPushed(#PB_Key_Down)
        obj_y - 0.01
      ElseIf KeyboardPushed(#PB_Key_Left)
        obj_x - 0.01
      ElseIf KeyboardPushed(#PB_Key_Right)
        obj_x + 0.01
      ElseIf KeyboardPushed(#PB_Key_Add)      ; keypad +
        obj_z - 0.01
      ElseIf KeyboardPushed(#PB_Key_Subtract) ; keypad -
        obj_z + 0.01
      EndIf
      If keypressed : keypressed - 1 : EndIf     

      Delay(10)

    EndIf
Until KeyboardPushed(#PB_Key_Escape)
3.) Nun das ganze mit 3 Kreisen auf der Z-Achse:

Code: Alles auswählen

Procedure.f GSin(winkel.f)
   ProcedureReturn Sin(winkel*(2*3.14159265/360))
EndProcedure 
 
Procedure.f GCos(winkel.f) 
   ProcedureReturn Cos(winkel*(2*3.14159265/360))
EndProcedure 

;-----

#sw = 1024
#sh = 768
#sn = "Sinus"

#hsw = #sw/2
#hsh = #sh/2

If InitSprite()=0 Or InitKeyboard()=0
  MessageRequester("ERROR","Cant init game engine !"):End
EndIf

If OpenScreen(#sw,#sh,32,#sn)=0
  If OpenScreen(#sw,#sh,24,#sn)=0
    If OpenScreen(#sw,#sh,16,#sn)=0
      If OpenScreen(#sw,#sh,08,#sn)=0
        MessageRequester("ERROR","Cant open screen !"):End
EndIf:EndIf:EndIf:EndIf
 

Procedure Point3Dto2D(x.f,y.f,z.f,*pt.POINT)
  #proj = 400 ; gewöhnlich 100
  z + 1
  *pt\x = Round((x/z)* #proj+#hsw,1)
  *pt\y = Round((y/z)*-#proj+#hsh,1)
EndProcedure


Procedure Line3D(x1.f,y1.f,z1.f,x2.f,y2.f,z2.f,color)
  ; draw a line in 3D space
  Point3Dto2D(x1,y1,z1,p1.POINT)
  Point3Dto2D(x2,y2,z2,p2.POINT)
  If color = -1
    LineXY(p1\x,p1\y,p2\x,p2\y)
  Else
    LineXY(p1\x,p1\y,p2\x,p2\y,color)
  EndIf
EndProcedure

schrittweite = 20
z.f     = 0
obj_y.f = 0
obj_x.f = 0
obj_z.f = -0.1

Repeat 
    ExamineKeyboard() 
    FlipBuffers()
    If IsScreenActive()
      ClearScreen(0)

      If StartDrawing(ScreenOutput())
        FrontColor(RGB($FF,$FF,$00))
        grad.f = 90.0
        Point3Dto2D(obj_x+gSin(grad)*0.3,obj_y+0.3,(obj_z+0-GCos(grad)*0.1),pt.POINT)
        old_x1 = pt\x : old_y1 = pt\y
        Point3Dto2D(obj_x+gSin(grad)*0.5,obj_y    ,(obj_z-0-GCos(grad)*0.1),pt.POINT)
        old_x2 = pt\x : old_y2 = pt\y
        Point3Dto2D(obj_x+gSin(grad)*0.3,obj_y-0.3,(obj_z-0-GCos(grad)*0.1),pt.POINT)
        old_x3 = pt\x : old_y3 = pt\y
        While grad =< 360+90+360/schrittweite
          Point3Dto2D(obj_x+gSin(grad)*0.3,obj_y+0.3,(obj_z+0-GCos(grad)*0.1),pt.POINT )
          Point3Dto2D(obj_x+gSin(grad)*0.5,obj_y    ,(obj_z-0-GCos(grad)*0.1),pt2.POINT)
          Point3Dto2D(obj_x+gSin(grad)*0.3,obj_y-0.3,(obj_z-0-GCos(grad)*0.1),pt3.POINT)
          LineXY(pt\x  ,pt\y  ,pt2\x ,pt2\y )
          LineXY(pt3\x ,pt3\y ,pt2\x ,pt2\y )
          LineXY(pt\x ,pt\y ,old_x1,old_y1)
          LineXY(pt2\x,pt2\y,old_x2,old_y2)
          LineXY(pt3\x,pt3\y,old_x3,old_y3)
          old_x1 = pt\x  : old_y1 = pt\y
          old_x2 = pt2\x : old_y2 = pt2\y
          old_x3 = pt3\x : old_y3 = pt3\y
          grad + 360/schrittweite
        Wend
        
        FrontColor(RGB(255, 255, 255))
        DrawingMode(1) 
        DrawText(50,30, "Schrittweite (F1/F2): " + Str(Schrittweite))
        DrawText(50,50, "Cursor Keys left/right & up/down to move object")
        DrawText(50,70, "Keypad +/- to z00m object")
        StopDrawing()
      EndIf

      If KeyboardPushed(#PB_Key_F1) And keypressed = 0
        Schrittweite + 1
        keypressed = 5
      ElseIf KeyboardPushed(#PB_Key_F2) And keypressed = 0
        Schrittweite - 1
        If Schrittweite < 3 : Schrittweite = 3 : EndIf
        keypressed = 5
      ElseIf KeyboardPushed(#PB_Key_Up)
        obj_y + 0.01
      ElseIf KeyboardPushed(#PB_Key_Down)
        obj_y - 0.01
      ElseIf KeyboardPushed(#PB_KEY_LEFT)
        obj_x - 0.01
      ElseIf KeyboardPushed(#PB_KEY_RIGHT)
        obj_x + 0.01
      ElseIf KeyboardPushed(#PB_KEY_ADD)      ; keypad +
        obj_z - 0.01
      ElseIf KeyboardPushed(#PB_KEY_SUBTRACT) ; keypad -
        obj_z + 0.01
      EndIf
      If keypressed : keypressed - 1 : EndIf     

      Delay(10)

    EndIf
Until KeyboardPushed(#PB_Key_Escape)
4.) Nochmal mit 3D Kreisen. Zusätzlich verbinden wir die Pole, es entstehen dort Dreiecke.

Code: Alles auswählen

Procedure.f GSin(winkel.f)
   ProcedureReturn Sin(winkel*(2*3.14159265/360))
EndProcedure 
 
Procedure.f GCos(winkel.f) 
   ProcedureReturn Cos(winkel*(2*3.14159265/360))
EndProcedure 

;-----

#sw = 1024
#sh = 768
#sn = "Sinus"

#hsw = #sw/2
#hsh = #sh/2

If InitSprite()=0 Or InitKeyboard()=0
  MessageRequester("ERROR","Cant init game engine !"):End
EndIf

If OpenScreen(#sw,#sh,32,#sn)=0
  If OpenScreen(#sw,#sh,24,#sn)=0
    If OpenScreen(#sw,#sh,16,#sn)=0
      If OpenScreen(#sw,#sh,08,#sn)=0
        MessageRequester("ERROR","Cant open screen !"):End
EndIf:EndIf:EndIf:EndIf
 

Procedure Point3Dto2D(x.f,y.f,z.f,*pt.POINT)
  #proj = 400 ; gewöhnlich 100
  z + 1
  *pt\x = Round((x/z)* #proj+#hsw,1)
  *pt\y = Round((y/z)*-#proj+#hsh,1)
EndProcedure


Procedure Line3D(x1.f,y1.f,z1.f,x2.f,y2.f,z2.f,color)
  ; draw a line in 3D space
  Point3Dto2D(x1,y1,z1,p1.POINT)
  Point3Dto2D(x2,y2,z2,p2.POINT)
  If color = -1
    LineXY(p1\x,p1\y,p2\x,p2\y)
  Else
    LineXY(p1\x,p1\y,p2\x,p2\y,color)
  EndIf
EndProcedure

schrittweite = 20
z.f     = 0
obj_y.f = 0
obj_x.f = 0
obj_z.f = -0.1

Repeat 
    ExamineKeyboard() 
    FlipBuffers()
    If IsScreenActive()
      ClearScreen(0)

      If StartDrawing(ScreenOutput())
        FrontColor(RGB($FF,$FF,$00))
        grad.f = 90.0
        Point3Dto2D(obj_x+gSin(grad)*0.3,obj_y+0.3,(obj_z+0-GCos(grad)*0.1),pt.POINT)
        old_x1 = pt\x : old_y1 = pt\y
        Point3Dto2D(obj_x+gSin(grad)*0.5,obj_y    ,(obj_z-0-GCos(grad)*0.1),pt.POINT)
        old_x2 = pt\x : old_y2 = pt\y
        Point3Dto2D(obj_x+gSin(grad)*0.3,obj_y-0.3,(obj_z-0-GCos(grad)*0.1),pt.POINT)
        old_x3 = pt\x : old_y3 = pt\y
        Point3Dto2D(obj_x,obj_y+0.4,obj_z,m1.POINT)
        Point3Dto2D(obj_x,obj_y-0.4,obj_z,m2.POINT)
        While grad =< 360+90+360/schrittweite
          Point3Dto2D(obj_x+gSin(grad)*0.3,obj_y+0.3,(obj_z+0-GCos(grad)*0.1),pt.POINT )
          Point3Dto2D(obj_x+gSin(grad)*0.5,obj_y    ,(obj_z-0-GCos(grad)*0.1),pt2.POINT)
          Point3Dto2D(obj_x+gSin(grad)*0.3,obj_y-0.3,(obj_z-0-GCos(grad)*0.1),pt3.POINT)
          LineXY(pt\x  ,pt\y  ,pt2\x ,pt2\y )
          LineXY(pt3\x ,pt3\y ,pt2\x ,pt2\y )
          LineXY(pt\x  ,pt\y  ,m1\x  ,m1\y )
          LineXY(pt3\x ,pt3\y ,m2\x  ,m2\y )
          LineXY(pt\x ,pt\y ,old_x1,old_y1)
          LineXY(pt2\x,pt2\y,old_x2,old_y2)
          LineXY(pt3\x,pt3\y,old_x3,old_y3)
          old_x1 = pt\x  : old_y1 = pt\y
          old_x2 = pt2\x : old_y2 = pt2\y
          old_x3 = pt3\x : old_y3 = pt3\y
          grad + 360/schrittweite
        Wend
        
        FrontColor(RGB(255, 255, 255)) 
        DrawingMode(1) 
        DrawText(50,30, "Schrittweite (F1/F2): " + Str(Schrittweite))
        DrawText(50,50, "Cursor Keys left/right & up/down to move object")
        DrawText(50,70, "Keypad +/- to z00m object")
        StopDrawing()
      EndIf

      If KeyboardPushed(#PB_Key_F1) And keypressed = 0
        Schrittweite + 1
        keypressed = 5
      ElseIf KeyboardPushed(#PB_Key_F2) And keypressed = 0
        Schrittweite - 1
        If Schrittweite < 3 : Schrittweite = 3 : EndIf
        keypressed = 5
      ElseIf KeyboardPushed(#PB_Key_Up)
        obj_y + 0.01
      ElseIf KeyboardPushed(#PB_Key_Down)
        obj_y - 0.01
      ElseIf KeyboardPushed(#PB_Key_Left)
        obj_x - 0.01
      ElseIf KeyboardPushed(#PB_Key_Right)
        obj_x + 0.01
      ElseIf KeyboardPushed(#PB_Key_Add)      ; keypad +
        obj_z - 0.01
      ElseIf KeyboardPushed(#PB_Key_Subtract) ; keypad -
        obj_z + 0.01
      EndIf
      If keypressed : keypressed - 1 : EndIf     

      Delay(10)

    EndIf
Until KeyboardPushed(#PB_Key_Escape)
5.) Als letztes mit beliebig vielen Kreisen auf der Z-Achse:

Code: Alles auswählen

Procedure.f GSin(winkel.f)
   ProcedureReturn Sin(winkel*(2*3.14159265/360))
EndProcedure
 
Procedure.f GCos(winkel.f)
   ProcedureReturn Cos(winkel*(2*3.14159265/360))
EndProcedure

;-----
CompilerIf #PB_Compiler_OS <> #PB_OS_Windows
   Structure POINT
     x.l
     y.l
   EndStructure
CompilerEndIf


#sw = 1024
#sh = 768
#sn = "Sinus"

#hsw = #sw/2
#hsh = #sh/2

If InitSprite()=0 Or InitKeyboard()=0
  MessageRequester("ERROR","Cant init game engine !"):End
EndIf

If OpenScreen(#sw,#sh,32,#sn)=0
  If OpenScreen(#sw,#sh,24,#sn)=0
    If OpenScreen(#sw,#sh,16,#sn)=0
      If OpenScreen(#sw,#sh,08,#sn)=0
        MessageRequester("ERROR","Cant open screen !"):End
EndIf:EndIf:EndIf:EndIf
 

Procedure Point3Dto2D(x.f,y.f,z.f,*pt.POINT)
  #proj = 400 ; gewoehnlich 100
  z + 1
  *pt\x = Round((x/z)* #proj+#hsw,1)
  *pt\y = Round((y/z)*-#proj+#hsh,1)
EndProcedure


Procedure Line3D(x1.f,y1.f,z1.f,x2.f,y2.f,z2.f,color)
  ; draw a line in 3D space
  Point3Dto2D(x1,y1,z1,p1.POINT)
  Point3Dto2D(x2,y2,z2,p2.POINT)
  If color = -1
    LineXY(p1\x,p1\y,p2\x,p2\y)
  Else
    LineXY(p1\x,p1\y,p2\x,p2\y,color)
  EndIf
EndProcedure

Procedure DrawObject(Radius.f,schrittweite1,schrittweite2,obj_x.f,obj_y.f,obj_z.f)
  If Schrittweite1 < 3 : Schrittweite1 = 3 : EndIf
  If Schrittweite2 < 1 : Schrittweite2 = 1 : EndIf
  gradschritte.f = 90.0 / Schrittweite2
  sincos.f    = 90.0
  For i = 1 To schrittweite2
    grad.f = 90.0
    Point3Dto2D(obj_x+gSin(grad)*(Radius*GSin(sincos)), obj_y-Radius*GCos(sincos), (obj_z+0-(Radius*GSin(sincos))*GCos(grad)*0.1), pt1.POINT)
    Point3Dto2D(obj_x+gSin(grad)*(Radius*GSin(sincos)), obj_y+Radius*GCos(sincos), (obj_z+0-(Radius*GSin(sincos))*GCos(grad)*0.1), pt2.POINT)
    old_x1 = pt1\x : old_y1 = pt1\y
    old_x2 = pt2\x : old_y2 = pt2\y
    While grad =< 360+90+360/schrittweite1
      Point3Dto2D(obj_x+gSin(grad)*(Radius*GSin(sincos)), obj_y-Radius*GCos(sincos), (obj_z+0-(Radius*GSin(sincos))*GCos(grad)*0.1), pt1.POINT )
      Point3Dto2D(obj_x+gSin(grad)*(Radius*GSin(sincos)), obj_y+Radius*GCos(sincos), (obj_z+0-(Radius*GSin(sincos))*GCos(grad)*0.1), pt2.POINT )
      If i = schrittweite2
        Point3Dto2D(obj_x,obj_y+Radius,obj_z,m1.POINT)
        Point3Dto2D(obj_x,obj_y-Radius,obj_z,m2.POINT)
        LineXY(pt1\x  ,pt1\y  ,m1\x  ,m1\y )
        LineXY(pt2\x  ,pt2\y  ,m2\x  ,m2\y )
      EndIf
      LineXY(pt1\x ,pt1\y ,old_x1,old_y1)
      If i>1
        LineXY(pt2\x ,pt2\y ,old_x2,old_y2)

        Point3Dto2D(obj_x+gSin(grad)*(Radius*GSin(sincos-gradschritte)), obj_y-Radius*GCos(sincos-gradschritte), (obj_z+0-(Radius*GSin(sincos-gradschritte))*GCos(grad)*0.1), pt3.POINT )
        LineXY(pt1\x,pt1\y,pt3\x,pt3\y)
        Point3Dto2D(obj_x+gSin(grad)*(Radius*GSin(sincos-gradschritte)), obj_y+Radius*GCos(sincos-gradschritte), (obj_z+0-(Radius*GSin(sincos-gradschritte))*GCos(grad)*0.1), pt4.POINT )
        LineXY(pt2\x,pt2\y,pt4\x,pt4\y)
      EndIf
      old_x1 = pt1\x  : old_y1 = pt1\y
      old_x2 = pt2\x  : old_y2 = pt2\y
      grad + 360/schrittweite1
    Wend
    sincos + gradschritte
    doit = 1
  Next i
EndProcedure

schrittweite1 = 25
schrittweite2 = 8
z.f     = 0
obj_y.f = 0
obj_x.f = 0
obj_z.f = -0.1

Repeat
    ExamineKeyboard()
    FlipBuffers()
    If IsScreenActive()
      ClearScreen (RGB(0,0,0))

      If StartDrawing(ScreenOutput())
        FrontColor(RGB($FF,$FF,$00))
        DrawObject(0.7,Schrittweite1,Schrittweite2,obj_x,obj_y,obj_z)
       
        FrontColor(RGB(255,255,255))
        DrawingMode(1)
        DrawText(50,30,"Schrittweite 1 (F1/F2): " + Str(Schrittweite1))
        DrawText(50,50,"Schrittweite 2 (F3/F4): " + Str(Schrittweite2))
        DrawText(50,80,"Cursor Keys left/right & up/down to move object")
        DrawText(50,100,"Keypad +/- to z00m object")
        StopDrawing()
      EndIf

      If KeyboardPushed(#PB_Key_F1) And keypressed = 0
        Schrittweite1 + 1
        keypressed = 5
      ElseIf KeyboardPushed(#PB_Key_F2) And keypressed = 0
        Schrittweite1 - 1
        If Schrittweite1 < 3 : Schrittweite1 = 3 : EndIf
        keypressed = 5
      ElseIf KeyboardPushed(#PB_Key_F3) And keypressed = 0
        Schrittweite2 + 1
        keypressed = 5
      ElseIf KeyboardPushed(#PB_Key_F4) And keypressed = 0
        Schrittweite2 - 1
        If Schrittweite2 < 1 : Schrittweite2 = 1 : EndIf
        keypressed = 5
      ElseIf KeyboardPushed(#PB_Key_Up)
        obj_y + 0.01
      ElseIf KeyboardPushed(#PB_Key_Down)
        obj_y - 0.01
      ElseIf KeyboardPushed(#PB_Key_Left)
        obj_x - 0.01
      ElseIf KeyboardPushed(#PB_Key_Right)
        obj_x + 0.01
      ElseIf KeyboardPushed(#PB_Key_Add)      ; keypad +
        obj_z - 0.01
      ElseIf KeyboardPushed(#PB_Key_Subtract) ; keypad -
        obj_z + 0.01
      EndIf
      If keypressed : keypressed - 1 : EndIf     

      Delay(10)

    EndIf
Until KeyboardPushed(#PB_Key_Escape)

Re: 3D Kugel aus einzelnen Quadraten erstellen

Verfasst: 02.02.2013 14:14
von STARGÅTE
So, nun melde ich mich noch mal.
Es gibt genau 5 möglichkeiten, aus regelmäßigen Flächen eine "Kugel" zu bauen, und dass sind die platonischen Körper:
Bild

Dort hat man also bis zu 20 Flächen/Ecken, die alle zueinander den gleichen Abstand und Größe haben.

Natürlich kann man nun weiter gehen und "Ecken eindrücken" und erhält so weitere Flächen, aber diese sind dann nie wieder alle gleich.

@dige: Du hast halt immer noch nicht gesagt was du willst, ist es ok, wenn die Vierecke in den Polen zu vielen Dreiecken werden?
Ist es ok, wenn alles Quadrate sind, und sich damit überschneiden?
Was ist wenn die Texturen nicht zu lesen sind, weil es gedreht wurde?

Re: 3D Kugel aus einzelnen Quadraten erstellen

Verfasst: 02.02.2013 14:17
von DarkDragon
Also hier mal meine vorgeschlagene Lösung auf die schnelle zusammengekugelt - äh - gewürfelt (Haha .. was für'n Wortwitz):

Code: Alles auswählen

InitEngine3D()
InitSprite()
InitKeyboard()
InitMouse()

OpenWindow(0, 0, 0, 1024, 768, "")
OpenWindowedScreen(WindowID(0), 0, 0, 1024, 768)

; Testtextur generieren
CreateTexture(0, 512, 512)

Define bx.i, by.i

StartDrawing(TextureOutput(0))
For bx = 0 To OutputWidth() - 1 Step 32
  For by = 0 To OutputHeight() - 1 Step 32
    DrawingMode(#PB_2DDrawing_Default)
    Box(bx, by, 32, 32, RGB(bx * 255 / OutputWidth(), 255, by * 255 / OutputHeight()))
    DrawingMode(#PB_2DDrawing_Outlined)
    Box(bx, by, 32, 32, RGB(255, 0, 0))
  Next by
Next bx
StopDrawing()

; Material erstellen
CreateMaterial(0, TextureID(0))

; Kugel erstellen
CreateSphere(0, 1.0, 32, 32)
CreateEntity(0, MeshID(0), MaterialID(0))

; Kamera erstellen
CreateCamera(0, 0, 0, 100, 100)
MoveCamera(0, 0, 0, 5.0)

; Licht erstellen
CreateLight(0, RGB(255, 255, 255), 0.0, 1.0, -3.0)

Define x.d, y.d

Repeat
  ExamineMouse()
  x + MouseDeltaX() * 0.001
  y + MouseDeltaY() * 0.001
  
  ScrollMaterial(0, x, y, #PB_Material_Fixed)
  
  ClearScreen(0)
  RenderWorld()
  FlipBuffers()
  
  ExamineKeyboard()
Until KeyboardPushed(#PB_Key_Escape) Or WindowEvent() = #PB_Event_CloseWindow
End
Die Bilder müssten dann halt in eine Textur rein.

Re: 3D Kugel aus einzelnen Quadraten erstellen

Verfasst: 02.02.2013 14:25
von STARGÅTE
@DarkDragon:

Na so hab ich mir das Ding was dige haben will überhaupt nicht vorgestellt.
Aber ok, das ist natürlich eine mögliche Lösung.
So ist die vordere Texture immer gleich, weil du das Material drehst und nicht die "Drahtkugel".

Re: 3D Kugel aus einzelnen Quadraten erstellen

Verfasst: 02.02.2013 16:17
von NicTheQuick
Wieso stürzt unter Linux eigentlich immer noch das Executable ab, wenn da irgendwo 3D verwendet wird?

Re: 3D Kugel aus einzelnen Quadraten erstellen

Verfasst: 02.02.2013 16:54
von DarkDragon
STARGÅTE hat geschrieben:So ist die vordere Texture immer gleich
Ja, aber nicht bei Rotation um die Y Achse.

@NicTheQuick: Keine Ahnung, ich habe schon einige Zeit kein Desktop-Linux am laufen (wollte ich mal wieder ändern, aber mir fehlt die Zeit). Was sagt denn das Log?

Re: 3D Kugel aus einzelnen Quadraten erstellen

Verfasst: 02.02.2013 19:56
von dige
@Stargate:
Bild
Bild

Das Bild ist vermutlich eine Kugel mit einer Bild Index Textur.
Mir schwebt aber vor, jedes Bild als separates Objekt zu zeichnen,
so das Zwischenraum zwischen den Bildern bleibt.

Das Bild das räumlich gesehen am nächsten zur
Bildschirmfläche gelegen ist soll vergrößert dargestellt
werden und dem Nutzer als aktuell auswählbares
Bild angezeigt werden.

Wenn jedes Viereck ein Objekt ist, können immer
wieder Bilder nachgeladen werden, je nach Richtung
in die die Kugel gedreht wird. Und somit kann durch
riesige Bildbestände navigiert werden.

Deshalb ist das Texturscrolling vermutlich keine Variante...

Re: 3D Kugel aus einzelnen Quadraten erstellen

Verfasst: 02.02.2013 20:01
von STARGÅTE
Oke, damit lässt es sich schon mal arbeiten.
Aber was ist nun wenn man den Ball nicht nach links/rechts dreht, sondern nach oben/unten, "welche" Bilder sollen dann nachgeladen werden?

Natürlich kann man ein "unendlich" ausgedehntes Raster in einem ausschnitt so krümmen, dass es wie eine Kugel aussieht, dass ist vermutlich das, was du willst.
Einfach ein Raster von Bilder, wo ich in alle Seiten scrollen kann, nur dass dieses Raster halt im lokalen Bereich gekrümmt ist.
Richtig?

Re: 3D Kugel aus einzelnen Quadraten erstellen

Verfasst: 02.02.2013 20:04
von dige
Das nachladen ist erstmal sekundär. Mich interessiert ersteinmal
ob es bspw. mit Sprite3D möglich ist die Bilder in Form
einer Kugel anzuordnen.

Das mit dem Raster und der Krümmung verstehe ich leider nicht :-/