Ruotare un prisma in una DrawingArea: differenze tra le versioni
Nessun oggetto della modifica |
Nessun oggetto della modifica |
||
| (3 versioni intermedie di uno stesso utente non sono mostrate) | |||
| Riga 87: | Riga 87: | ||
Next | Next | ||
<FONT Color=gray>' ''=== DISEGNO DELLE FACCE ===''</font> | |||
Paint.Brush = Paint.Color(Color.Black) | Paint.Brush = Paint.Color(Color.Black) | ||
| Riga 100: | Riga 100: | ||
Next | Next | ||
Next | Next | ||
End | End | ||
| Riga 139: | Riga 137: | ||
Nell'esempio che segue sarà possibile aumentare o diminuire la dimensione del disegno del Prisma, cliccando rispettivamente sui tasti "+" e "-" della tastiera. | Nell'esempio che segue sarà possibile aumentare o diminuire la dimensione del disegno del Prisma, cliccando rispettivamente sui tasti "+" e "-" della tastiera. | ||
Private angleY As Float | Private angleY As Float <FONT Color=gray>' ''Angolo di rotazione sull'asse Y (incrementato nel tempo)''</font> | ||
Private Zoom As Float = 150 ' Fattore di ingrandimento della scena 3D | Private Zoom As Float = 150 <FONT Color=gray>' ''Fattore di ingrandimento della scena 3D''</font> | ||
Private Vertices As Object[] ' Lista dei vertici 3D del prisma | Private Vertices As Object[] <FONT Color=gray>' ''Lista dei vertici 3D del prisma''</font> | ||
Private Faces As Object[] ' Lista delle facce (ogni faccia è una lista di indici dei vertici) | Private Faces As Object[] <FONT Color=gray>' ''Lista delle facce (ogni faccia è una lista di indici dei vertici)''</font> | ||
Private PerspectiveFactor As Float = 0.5 ' 0 = proiezione isometrica, 1 = prospettiva piena | Private PerspectiveFactor As Float = 0.5 <FONT Color=gray>' ''0 = proiezione isometrica, 1 = prospettiva piena''</font> | ||
Public Sub Form_Open() | Public Sub Form_Open() | ||
Me.Title = "Prisma pentagonale rotante" | Me.Title = "Prisma pentagonale rotante" | ||
Me.Move(0, 0, Screen.AvailableWidth, Screen.AvailableHeight) | Me.Move(0, 0, Screen.AvailableWidth, Screen.AvailableHeight) | ||
Me.Arrangement = Arrange.Fill | Me.Arrangement = Arrange.Fill | ||
Vertices = New Object[] | Vertices = New Object[] | ||
Faces = New Object[] | Faces = New Object[] | ||
<FONT Color=gray>' ''=== COSTRUZIONE DEI VERTICI DEL PRISMA ===''</font> | |||
Dim i As Integer | Dim i As Integer | ||
Dim angle As Float | Dim angle As Float | ||
Dim r As Float = 1.0 ' Raggio del pentagono (distanza dal centro) | Dim r As Float = 1.0 ' Raggio del pentagono (distanza dal centro)''</font> | ||
Dim h As Float = 1.5 ' Metà altezza del prisma (in asse Z, da -h a +h) | Dim h As Float = 1.5 ' Metà altezza del prisma (in asse Z, da -h a +h)''</font> | ||
<FONT Color=gray>' ''Pentagono superiore (z = +h):''</font> | |||
For i = 0 To 4 | For i = 0 To 4 | ||
angle = i * 2 * Pi / 5 | angle = i * 2 * Pi / 5 | ||
Vertices.Push([r * Cos(angle), r * Sin(angle), h]) | Vertices.Push([r * Cos(angle), r * Sin(angle), h]) | ||
Next | Next | ||
<FONT Color=gray>' ''Pentagono inferiore (z = -h):''</font> | |||
For i = 0 To 4 | For i = 0 To 4 | ||
angle = i * 2 * Pi / 5 | angle = i * 2 * Pi / 5 | ||
Vertices.Push([r * Cos(angle), r * Sin(angle), -h]) | Vertices.Push([r * Cos(angle), r * Sin(angle), -h]) | ||
Next | Next | ||
<FONT Color=gray>' ''=== DEFINIZIONE DELLE FACCE ==='' | |||
' ''Faccia superiore (pentagono) → vertici da 0 a 4:''</font> | |||
Faces.Push([0, 1, 2, 3, 4]) | Faces.Push([0, 1, 2, 3, 4]) | ||
<FONT Color=gray>' ''Faccia inferiore (invertita per orientamento corretto) → vertici da 5 a 9:''</font> | |||
Faces.Push([9, 8, 7, 6, 5]) | Faces.Push([9, 8, 7, 6, 5]) | ||
<FONT Color=gray>' ''Facce laterali rettangolari: ogni lato collega un vertice superiore a quello inferiore:''</font> | |||
For i = 0 To 4 | For i = 0 To 4 | ||
Dim nextI As Integer = (i + 1) Mod 5 | Dim nextI As Integer = (i + 1) Mod 5 | ||
Faces.Push([i, nextI, nextI + 5, i + 5]) | Faces.Push([i, nextI, nextI + 5, i + 5]) | ||
Next | Next | ||
<FONT Color=gray>' ''Imposta il timer per animare la rotazione (~60 FPS):''</font> | |||
Timer1.Delay = 16 | Timer1.Delay = 16 | ||
Timer1.Start | Timer1.Start | ||
End | End | ||
Public Sub Timer1_Timer() | Public Sub Timer1_Timer() | ||
angleY += 0.025 | angleY += 0.025 | ||
DrawingArea1.Refresh | DrawingArea1.Refresh | ||
End | |||
End | |||
Public Sub DrawingArea1_Draw() | |||
Public Sub DrawingArea1_Draw() | |||
<FONT Color=gray>' ''Calcola il centro dello schermo:''</font> | |||
Dim w As Integer = DrawingArea1.W | Dim w As Integer = DrawingArea1.W | ||
Dim h As Integer = DrawingArea1.H | Dim h As Integer = DrawingArea1.H | ||
Dim cx As Float = w / 2 | Dim cx As Float = w / 2 | ||
Dim cy As Float = h / 2 | Dim cy As Float = h / 2 | ||
Dim points As Object[] = New Object[] <FONT Color=gray>' ''Coordinate proiettate 2D''</font> | |||
Dim points As Object[] = New Object[] | |||
<FONT Color=gray>' ''=== TRASFORMAZIONE E PROIEZIONE DEI VERTICI 3D ===''</font> | |||
For Each v As Float[] In Vertices | For Each v As Float[] In Vertices | ||
Dim x, y, z As Float | Dim x, y, z As Float | ||
| Riga 219: | Riga 215: | ||
y = v[1] | y = v[1] | ||
z = v[2] | z = v[2] | ||
<FONT Color=gray>' ''Rotazione attorno all’asse Y:''</font> | |||
Dim x1 As Float = x * Cos(angleY) + z * Sin(angleY) | Dim x1 As Float = x * Cos(angleY) + z * Sin(angleY) | ||
Dim z1 As Float = -x * Sin(angleY) + z * Cos(angleY) | Dim z1 As Float = -x * Sin(angleY) + z * Cos(angleY) | ||
x = x1 | x = x1 | ||
z = z1 | z = z1 | ||
<FONT Color=gray>' ''Proiezione prospettica interpolata:''</font> | |||
If (z + 3) < 0.1 Then | If (z + 3) < 0.1 Then | ||
points.Push([cx, cy]) | points.Push([cx, cy]) <FONT Color=gray>' ''Punto "di sicurezza" per evitare divisioni per zero''</font> | ||
Continue | Continue | ||
Endif | Endif | ||
Dim scale As Float = Zoom / (1 + PerspectiveFactor * (z + 3)) | Dim scale As Float = Zoom / (1 + PerspectiveFactor * (z + 3)) | ||
Dim sx As Float = cx + x * scale | Dim sx As Float = cx + x * scale | ||
Dim sy As Float = cy - y * scale | Dim sy As Float = cy - y * scale | ||
points.Push([sx, sy]) | points.Push([sx, sy]) <FONT Color=gray>' ''Salva il punto proiettato''</font> | ||
Next | Next | ||
<FONT Color=gray>' ''=== DISEGNA TUTTE LE FACCE COME POLIGONI CHIUSI ===''</font> | |||
Paint.Brush = Paint.Color(Color.Black) | Paint.Brush = Paint.Color(Color.Black) | ||
For Each f As Integer[] In Faces | For Each f As Integer[] In Faces | ||
Dim i As Integer | Dim i As Integer | ||
| Riga 252: | Riga 248: | ||
Next | Next | ||
Next | Next | ||
End | |||
Public Sub Form_KeyPress() <FONT Color=gray>' ''GESTIONE DELLA TASTIERA PER ZOOM''</font> | |||
' | |||
Select Case Key.Code | Select Case Key.Code | ||
Case Key["+"] | Case Key["+"] | ||
Zoom = Min(Zoom + 25, 1000) | Zoom = Min(Zoom + 25, 1000) <FONT Color=gray>' ''Ingrandisce l’oggetto''</font> | ||
Case Key["-"] | Case Key["-"] | ||
Zoom = Max(Zoom - 25, 25) | Zoom = Max(Zoom - 25, 25) <FONT Color=gray>' ''Rimpicciolisce l’oggetto''</font> | ||
End Select | End Select | ||
DrawingArea1.Refresh | DrawingArea1.Refresh | ||
End | End | ||
| Riga 276: | Riga 270: | ||
Nell'esempio che segue sarà possibile aumentare o diminuire la dimensione del disegno del Prisma, cliccando rispettivamente sui tasti "+" e "-" della tastiera. | Nell'esempio che segue sarà possibile aumentare o diminuire la dimensione del disegno del Prisma, cliccando rispettivamente sui tasti "+" e "-" della tastiera. | ||
Private angleY As Float <FONT Color=gray>' ''Angolo di rotazione sull'asse Y (aumenta nel tempo)''</font> | |||
Private Zoom As Float = 150 <FONT Color=gray>' ''Fattore di ingrandimento della scena''</font> | |||
Private angleY As Float ' Angolo di rotazione sull'asse Y (aumenta nel tempo) | Private Vertices As Object[] <FONT Color=gray>' ''Elenco dei vertici 3D (ogni vertice è un array [x, y, z])''</font> | ||
Private Zoom As Float = 150 | Private Faces As Object[] <FONT Color=gray>' ''Elenco delle facce (ogni faccia è un array di indici)''</font> | ||
Private Vertices As Object[] | Private PerspectiveFactor As Float = 0.5 <FONT Color=gray>' ''0 = isometria, 1 = prospettiva completa''</font> | ||
Private Faces As Object[] | |||
Private PerspectiveFactor As Float = 0.5 | |||
Public Sub Form_Open() | |||
Public Sub Form_Open() | |||
Me.Title = "Prisma esagonale rotante" | Me.Title = "Prisma esagonale rotante" | ||
Me.Move(0, 0, Screen.AvailableWidth, Screen.AvailableHeight) | Me.Move(0, 0, Screen.AvailableWidth, Screen.AvailableHeight) | ||
Me.Arrangement = Arrange.Fill | Me.Arrangement = Arrange.Fill | ||
Vertices = New Object[] | Vertices = New Object[] <FONT Color=gray>' ''Inizializza la lista dei vertici''</font> | ||
Faces = New Object[] | Faces = New Object[] <FONT Color=gray>' ''Inizializza la lista delle facce''</font> | ||
<FONT Color=gray>' ''=== COSTRUZIONE VERTICI ===''</font> | |||
Dim i As Integer | Dim i As Integer | ||
Dim angle As Float | Dim angle As Float | ||
Dim r As Float = 1.0 | Dim r As Float = 1.0 <FONT Color=gray>' ''Raggio dell'esagono (distanza dal centro)''</font> | ||
Dim h As Float = 1.5 | Dim h As Float = 1.5 <FONT Color=gray>' ''Metà altezza del prisma (da -h a +h)''</font> | ||
<FONT Color=gray>' ''Esagono superiore (z = +h):''</font> | |||
For i = 0 To 5 | For i = 0 To 5 | ||
angle = i * 2 * Pi / 6 | angle = i * 2 * Pi / 6 | ||
Vertices.Push([r * Cos(angle), r * Sin(angle), h]) | Vertices.Push([r * Cos(angle), r * Sin(angle), h]) | ||
Next | Next | ||
<FONT Color=gray>' ''Esagono inferiore (z = -h):''</font> | |||
For i = 0 To 5 | For i = 0 To 5 | ||
angle = i * 2 * Pi / 6 | angle = i * 2 * Pi / 6 | ||
Vertices.Push([r * Cos(angle), r * Sin(angle), -h]) | Vertices.Push([r * Cos(angle), r * Sin(angle), -h]) | ||
Next | Next | ||
<FONT Color=gray>' ''=== DEFINIZIONE DELLE FACCE ==='' | |||
' ''Faccia superiore (esagono):''</font> | |||
Faces.Push([0, 1, 2, 3, 4, 5]) | Faces.Push([0, 1, 2, 3, 4, 5]) | ||
<FONT Color=gray>' ''Faccia inferiore (invertita per corretto orientamento visivo):''</font> | |||
Faces.Push([11, 10, 9, 8, 7, 6]) | Faces.Push([11, 10, 9, 8, 7, 6]) | ||
<FONT Color=gray>' ''6 facce laterali rettangolari tra i vertici superiore e inferiore:''</font> | |||
For i = 0 To 5 | For i = 0 To 5 | ||
Dim nextI As Integer = (i + 1) Mod 6 | Dim nextI As Integer = (i + 1) Mod 6 | ||
Faces.Push([i, nextI, nextI + 6, i + 6]) | Faces.Push([i, nextI, nextI + 6, i + 6]) | ||
Next | Next | ||
<FONT Color=gray>' ''Avvia il timer per animare la rotazione (~60 fotogrammi al secondo):''</font> | |||
Timer1.Delay = 16 | Timer1.Delay = 16 | ||
Timer1.Start | Timer1.Start | ||
End | End | ||
Public Sub Timer1_Timer() | Public Sub Timer1_Timer() | ||
angleY += 0.025 | |||
DrawingArea1.Refresh | angleY += 0.025 <FONT Color=gray>' ''Rotazione continua sull’asse Y''</font> | ||
End | DrawingArea1.Refresh <FONT Color=gray>' ''Richiede il ridisegno della scena''</font> | ||
End | |||
Public Sub DrawingArea1_Draw() | |||
Public Sub DrawingArea1_Draw() | |||
<FONT Color=gray>' ''Centro della DrawingArea (per centrare la proiezione):''</font> | |||
Dim w As Integer = DrawingArea1.W | Dim w As Integer = DrawingArea1.W | ||
Dim h As Integer = DrawingArea1.H | Dim h As Integer = DrawingArea1.H | ||
Dim cx As Float = w / 2 | Dim cx As Float = w / 2 | ||
Dim cy As Float = h / 2 | Dim cy As Float = h / 2 | ||
Dim points As Object[] = New Object[] <FONT Color=gray>' ''Lista dei punti proiettati 2D''</font> | |||
Dim points As Object[] = New Object[] | |||
<FONT Color=gray>' ''=== PROIEZIONE 3D → 2D PER OGNI VERTICE ===''</font> | |||
For Each v As Float[] In Vertices | For Each v As Float[] In Vertices | ||
Dim x, y, z As Float | Dim x, y, z As Float | ||
x = v[0] | x = v[0] | ||
y = v[1] | y = v[1] | ||
z = v[2] | z = v[2] | ||
<FONT Color=gray>' ''ROTAZIONE SULL'ASSE Y''</font> | |||
Dim x1 As Float = x * Cos(angleY) + z * Sin(angleY) | Dim x1 As Float = x * Cos(angleY) + z * Sin(angleY) | ||
Dim z1 As Float = -x * Sin(angleY) + z * Cos(angleY) | Dim z1 As Float = -x * Sin(angleY) + z * Cos(angleY) | ||
x = x1 | x = x1 | ||
z = z1 | z = z1 | ||
<FONT Color=gray>' ''PROIEZIONE PROSPETTICA INTERPOLATA''</font> | |||
If (z + 3) < 0.1 Then | If (z + 3) < 0.1 Then | ||
points.Push([cx, cy]) | points.Push([cx, cy]) <FONT Color=gray>' ''Punto neutro di sicurezza''</font> | ||
Continue | Continue | ||
Endif | Endif | ||
Dim scale As Float = Zoom / (1 + PerspectiveFactor * (z + 3)) | Dim scale As Float = Zoom / (1 + PerspectiveFactor * (z + 3)) | ||
Dim sx As Float = cx + x * scale | Dim sx As Float = cx + x * scale | ||
Dim sy As Float = cy - y * scale | Dim sy As Float = cy - y * scale | ||
points.Push([sx, sy]) | points.Push([sx, sy]) <FONT Color=gray>' ''Aggiunge punto proiettato alla lista''</font> | ||
Next | Next | ||
<FONT Color=gray>' ''=== DISEGNO DELLE FACCE ===''</font> | |||
Paint.Brush = Paint.Color(Color.Black) | Paint.Brush = Paint.Color(Color.Black) | ||
For Each f As Integer[] In Faces | For Each f As Integer[] In Faces | ||
Dim i As Integer | Dim i As Integer | ||
| Riga 392: | Riga 382: | ||
Next | Next | ||
Next | Next | ||
End | |||
End | |||
Public Sub Form_KeyPress() <FONT Color=gray>' ''ZOOM CON TASTIERA''</font> | |||
Public Sub Form_KeyPress() | |||
Select Case Key.Code | Select Case Key.Code | ||
Case Key["+"] | Case Key["+"] | ||
Zoom = Min(Zoom + 25, 1000) | Zoom = Min(Zoom + 25, 1000) <FONT Color=gray>' ''Ingrandisce''</font> | ||
Case Key["-"] | Case Key["-"] | ||
Zoom = Max(Zoom - 25, 25) | Zoom = Max(Zoom - 25, 25) <FONT Color=gray>' ''Rimpicciolisce''</font> | ||
End Select | End Select | ||
DrawingArea1.Refresh | DrawingArea1.Refresh | ||
End | End | ||
Versione attuale delle 18:46, 10 ago 2025
Ruotare un Prisma triangolare
Mostreremo un possibile codice per disegnare e ruotare un Prisma triangolare intorno al suo asse Y in una DrawingArea.
Nell'esempio che segue sarà possibile aumentare o diminuire la dimensione del disegno del Prisma, cliccando rispettivamente sui tasti "+" e "-" della tastiera.
Private angleY As Float ' Angolo di rotazione sull'asse Y
Private Zoom As Float = 150 ' Fattore di ingrandimento della proiezione
Private Vertices As Object[] ' Array dei vertici 3D (ogni vertice è un array [x, y, z])
Private Faces As Object[] ' Array delle facce (ogni faccia è un array di indici dei vertici)
Private PerspectiveFactor As Float = 0.5 ' Interpolazione tra isometria (0) e prospettiva (1)
Public Sub Form_Open()
Me.Title = "Prisma triangolare rotante sul suo asse Y"
Me.Move(0, 0, Screen.AvailableWidth, Screen.AvailableHeight)
Me.Arrangement = Arrange.Fill
Vertices = New Object[]
Faces = New Object[]
' === DEFINIZIONE DEI 6 VERTICI DEL PRISMA ===
' Triangolo superiore (z = +1):
Vertices.Push([0, 1, 1]) ' Vertice centrale in alto
Vertices.Push([-1, -1, 1]) ' Vertice in basso a sinistra
Vertices.Push([1, -1, 1]) ' Vertice in basso a destra
' Triangolo inferiore (z = -1):
Vertices.Push([0, 1, -1]) ' Vertice centrale in alto (opposto)
Vertices.Push([-1, -1, -1]) ' Basso sinistra (opposto)
Vertices.Push([1, -1, -1]) ' Basso destra (opposto)
' === DEFINIZIONE DELLE 5 FACCE ===
' Ogni faccia è una lista ordinata di indici (chiusa automaticamente nel disegno):
Faces.Push([0, 1, 2]) ' Faccia triangolare superiore
Faces.Push([3, 5, 4]) ' Faccia triangolare inferiore (ordine invertito per corretto orientamento)
Faces.Push([0, 2, 5, 3]) ' Faccia laterale 1 (rettangolare)
Faces.Push([2, 1, 4, 5]) ' Faccia laterale 2
Faces.Push([1, 0, 3, 4]) ' Faccia laterale 3
Timer1.Delay = 16
Timer1.Start
End
Public Sub Timer1_Timer()
angleY += 0.03
DrawingArea1.Refresh
End
Public Sub DrawingArea1_Draw()
' Centro della DrawingArea:
Dim w As Integer = DrawingArea1.W
Dim h As Integer = DrawingArea1.H
Dim cx As Float = w / 2
Dim cy As Float = h / 2
Dim points As Object[] = New Object[]
' === PROIEZIONE 3D → 2D PER OGNI VERTICE ===
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 Y:
Dim x1 As Float = x * Cos(angleY) + z * Sin(angleY)
Dim z1 As Float = -x * Sin(angleY) + z * Cos(angleY)
x = x1
z = z1
' Proiezione prospettica interpolata:
If (z + 3) < 0.1 Then
points.Push([cx, cy]) ' Punto "di sicurezza"
Continue
Endif
Dim scale As Float = Zoom / (1 + PerspectiveFactor * (z + 3))
Dim sx As Float = cx + x * scale
Dim sy As Float = cy - y * scale
points.Push([sx, sy]) ' Salva le coordinate 2D proiettate
Next
' === DISEGNO DELLE FACCE ===
Paint.Brush = Paint.Color(Color.Black)
For Each f As Integer[] In Faces
Dim i As Integer
For i = 0 To f.Count - 1
Dim p1 As Float[] = points[f[i]]
Dim p2 As Float[] = points[(f[(i + 1) Mod f.Count])]
Paint.MoveTo(p1[0], p1[1])
Paint.LineTo(p2[0], p2[1])
Paint.Stroke
Next
Next
End
Public Sub Form_KeyPress() ' Zoom controllato da tastiera
Select Case Key.Code
Case Key["+"]
Zoom = Min(Zoom + 25, 1000) ' Ingrandisce
Case Key["-"]
Zoom = Max(Zoom - 25, 25) ' Rimpicciolisce
End Select
DrawingArea1.Refresh
End
Far ruotare il Prisma solo sul suo asse Z
Per far ruotare il Prisma solo sul suo asse Z, sostituire queste righe:
' Rotazione attorno all'asse Y: Dim x1 As Float = x * Cos(angleY) + z * Sin(angleY) Dim z1 As Float = -x * Sin(angleY) + z * Cos(angleY) x = x1 z = z1
con le seguenti:
' Rotazione attorno all'asse Z: Dim x1 As Float = x * Cos(angleY) - y * Sin(angleY) Dim y1 As Float = x * Sin(angleY) + y * Cos(angleY) x = x1 y = y1
Ruotare un Prisma pentagonale intorno al suo asse Y
Mostreremo un possibile codice per disegnare e ruotare un Prisma pentagonale intorno al suo asse Y in una DrawingArea.
Nell'esempio che segue sarà possibile aumentare o diminuire la dimensione del disegno del Prisma, cliccando rispettivamente sui tasti "+" e "-" della tastiera.
Private angleY As Float ' Angolo di rotazione sull'asse Y (incrementato nel tempo)
Private Zoom As Float = 150 ' Fattore di ingrandimento della scena 3D
Private Vertices As Object[] ' Lista dei vertici 3D del prisma
Private Faces As Object[] ' Lista delle facce (ogni faccia è una lista di indici dei vertici)
Private PerspectiveFactor As Float = 0.5 ' 0 = proiezione isometrica, 1 = prospettiva piena
Public Sub Form_Open()
Me.Title = "Prisma pentagonale rotante"
Me.Move(0, 0, Screen.AvailableWidth, Screen.AvailableHeight)
Me.Arrangement = Arrange.Fill
Vertices = New Object[]
Faces = New Object[]
' === COSTRUZIONE DEI VERTICI DEL PRISMA ===
Dim i As Integer
Dim angle As Float
Dim r As Float = 1.0 ' Raggio del pentagono (distanza dal centro)
Dim h As Float = 1.5 ' Metà altezza del prisma (in asse Z, da -h a +h)
' Pentagono superiore (z = +h):
For i = 0 To 4
angle = i * 2 * Pi / 5
Vertices.Push([r * Cos(angle), r * Sin(angle), h])
Next
' Pentagono inferiore (z = -h):
For i = 0 To 4
angle = i * 2 * Pi / 5
Vertices.Push([r * Cos(angle), r * Sin(angle), -h])
Next
' === DEFINIZIONE DELLE FACCE ===
' Faccia superiore (pentagono) → vertici da 0 a 4:
Faces.Push([0, 1, 2, 3, 4])
' Faccia inferiore (invertita per orientamento corretto) → vertici da 5 a 9:
Faces.Push([9, 8, 7, 6, 5])
' Facce laterali rettangolari: ogni lato collega un vertice superiore a quello inferiore:
For i = 0 To 4
Dim nextI As Integer = (i + 1) Mod 5
Faces.Push([i, nextI, nextI + 5, i + 5])
Next
' Imposta il timer per animare la rotazione (~60 FPS):
Timer1.Delay = 16
Timer1.Start
End
Public Sub Timer1_Timer()
angleY += 0.025
DrawingArea1.Refresh
End
Public Sub DrawingArea1_Draw()
' Calcola il centro dello schermo:
Dim w As Integer = DrawingArea1.W
Dim h As Integer = DrawingArea1.H
Dim cx As Float = w / 2
Dim cy As Float = h / 2
Dim points As Object[] = New Object[] ' Coordinate proiettate 2D
' === TRASFORMAZIONE E PROIEZIONE DEI VERTICI 3D ===
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 Y:
Dim x1 As Float = x * Cos(angleY) + z * Sin(angleY)
Dim z1 As Float = -x * Sin(angleY) + z * Cos(angleY)
x = x1
z = z1
' Proiezione prospettica interpolata:
If (z + 3) < 0.1 Then
points.Push([cx, cy]) ' Punto "di sicurezza" per evitare divisioni per zero
Continue
Endif
Dim scale As Float = Zoom / (1 + PerspectiveFactor * (z + 3))
Dim sx As Float = cx + x * scale
Dim sy As Float = cy - y * scale
points.Push([sx, sy]) ' Salva il punto proiettato
Next
' === DISEGNA TUTTE LE FACCE COME POLIGONI CHIUSI ===
Paint.Brush = Paint.Color(Color.Black)
For Each f As Integer[] In Faces
Dim i As Integer
For i = 0 To f.Count - 1
Dim p1 As Float[] = points[f[i]]
Dim p2 As Float[] = points[(f[(i + 1) Mod f.Count])]
Paint.MoveTo(p1[0], p1[1])
Paint.LineTo(p2[0], p2[1])
Paint.Stroke
Next
Next
End
Public Sub Form_KeyPress() ' GESTIONE DELLA TASTIERA PER ZOOM
Select Case Key.Code
Case Key["+"]
Zoom = Min(Zoom + 25, 1000) ' Ingrandisce l’oggetto
Case Key["-"]
Zoom = Max(Zoom - 25, 25) ' Rimpicciolisce l’oggetto
End Select
DrawingArea1.Refresh
End
Ruotare un Prisma esagonale intorno al suo asse Y
Mostreremo un possibile codice per disegnare e ruotare un Prisma esagonale intorno al suo asse Y in una DrawingArea.
Nell'esempio che segue sarà possibile aumentare o diminuire la dimensione del disegno del Prisma, cliccando rispettivamente sui tasti "+" e "-" della tastiera.
Private angleY As Float ' Angolo di rotazione sull'asse Y (aumenta nel tempo)
Private Zoom As Float = 150 ' Fattore di ingrandimento della scena
Private Vertices As Object[] ' Elenco dei vertici 3D (ogni vertice è un array [x, y, z])
Private Faces As Object[] ' Elenco delle facce (ogni faccia è un array di indici)
Private PerspectiveFactor As Float = 0.5 ' 0 = isometria, 1 = prospettiva completa
Public Sub Form_Open()
Me.Title = "Prisma esagonale rotante"
Me.Move(0, 0, Screen.AvailableWidth, Screen.AvailableHeight)
Me.Arrangement = Arrange.Fill
Vertices = New Object[] ' Inizializza la lista dei vertici
Faces = New Object[] ' Inizializza la lista delle facce
' === COSTRUZIONE VERTICI ===
Dim i As Integer
Dim angle As Float
Dim r As Float = 1.0 ' Raggio dell'esagono (distanza dal centro)
Dim h As Float = 1.5 ' Metà altezza del prisma (da -h a +h)
' Esagono superiore (z = +h):
For i = 0 To 5
angle = i * 2 * Pi / 6
Vertices.Push([r * Cos(angle), r * Sin(angle), h])
Next
' Esagono inferiore (z = -h):
For i = 0 To 5
angle = i * 2 * Pi / 6
Vertices.Push([r * Cos(angle), r * Sin(angle), -h])
Next
' === DEFINIZIONE DELLE FACCE ===
' Faccia superiore (esagono):
Faces.Push([0, 1, 2, 3, 4, 5])
' Faccia inferiore (invertita per corretto orientamento visivo):
Faces.Push([11, 10, 9, 8, 7, 6])
' 6 facce laterali rettangolari tra i vertici superiore e inferiore:
For i = 0 To 5
Dim nextI As Integer = (i + 1) Mod 6
Faces.Push([i, nextI, nextI + 6, i + 6])
Next
' Avvia il timer per animare la rotazione (~60 fotogrammi al secondo):
Timer1.Delay = 16
Timer1.Start
End
Public Sub Timer1_Timer()
angleY += 0.025 ' Rotazione continua sull’asse Y
DrawingArea1.Refresh ' Richiede il ridisegno della scena
End
Public Sub DrawingArea1_Draw()
' Centro della DrawingArea (per centrare la proiezione):
Dim w As Integer = DrawingArea1.W
Dim h As Integer = DrawingArea1.H
Dim cx As Float = w / 2
Dim cy As Float = h / 2
Dim points As Object[] = New Object[] ' Lista dei punti proiettati 2D
' === PROIEZIONE 3D → 2D PER OGNI VERTICE ===
For Each v As Float[] In Vertices
Dim x, y, z As Float
x = v[0]
y = v[1]
z = v[2]
' ROTAZIONE SULL'ASSE Y
Dim x1 As Float = x * Cos(angleY) + z * Sin(angleY)
Dim z1 As Float = -x * Sin(angleY) + z * Cos(angleY)
x = x1
z = z1
' PROIEZIONE PROSPETTICA INTERPOLATA
If (z + 3) < 0.1 Then
points.Push([cx, cy]) ' Punto neutro di sicurezza
Continue
Endif
Dim scale As Float = Zoom / (1 + PerspectiveFactor * (z + 3))
Dim sx As Float = cx + x * scale
Dim sy As Float = cy - y * scale
points.Push([sx, sy]) ' Aggiunge punto proiettato alla lista
Next
' === DISEGNO DELLE FACCE ===
Paint.Brush = Paint.Color(Color.Black)
For Each f As Integer[] In Faces
Dim i As Integer
For i = 0 To f.Count - 1
Dim p1 As Float[] = points[f[i]]
Dim p2 As Float[] = points[(f[(i + 1) Mod f.Count])]
Paint.MoveTo(p1[0], p1[1])
Paint.LineTo(p2[0], p2[1])
Paint.Stroke
Next
Next
End
Public Sub Form_KeyPress() ' ZOOM CON TASTIERA
Select Case Key.Code
Case Key["+"]
Zoom = Min(Zoom + 25, 1000) ' Ingrandisce
Case Key["-"]
Zoom = Max(Zoom - 25, 25) ' Rimpicciolisce
End Select
DrawingArea1.Refresh
End