Ruotare un cubo 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
Riga 1: Riga 1:
==Rotazione di un cubo intorno al suo asse Y==
==Rotazione di un cubo intorno al suo asse Y==
Mostriamo di seguito un possibile codice per ruotare un cubo in 3D intorno al suo asse Y in una ''DrawingArea''.
Mostriamo di seguito un possibile codice per ruotare un Cubo in 3D intorno al suo asse Y in una ''DrawingArea''.
  <FONT Color=gray>' ''=== Variabile per l’angolo di rotazione attorno all’asse Y ===''</font>
 
Nell'esempio che segue sarà possibile aumentare o diminuire la dimensione del disegno del Cubo, cliccando rispettivamente sui tasti "+" e "-" della tastiera.  
  <FONT Color=gray>' ''Variabile per l’angolo di rotazione attorno all’asse Y:''</font>
  Private angleY As Float
  Private angleY As Float
<FONT Color=gray>' ''Fattore di zoom (valore più alto = oggetto più grande):''</font>
Private Zoom As Float = 150
   
   
   
   
Riga 111: Riga 115:
   
   
  <FONT Color=gray>' ''Trasla al centro della DrawingArea e scala:''</font>
  <FONT Color=gray>' ''Trasla al centro della DrawingArea e scala:''</font>
   Return New PointF(cx + x2D * 100, cy - y2D * 100)
   Return New PointF(cx + x2D * Zoom, cy - y2D * Zoom)
   
   
  End
  End
Riga 122: Riga 126:
   Paint.LineTo(points[i2].X, points[i2].Y)  <FONT Color=gray>' ''Punto finale''</font>
   Paint.LineTo(points[i2].X, points[i2].Y)  <FONT Color=gray>' ''Punto finale''</font>
   Paint.Stroke()                            <FONT Color=gray>' ''Esegue il disegno della linea''</font>
   Paint.Stroke()                            <FONT Color=gray>' ''Esegue il disegno della linea''</font>
End
Public Sub Form_KeyPress()  <FONT Color=gray>' ''Gestione della tastiera per controllare lo zoom''</font>
Select Case Key.Code
  Case Key["+"]
    Zoom = Min(Zoom + 25, 1000)
  Case Key["-"]
    Zoom = Max(Zoom - 25, 25)
End Select
DrawingArea1.Refresh
   
   
  End
  End
Riga 127: Riga 145:


==Rotazione di un cubo intorno ai suoi assi X, Y e Z==
==Rotazione di un cubo intorno ai suoi assi X, Y e Z==
  <FONT Color=gray>' ''===Variabili per gli angoli di rotazione su X, Y e Z ===''</font>
  <FONT Color=gray>' ''Variabili per gli angoli di rotazione su X, Y e Z:''</font>
  Private angleX As Float
  Private angleX As Float
  Private angleY As Float
  Private angleY As Float
  Private angleZ As Float
  Private angleZ As Float
<FONT Color=gray>' ''Fattore di zoom (valore più alto = oggetto più grande):''</font>
Private Zoom As Float = 150
   
   
   
   
Riga 172: Riga 192:
   Dim az As Float = Rad(angleZ)
   Dim az As Float = Rad(angleZ)
   
   
  === Vertici 3D del cubo ===
  <FONT Color=gray>' ''=== Vertici 3D del cubo ===''</font>
   Dim vertices As New Float[][8]
   Dim vertices As New Float[][8]
   vertices[0] = [-size, -size, -size]
   vertices[0] = [-size, -size, -size]
Riga 286: Riga 306:
   Dim y2D As Float = y * factor
   Dim y2D As Float = y * factor
   
   
   Return New PointF(cx + x2D * 100, cy - y2D * 100)
   Return New PointF(cx + x2D * Zoom, cy - y2D * Zoom)
   
   
  End
  End
Riga 292: Riga 312:
   
   
  <FONT Color=gray>' ''=== Disegna una linea tra due punti proiettati ===''</font>
  <FONT Color=gray>' ''=== Disegna una linea tra due punti proiettati ===''</font>
  Private Procedure DrawEdge(points As PointF[], i1 As Integer, i2 As Integer)''</font>
  Private Procedure DrawEdge(points As PointF[], i1 As Integer, i2 As Integer)
   
   
   Paint.MoveTo(points[i1].X, points[i1].Y)
   Paint.MoveTo(points[i1].X, points[i1].Y)
   Paint.LineTo(points[i2].X, points[i2].Y)
   Paint.LineTo(points[i2].X, points[i2].Y)
   Paint.Stroke()
   Paint.Stroke()
End
Public Sub Form_KeyPress()  <FONT Color=gray>' ''Gestione della tastiera per controllare lo zoom''</font>
Select Case Key.Code
  Case Key["+"]
    Zoom = Min(Zoom + 25, 1000)
  Case Key["-"]
    Zoom = Max(Zoom - 25, 25)
End Select
DrawingArea1.Refresh
   
   
  End
  End

Versione delle 13:20, 21 lug 2025

Rotazione di un cubo intorno al suo asse Y

Mostriamo di seguito un possibile codice per ruotare un Cubo in 3D intorno al suo asse Y in una DrawingArea.

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

' Variabile per l’angolo di rotazione attorno all’asse Y:
Private angleY As Float
' Fattore di zoom (valore più alto = oggetto più grande):
Private Zoom As Float = 150


Public Sub Form_Open()

 With Me
   .Title = "Cubo che ruota intorno al suo asse Y"
   .Move(0, 0, Screen.AvailableWidth, Screen.AvailableHeight)
   .Arrangement = Arrange.Fill
 End With

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

End


Public Sub Timer1_Timer()

 angleY += 2            ' Incrementa la rotazione Y (in gradi)
 DrawingArea1.Refresh    ' Richiede il ridisegno della scena

End


Public Sub DrawingArea1_Draw()

' === Centro dello schermo ===
 Dim cx As Float = DrawingArea1.Width / 2
 Dim cy As Float = DrawingArea1.Height / 2

' === Parametri del cubo ===
 Dim size As Float = 1.0         ' Metà lato del cubo (il cubo sarà 2×size)
 Dim d As Float = 5.0            ' Distanza simulata della "camera" (l'osservatore)
 Dim ay As Float = Rad(angleY)   ' Angolo Y convertito in radianti

' === Definizione dei vertici 3D del cubo ===
 ' Ordine: da 0 a 7 (8 vertici di un cubo centrato sull'origine):
 Dim vertices As New Float[][8]
 vertices[0] = [-size, -size, -size]
 vertices[1] = [ size, -size, -size]
 vertices[2] = [ size,  size, -size]
 vertices[3] = [-size,  size, -size]
 vertices[4] = [-size, -size,  size]
 vertices[5] = [ size, -size,  size]
 vertices[6] = [ size,  size,  size]
 vertices[7] = [-size,  size,  size]

' === Ruota e proietta ogni vertice ===
 Dim projected As New PointF[8]
 For i As Integer = 0 To 7
   Dim p As Float[] = RotateY(vertices[i], ay)    ' Rotazione Y
   projected[i] = Project3D(p, d, cx, cy)         ' Proiezione 3D → 2D
 Next

' === Impostazioni per disegno linee ===
 Paint.LineWidth = 2
 Paint.Brush = Paint.Color(Color.Black)

' === Disegna i lati del cubo ===

' Faccia frontale (quella visibile quando Z è negativo):
 DrawEdge(projected, 0, 1)
 DrawEdge(projected, 1, 2)
 DrawEdge(projected, 2, 3)
 DrawEdge(projected, 3, 0)

' Faccia posteriore (Z positivo):
 DrawEdge(projected, 4, 5)
 DrawEdge(projected, 5, 6)
 DrawEdge(projected, 6, 7)
 DrawEdge(projected, 7, 4)

' Collegamenti tra vertici corrispondenti frontali/posteriori:
 DrawEdge(projected, 0, 4)
 DrawEdge(projected, 1, 5)
 DrawEdge(projected, 2, 6)
 DrawEdge(projected, 3, 7)

End

' === Funzione: rotazione attorno all’asse Y ===
Private Function RotateY(v As Float[], angle As Float) As Float[]

 Dim x As Float = v[0]
 Dim y As Float = v[1]
 Dim z As Float = v[2]

' Formula di rotazione attorno all'asse Y:
' ruota il punto nel piano XZ:
 Dim xr As Float = x * Cos(angle) + z * Sin(angle)
 Dim zr As Float = -x * Sin(angle) + z * Cos(angle)

 Return [xr, y, zr]

End

' === Funzione: proiezione prospettica 3D → 2D ===
Private Function Project3D(v As Float[], d As Float, cx As Float, cy As Float) As PointF
 Dim x As Float = v[0]
 Dim y As Float = v[1]
 Dim z As Float = v[2]

' Fattore prospettico: maggiore Z → più vicino alla "camera" (l'osservatore):
 Dim factor As Float = d / (z + d + 0.001)  ' evita divisione per 0
 Dim x2D As Float = x * factor
 Dim y2D As Float = y * factor

' Trasla al centro della DrawingArea e scala:
 Return New PointF(cx + x2D * Zoom, cy - y2D * Zoom)

End


' === Procedura che disegna uno spigolo tra due vertici proiettati ===
Private Procedure DrawEdge(points As PointF[], i1 As Integer, i2 As Integer)

 Paint.MoveTo(points[i1].X, points[i1].Y)   ' Punto iniziale
 Paint.LineTo(points[i2].X, points[i2].Y)   ' Punto finale
 Paint.Stroke()                             ' Esegue il disegno della linea

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


Rotazione di un cubo intorno ai suoi assi X, Y e Z

' Variabili per gli angoli di rotazione su X, Y e Z:
Private angleX As Float
Private angleY As Float
Private angleZ As Float
' Fattore di zoom (valore più alto = oggetto più grande):
Private Zoom As Float = 150


Public Sub Form_Open()

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

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

End


Public Sub Timer1_Timer()
 
 angleX += 1.2           ' Incrementa angolo di rotazione su X
 angleY += 2.0           ' Rotazione su Y
 angleZ += 0.8           ' Rotazione su Z

 DrawingArea1.Refresh    ' Richiede ridisegno della scena

End


' === Disegno del cubo rotante ===
Public Sub DrawingArea1_Draw()

' Centro della DrawingArea:
 Dim cx As Float = DrawingArea1.Width / 2
 Dim cy As Float = DrawingArea1.Height / 2

' Parametri del cubo:
 Dim size As Float = 1.0           ' Metà lato
 Dim d As Float = 5.0              ' Distanza della "camera"(l'osservatore)
 Dim ax As Float = Rad(angleX)
 Dim ay As Float = Rad(angleY)
 Dim az As Float = Rad(angleZ)

' === Vertici 3D del cubo ===
 Dim vertices As New Float[][8]
 vertices[0] = [-size, -size, -size]
 vertices[1] = [ size, -size, -size]
 vertices[2] = [ size,  size, -size]
 vertices[3] = [-size,  size, -size]
 vertices[4] = [-size, -size,  size]
 vertices[5] = [ size, -size,  size]
 vertices[6] = [ size,  size,  size]
 vertices[7] = [-size,  size,  size]

' === Ruota e proietta ogni vertice ===
 Dim projected As New PointF[8]
 For i As Integer = 0 To 7
   Dim p As Float[] = vertices[i]

' Applica rotazione X → Y → Z:
   p = RotateX(p, ax)
   p = RotateY(p, ay)
   p = RotateZ(p, az)

' Proiezione 3D → 2D:
   projected[i] = Project3D(p, d, cx, cy)
 Next

' Impostazioni di disegno:
 Paint.LineWidth = 2
 Paint.Brush = Paint.Color(Color.Black)

' === Disegna i 12 spigoli del cubo ===

' Faccia frontale:
 DrawEdge(projected, 0, 1)
 DrawEdge(projected, 1, 2)
 DrawEdge(projected, 2, 3)
 DrawEdge(projected, 3, 0)

' Faccia posteriore:
 DrawEdge(projected, 4, 5)
 DrawEdge(projected, 5, 6)
 DrawEdge(projected, 6, 7)
 DrawEdge(projected, 7, 4)

' Spigoli che collegano fronte e retro:
 DrawEdge(projected, 0, 4)
 DrawEdge(projected, 1, 5)
 DrawEdge(projected, 2, 6)
 DrawEdge(projected, 3, 7)

End


' === ROTAZIONE attorno all'asse X ===
Private Function RotateX(v As Float[], angle As Float) As Float[]

 Dim x As Float = v[0]
 Dim y As Float = v[1]
 Dim z As Float = v[2]

' Ruota y e z nel piano YZ:
 Dim yr As Float = y * Cos(angle) - z * Sin(angle)
 Dim zr As Float = y * Sin(angle) + z * Cos(angle)

 Return [x, yr, zr]

End


' === ROTAZIONE attorno all'asse Y ===
Private Function RotateY(v As Float[], angle As Float) As Float[]

 Dim x As Float = v[0]
 Dim y As Float = v[1]
 Dim z As Float = v[2]

' Ruota x e z nel piano XZ:
 Dim xr As Float = x * Cos(angle) + z * Sin(angle)
 Dim zr As Float = -x * Sin(angle) + z * Cos(angle)

 Return [xr, y, zr]

End


' === ROTAZIONE attorno all'asse Z ===
Private Function RotateZ(v As Float[], angle As Float) As Float[]

 Dim x As Float = v[0]
 Dim y As Float = v[1]
 Dim z As Float = v[2]

' Ruota x e y nel piano XY:
 Dim xr As Float = x * Cos(angle) - y * Sin(angle)
 Dim yr As Float = x * Sin(angle) + y * Cos(angle)

 Return [xr, yr, z]

End


' === PROIEZIONE prospettica 3D → 2D ===
Private Function Project3D(v As Float[], d As Float, cx As Float, cy As Float) As PointF

 Dim x As Float = v[0]
 Dim y As Float = v[1]
 Dim z As Float = v[2]

' Calcola il fattore di profondità:
 Dim factor As Float = d / (z + d + 0.001)   ' +0.001 evita divisione per zero

' Applica il fattore e centra sulla DrawingArea:
 Dim x2D As Float = x * factor
 Dim y2D As Float = y * factor

 Return New PointF(cx + x2D * Zoom, cy - y2D * Zoom)

End


' === Disegna una linea tra due punti proiettati ===
Private Procedure DrawEdge(points As PointF[], i1 As Integer, i2 As Integer)

 Paint.MoveTo(points[i1].X, points[i1].Y)
 Paint.LineTo(points[i2].X, points[i2].Y)
 Paint.Stroke()

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