Ruotare un ottaedro in una DrawingArea: differenze tra le versioni

Da Gambas-it.org - Wikipedia.
Vai alla navigazione Vai alla ricerca
Nessun oggetto della modifica
Nessun oggetto della modifica
 
(Una versione intermedia di uno stesso utente non è mostrata)
Riga 115: Riga 115:
     Paint.Stroke                  <FONT Color=gray>' ''Esegue effettivamente il disegno''</font>
     Paint.Stroke                  <FONT Color=gray>' ''Esegue effettivamente il disegno''</font>
   Next
   Next
  Paint.End
   
   
  End
  End
Riga 125: Riga 123:
   Select Case Key.Code
   Select Case Key.Code
     Case Key["+"]
     Case Key["+"]
       Zoom += 50
       Zoom = Min(Zoom + 25, 1000)
      If Zoom > 1000 Then Zoom = 1000
     Case Key["-"]
     Case Key["-"]
       Zoom -= 50
       Zoom = Max(Zoom - 25, 25)
      If Zoom < 50 Then Zoom = 50
   End Select
   End Select
   
   

Versione attuale delle 18:44, 10 ago 2025

Mostreremo un possibile codice per disegnare e ruotare un Ottaedro intorno ai suoi assi X, Y e Z in una DrawingArea.

Nell'esempio che segue sarà possibile aumentare o diminuire la dimensione del disegno dell'Ottaedro, cliccando rispettivamente sui tasti "+" e "-" della tastiera.

' Variabili per l'angolo di rotazione:
Private angleX As Float
Private angleY As Float

' Fattore di zoom (valore più alto = oggetto più grande):
Private Zoom As Float = 150

' Array dinamici per i vertici e gli spigoli:
Private Vertices As Object[]
Private Edges As Object[]


Public Sub Form_Open()

 With Me
   .Title = "Ottaedro che ruota intorno ai suoi assi X, Y e Z"
   .Move(0, 0, Screen.AvailableWidth, Screen.AvailableHeight)
   .Arrangement = Arrange.Fill
 End With

 Vertices = New Object[]
 Edges = New Object[]

' Definizione dei 6 vertici dell'ottaedro (coordinate 3D):
 Vertices.Push([0, 0, 1])     ' Vertice superiore
 Vertices.Push([1, 0, 0])
 Vertices.Push([0, 1, 0])
 Vertices.Push([-1, 0, 0])
 Vertices.Push([0, -1, 0])
 Vertices.Push([0, 0, -1])    ' Vertice inferiore

' Definizione degli spigoli come coppie di indici dei vertici:
 Edges.Push([0, 1])
 Edges.Push([0, 2])
 Edges.Push([0, 3])
 Edges.Push([0, 4])
 Edges.Push([5, 1])
 Edges.Push([5, 2])
 Edges.Push([5, 3])
 Edges.Push([5, 4])
 Edges.Push([1, 2])
 Edges.Push([2, 3])
 Edges.Push([3, 4])
 Edges.Push([4, 1])

 Timer1.Delay = 16   ' ~60 FPS
 Timer1.Start

End


Public Sub Timer1_Timer()

 angleX += 0.03   ' Rotazione sull'asse X
 angleY += 0.02   ' Rotazione sull'asse Y
 DrawingArea1.Refresh

End


Public Sub DrawingArea1_Draw()

 Dim w As Integer = DrawingArea1.W
 Dim h As Integer = DrawingArea1.H
 Dim cx As Float = w / 2       ' Centro orizzontale
 Dim cy As Float = h / 2       ' Centro verticale
 Dim points As Object[] = New Object[]   ' Coordinate proiettate 2D

' Calcola la proiezione 2D per ogni vertice ruotato:
 For Each v As Float[] In Vertices
   Dim x, y, z As Float
   x = v[0]
   y = v[1]
   z = v[2]

' Rotazione attorno all'asse X:
   Dim y1 As Float = y * Cos(angleX) - z * Sin(angleX)
   Dim z1 As Float = y * Sin(angleX) + z * Cos(angleX)
   y = y1
   z = z1

' Rotazione attorno all'asse Y:
   Dim x1 As Float = x * Cos(angleY) + z * Sin(angleY)
   z1 = -x * Sin(angleY) + z * Cos(angleY)
   x = x1
   z = z1

' Evita divisioni per numeri troppo piccoli:
   If (z + 3) < 0.1 Then
     points.Push([cx, cy])   ' Coordinate "di sicurezza"
     Continue
   Endif

' Proiezione prospettica: oggetti più vicini appaiono più grandi:
   Dim scale As Float = Zoom / (z + 3)
   Dim sx As Float = cx + x * scale  ' Coordinata X sullo schermo
   Dim sy As Float = cy - y * scale  ' Coordinata Y sullo schermo

   points.Push([sx, sy])   ' Aggiunge punto proiettato all'elenco
 Next

' Imposta il colore per disegnare gli spigoli:
 Paint.Brush = Paint.Color(Color.Black)

' Disegna tutti gli spigoli dell’ottaedro:
 For Each e As Integer[] In Edges
   Dim p1 As Float[] = points[e[0]]
   Dim p2 As Float[] = points[e[1]]

   Paint.MoveTo(p1[0], p1[1])    ' Inizio linea
   Paint.LineTo(p2[0], p2[1])    ' Fine linea
   Paint.Stroke                  ' Esegue effettivamente il disegno
 Next

End


Public Sub Form_KeyPress()   ' Gestione della tastiera per controllare lo zoom

 Select Case Key.Code
   Case Key["+"]
     Zoom = Min(Zoom + 25, 1000)
   Case Key["-"]
     Zoom = Max(Zoom - 25, 25)
 End Select

 DrawingArea1.Refresh

End