Ruotare un cubo in una DrawingArea: differenze tra le versioni
Vai alla navigazione
Vai alla ricerca
Nessun oggetto della modifica |
Nessun oggetto della modifica |
||
| (4 versioni intermedie di uno stesso utente non sono mostrate) | |||
| 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 | Mostriamo di seguito un possibile codice per ruotare un Cubo in 3D intorno al suo asse Y in una ''DrawingArea''. | ||
<FONT Color=gray>' '' | |||
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 8: | Riga 12: | ||
With Me | With Me | ||
.Title = " | .Title = "Cubo che ruota intorno al suo asse Y" | ||
.Move(0, 0, Screen.AvailableWidth, Screen.AvailableHeight) | .Move(0, 0, Screen.AvailableWidth, Screen.AvailableHeight) | ||
.Arrangement = Arrange.Fill | .Arrangement = Arrange.Fill | ||
| 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 * | 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 | |||
==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> | |||
Private angleX As Float | |||
Private angleY As Float | |||
Private angleZ As Float | |||
<FONT Color=gray>' ''Fattore di zoom (valore più alto = oggetto più grande):''</font> | |||
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 <FONT Color=gray>' ''~60 FPS''</font> | |||
Timer1.Start | |||
End | |||
Public Sub Timer1_Timer() | |||
angleX += 1.2 <FONT Color=gray>' ''Incrementa angolo di rotazione su X''</font> | |||
angleY += 2.0 <FONT Color=gray>' ''Rotazione su Y''</font> | |||
angleZ += 0.8 <FONT Color=gray>' ''Rotazione su Z''</font> | |||
DrawingArea1.Refresh <FONT Color=gray>' ''Richiede ridisegno della scena''</font> | |||
End | |||
<FONT Color=gray>' ''=== Disegno del cubo rotante ===''</font> | |||
Public Sub DrawingArea1_Draw() | |||
<FONT Color=gray>' ''Centro della DrawingArea:''</font> | |||
Dim cx As Float = DrawingArea1.Width / 2 | |||
Dim cy As Float = DrawingArea1.Height / 2 | |||
<FONT Color=gray>' ''Parametri del cubo:''</font> | |||
Dim size As Float = 1.0 <FONT Color=gray>' ''Metà lato''</font> | |||
Dim d As Float = 5.0 <FONT Color=gray>' ''Distanza della "camera"(l'osservatore)''</font> | |||
Dim ax As Float = Rad(angleX) | |||
Dim ay As Float = Rad(angleY) | |||
Dim az As Float = Rad(angleZ) | |||
<FONT Color=gray>' ''=== Vertici 3D del cubo ===''</font> | |||
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] | |||
<FONT Color=gray>' ''=== Ruota e proietta ogni vertice ===''</font> | |||
Dim projected As New PointF[8] | |||
For i As Integer = 0 To 7 | |||
Dim p As Float[] = vertices[i] | |||
<FONT Color=gray>' ''Applica rotazione X → Y → Z:''</font> | |||
p = RotateX(p, ax) | |||
p = RotateY(p, ay) | |||
p = RotateZ(p, az) | |||
<FONT Color=gray>' ''Proiezione 3D → 2D:''</font> | |||
projected[i] = Project3D(p, d, cx, cy) | |||
Next | |||
<FONT Color=gray>' ''Impostazioni di disegno:''</font> | |||
Paint.LineWidth = 2 | |||
Paint.Brush = Paint.Color(Color.Black) | |||
<FONT Color=gray>' ''=== Disegna i 12 spigoli del cubo ===''</font> | |||
<FONT Color=gray>' ''Faccia frontale:''</font> | |||
DrawEdge(projected, 0, 1) | |||
DrawEdge(projected, 1, 2) | |||
DrawEdge(projected, 2, 3) | |||
DrawEdge(projected, 3, 0) | |||
<FONT Color=gray>' ''Faccia posteriore:''</font> | |||
DrawEdge(projected, 4, 5) | |||
DrawEdge(projected, 5, 6) | |||
DrawEdge(projected, 6, 7) | |||
DrawEdge(projected, 7, 4) | |||
<FONT Color=gray>' ''Spigoli che collegano fronte e retro:''</font> | |||
DrawEdge(projected, 0, 4) | |||
DrawEdge(projected, 1, 5) | |||
DrawEdge(projected, 2, 6) | |||
DrawEdge(projected, 3, 7) | |||
End | |||
<FONT Color=gray>' ''=== ROTAZIONE attorno all'asse X ===''</font> | |||
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] | |||
<FONT Color=gray>' ''Ruota y e z nel piano YZ:''</font> | |||
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 | |||
<FONT Color=gray>' ''=== ROTAZIONE attorno all'asse Y ===''</font> | |||
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] | |||
<FONT Color=gray>' ''Ruota x e z nel piano XZ:''</font> | |||
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 | |||
<FONT Color=gray>' ''=== ROTAZIONE attorno all'asse Z ===''</font> | |||
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] | |||
<FONT Color=gray>' ''Ruota x e y nel piano XY:''</font> | |||
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 | |||
<FONT Color=gray>' ''=== PROIEZIONE prospettica 3D → 2D ===''</font> | |||
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] | |||
<FONT Color=gray>' ''Calcola il fattore di profondità:''</font> | |||
Dim factor As Float = d / (z + d + 0.001) <FONT Color=gray>' ''+0.001 evita divisione per zero''</font> | |||
<FONT Color=gray>' ''Applica il fattore e centra sulla DrawingArea:''</font> | |||
Dim x2D As Float = x * factor | |||
Dim y2D As Float = y * factor | |||
Return New PointF(cx + x2D * Zoom, cy - y2D * Zoom) | |||
End | |||
<FONT Color=gray>' ''=== Disegna una linea tra due punti proiettati ===''</font> | |||
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() <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 attuale delle 14:37, 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