Ruotare un triangolo in una DrawingArea: differenze tra le versioni
Nessun oggetto della modifica |
Nessun oggetto della modifica |
||
| Riga 750: | Riga 750: | ||
<FONT Color=gray>' ''Trasla e scala nel sistema di coordinate della DrawingArea:''</font> | <FONT Color=gray>' ''Trasla e scala nel sistema di coordinate della DrawingArea:''</font> | ||
Return New PointF(cx + x2D * 100, cy - y2D * 100) | Return New PointF(cx + x2D * 100, cy - y2D * 100) <FONT Color=gray>' ''*100 = scala visiva''</font> | ||
End | End | ||
Versione delle 23:12, 27 lug 2025
Mostriamo due possibili codice per far ruotare su se stesso un Triangolo disegnato su una DrawingArea. [Nota 1]
Rotazione in 2D
Ruotare un Triangolo intorno al suo Baricentro
Di seguito mostreremo un possibile codice per ruotare un Triangolo intorno al suo Baricentro.
Il fulcro del Metodo ".Translate()" agisce da vortice, ossia da centro di rotazione intorno a una ipotetica circonferenza.
La rotazione del triangolo viene effettuata premendo i tasti freccia in su e freccia in giù della tastiera oppure ruotando la rotellina del mouse.
Private DrawingArea1 As DrawingArea
' Imposta le coordinate dei tre vertici del triangolo, con il primo vertice nel punto di rotazione (0, 0):
Private ABC As Single[] = [0, 0, 200, 0, 100, 300]
' Calcoli per ottenere il "Baricentro" del triangolo:
Private xb As Single = (ABC[0] + ABC[2] + ABC[4]) / 3
Private yb As Single = (ABC[1] + ABC[3] + ABC[5]) / 3
' Memorizza i gradi dell'angolo:
Private ang As Float
Private c As Integer[] = [Color.Blue, Color.Green, Color.Yellow, Color.Red]
Private f As Float[] = [0, 0.34, 0.67, 1]
Public Sub Form_Open()
With Me
.W = Screen.AvailableWidth
.H = Screen.AvailableHeight
.Arrangement = Arrange.Fill
End With
With DrawingArea1 = New DrawingArea(Me) As "DrawingArea1"
.Background = Color.White
End With
End
Public Sub DrawingArea1_Draw()
With Paint
.Brush = .LinearGradient(0, 20, 15, 0, c, f)
' Imposta il fulcro/punto della rotazione - ad esempio - al centro dell'area di disegno:
.Translate(DrawingArea1.W / 2, DrawingArea1.H / 2)
.Rotate(Rad(ang))
.LineWidth = 2.0
' Disegna il Triangolo.
' Siccome l'angolo ruota su se stesso, avendo come centro di rotazione il proprio "Baricentro", ad ogni coordinata del punto, che costituisce un elemento del vettore del Metodo ".Polygon()", si sottrae il valore della corrispondente coordinata del punto del Baricentro. In questo modo si farà coincidere l'angolo di rotazione con il "Baricentro" del Triangolo.
' Non si devono modificare i valori né i segni dei quattro argomenti qui riportati.
.Polygon([ABC[0] - xb, ABC[1] - yb, ABC[2] - xb, ABC[3] - yb, ABC[4] - xb, ABC[5] - yb])
.Stroke
.End
End With
End
Public Sub Form_KeyPress()
Select Case Key.Code
Case Key.Up
ang += 1
If ang = 361 Then ang = 1
Case Key.Down
ang -= 1
If ang = -361 Then ang = -1
End Select
DrawingArea1.Refresh
End
Public Sub Form_MouseWheel()
ang += Mouse.Delta
Select Case ang
Case 361
ang = 1
Case -361
ang = -1
End Select
DrawingArea1.Refresh
End
Public Sub Form_Resize() ' Con questo evento se cambia la dimensione del Form, il disegno non va perso.
DrawingArea1.Refresh
End
oppure anche questo codice:
Private DrawingArea1 As DrawingArea
Private Timer1 As Timer
Private rotationAngle As Float
Public Sub Form_Open()
With Me
.Move(0, 0, Screen.AvailableWidth, Screen.AvailableHeight)
.Arrangement = Arrange.Fill
End With
With DrawingArea1 = New DrawingArea(Me) As "DrawingArea1"
.Background = Color.Lighter(Color.White)
End With
Timer1 = New Timer As "Timer1"
Timer1.Delay = 30
Timer1.Start()
End
Public Sub Timer1_Timer()
rotationAngle += Rad(2) ' ruota di 2 gradi ogni frame
If rotationAngle >= 2 * Pi Then
rotationAngle -= 2 * Pi
End If
DrawingArea1.Refresh()
End
Public Sub DrawingArea1_Draw()
Dim cx As Float = DrawingArea1.W / 2
Dim cy As Float = DrawingArea1.H / 2
Dim size As Float = Min(DrawingArea1.W, DrawingArea1.H) * 0.4
' Definisci i vertici del triangolo (posizionati attorno a (0,0)):
Dim points As New PointF[3]
points[0] = New PointF(0, -size / 2) ' vertice superiore
points[1] = New PointF(-size / 2, size / 2) ' vertice basso sinistro
points[2] = New PointF(size / 2, size / 2) ' vertice basso destro
' Calcola baricentro (centroide):
Dim centroidX As Float = 0
Dim centroidY As Float = 0
For i As Integer = 0 To 2
centroidX += points[i].X
centroidY += points[i].Y
Next
centroidX /= 3
centroidY /= 3
' Ruota i punti attorno al baricentro e trasla al centro DrawingArea:
For i As Integer = 0 To 2
Dim xOld As Float = points[i].X - centroidX
Dim yOld As Float = points[i].Y - centroidY
points[i].X = xOld * Cos(rotationAngle) - yOld * Sin(rotationAngle) + centroidX + cx
points[i].Y = xOld * Sin(rotationAngle) + yOld * Cos(rotationAngle) + centroidY + cy
Next
With Paint
.Brush = Paint.Color(Color.Black)
.LineWidth = 2
.MoveTo(points[0].X, points[0].Y)
For i As Integer = 1 To 2
.LineTo(points[i].X, points[i].Y)
Next
.LineTo(points[0].X, points[0].Y)
.Stroke
' Punto nero sul baricentro (traslato):
.Arc(cx + centroidX, cy + centroidY, 5, Rad(0), Rad(360), False)
.Fill
End With
End
Il seguente codice disegna e ruota un Triangolo scaleno intorno al suo Baricentro:
Private DrawingArea1 As DrawingArea
Private Timer1 As Timer
Private rotationAngle As Float
Public Sub Form_Open()
With Me
.Move(0, 0, Screen.AvailableWidth, Screen.AvailableHeight)
.Arrangement = Arrange.Fill
End With
With DrawingArea1 = New DrawingArea(Me) As "DrawingArea1"
.Background = Color.Lighter(Color.White)
End With
Timer1 = New Timer As "Timer1"
Timer1.Delay = 30
Timer1.Start()
End
Public Sub Timer1_Timer()
rotationAngle += Rad(2)
If rotationAngle >= 2 * Pi Then
rotationAngle -= 2 * Pi
End If
DrawingArea1.Refresh()
End
Public Sub DrawingArea1_Draw()
Dim cx As Float = DrawingArea1.W / 2
Dim cy As Float = DrawingArea1.H / 2
' Vertici di un triangolo scaleno (modificabili):
Dim points As New PointF[3]
points[0] = New PointF(-160, -80) ' 'Vertice A
points[1] = New PointF(210, 50) ' 'Vertice B
points[2] = New PointF(50, 190) ' 'Vertice C
' Calcola il baricentro (media delle coordinate):
Dim baryX As Float = (points[0].X + points[1].X + points[2].X) / 3
Dim baryY As Float = (points[0].Y + points[1].Y + points[2].Y) / 3
' Ruota i punti attorno al baricentro:
For i As Integer = 0 To 2
Dim xOld As Float = points[i].X - baryX
Dim yOld As Float = points[i].Y - baryY
points[i].X = xOld * Cos(rotationAngle) - yOld * Sin(rotationAngle) + baryX
points[i].Y = xOld * Sin(rotationAngle) + yOld * Cos(rotationAngle) + baryY
' Trasla il triangolo per centrarlo nella DrawingArea:
points[i].X += cx
points[i].Y += cy
Next
With Paint
.Brush = Paint.Color(Color.Black)
.LineWidth = 2
' Disegna il triangolo:
.MoveTo(points[0].X, points[0].Y)
For i As Integer = 1 To 2
.LineTo(points[i].X, points[i].Y)
Next
.LineTo(points[0].X, points[0].Y)
.Stroke
' Disegna il punto nero sul baricentro traslato correttamente:
.Arc(cx + baryX, cy + baryY, 5, Rad(0), Rad(360), False)
.Fill
End With
End
Ruotare un Triangolo intorno al suo Incentro
Quest'altro codice servirà per far ruotare un Triangolo intorno al suo Incentro.
La rotazione del triangolo viene effettuata premendo i tasti freccia in su e freccia in giù della tastiera oppure ruotando la rotellina del mouse.
Il fulcro del Metodo ".Translate()" agisce da vortice, ossia da centro di rotazione intorno a una ipotetica circonferenza.
Private DrawingArea1 As DrawingArea ' Imposta le coordinate dei tre vertici del triangolo, con il primo vertice nel punto di rotazione (0, 0): Private ABC As Single[] = [0, 0, 200, 0, 100, 300] ' Calcola la distanza euclidea fra due punti, per ottenere la lunghezza di ciascun lato del triangolo: Private ab As Single = Sqr(((ABC[2] - ABC[0]) ^ 2) + ((ABC[3] - ABC[1]) ^ 2)) Private bc As Single = Sqr(((ABC[4] - ABC[2]) ^ 2) + ((ABC[5] - ABC[3]) ^ 2)) Private ac As Single = Sqr(((ABC[4] - ABC[0]) ^ 2) + ((ABC[5] - ABC[1]) ^ 2)) ' Calcoli per ottenere il "Incentro" del triangolo: Private ix As Single = ((ab * ABC[4]) + (bc * ABC[0]) + (ac * ABC[2])) / (ab + bc + ac) Private iy As Single = ((ab * ABC[5]) + (bc * ABC[1]) + (ac * ABC[3])) / (ab + bc + ac) ' Memorizza i gradi dell'angolo: Private ang As Float Private c As Integer[] = [Color.Blue, Color.Green, Color.Yellow, Color.Red] Private f As Float[] = [0, 0.34, 0.67, 1] Public Sub Form_Open() With Me .W = Screen.AvailableWidth .H = Screen.AvailableHeight .Arrangement = Arrange.Fill End With With DrawingArea1 = New DrawingArea(Me) As "DrawingArea1" .Background = Color.White End With End Public Sub DrawingArea1_Draw() With Paint .Brush = .LinearGradient(0, 20, 15, 0, c, f) ' Imposta il fulcro/punto della rotazione - ad esempio - al centro dell'area di disegno: .Translate(DrawingArea1.W / 2, DrawingArea1.H / 2) .Rotate(Rad(ang)) .LineWidth = 2.0 ' Disegna il Triangolo. ' Siccome l'angolo ruota su se stesso, avendo come centro di rotazione il proprio "Incentro", ad ogni coordinata del punto, che costituisce un elemento del vettore del Metodo ".Polygon()", si sottrae il valore della corrispondente coordinata del punto dell'Incentro. In questo modo si farà coincidere l'angolo di rotazione con il "Incentro" del Triangolo. ' Non si devono modificare i valori né i segni dei quattro argomenti qui riportati. .Polygon([ABC[0] - ix, ABC[1] - iy, ABC[2] - ix, ABC[3] - iy, ABC[4] - ix, ABC[5] - iy]) .Stroke .End End With End Public Sub Form_KeyPress() Select Case Key.Code Case Key.Up ang += 1 If ang = 361 Then ang = 1 Case Key.Down ang -= 1 If ang = -361 Then ang = -1 End Select DrawingArea1.Refresh End Public Sub Form_MouseWheel() ang += Mouse.Delta Select Case ang Case 361 ang = 1 Case -361 ang = -1 End Select DrawingArea1.Refresh End Public Sub Form_Resize() ' Con questo evento se cambia la dimensione del Form, il disegno non va perso. DrawingArea1.Refresh End
oppure quest'altro codice:
Private DrawingArea1 As DrawingArea
Private Timer1 As Timer
Private rotationAngle As Float = 0
Public Sub Form_Open()
With Me
.Move(0, 0, Screen.AvailableWidth, Screen.AvailableHeight)
.Arrangement = Arrange.Fill
End With
With DrawingArea1 = New DrawingArea(Me) As "DrawingArea1"
.Background = Color.Lighter(Color.White)
End With
Timer1 = New Timer As "Timer1"
Timer1.Delay = 30
Timer1.Start()
End
Public Sub Timer1_Timer()
rotationAngle += Rad(2)
If rotationAngle >= 2 * Pi Then
rotationAngle -= 2 * Pi
End If
DrawingArea1.Refresh()
End
Public Sub DrawingArea1_Draw()
Dim cx As Float = DrawingArea1.W / 2
Dim cy As Float = DrawingArea1.H / 2
Dim base As Float = Min(DrawingArea1.W, DrawingArea1.H) * 0.5
Dim height As Float = base * 0.7
' Vertici triangolo isoscele (vertice in alto):
Dim points As New PointF[3]
points[0] = New PointF(0, -height / 2) ' vertice superiore A
points[1] = New PointF(-base / 2, height / 2) ' vertice basso sinistro B
points[2] = New PointF(base / 2, height / 2) ' vertice basso destro C
' Calcola lunghezze lati:
Dim a As Float = Sqr((points[1].X - points[2].X) ^ 2 + (points[1].Y - points[2].Y) ^ 2) ' BC
Dim b As Float = Sqr((points[0].X - points[2].X) ^ 2 + (points[0].Y - points[2].Y) ^ 2) ' AC
Dim c As Float = Sqr((points[0].X - points[1].X) ^ 2 + (points[0].Y - points[1].Y) ^ 2) ' AB
' Calcola l'Incentro:
Dim incentroX As Float = (a * points[0].X + b * points[1].X + c * points[2].X) / (a + b + c)
Dim incentroY As Float = (a * points[0].Y + b * points[1].Y + c * points[2].Y) / (a + b + c)
' Ruota attorno all'incentro e trasla nel centro DrawingArea:
For i As Integer = 0 To 2
Dim xOld As Float = points[i].X - incentroX
Dim yOld As Float = points[i].Y - incentroY
points[i].X = xOld * Cos(rotationAngle) - yOld * Sin(rotationAngle) + incentroX + cx
points[i].Y = xOld * Sin(rotationAngle) + yOld * Cos(rotationAngle) + incentroY + cy
Next
With Paint
.Brush = Paint.Color(Color.Black)
.LineWidth = 2
.MoveTo(points[0].X, points[0].Y)
For i As Integer = 1 To 2
.LineTo(points[i].X, points[i].Y)
Next
.LineTo(points[0].X, points[0].Y)
.Stroke
' Punto nero sul incentro:
.Arc(cx + incentroX, cy + incentroY, 5, Rad(0), Rad(360), False)
.Fill
End With
End
Il seguente codice disegna e ruota un Triangolo scaleno intorno al suo Incentro:
Private DrawingArea1 As DrawingArea
Private Timer1 As Timer
Private rotationAngle As Float
Public Sub Form_Open()
With Me
.Move(0, 0, Screen.AvailableWidth, Screen.AvailableHeight)
.Arrangement = Arrange.Fill
End With
With DrawingArea1 = New DrawingArea(Me) As "DrawingArea1"
.Background = Color.Lighter(Color.White)
End With
Timer1 = New Timer As "Timer1"
Timer1.Delay = 30
Timer1.Start()
End
Public Sub Timer1_Timer()
rotationAngle += Rad(2)
If rotationAngle >= 2 * Pi Then
rotationAngle -= 2 * Pi
End If
DrawingArea1.Refresh()
End
Public Sub DrawingArea1_Draw()
Dim cx As Float = DrawingArea1.W / 2
Dim cy As Float = DrawingArea1.H / 2
' Vertici di un triangolo scaleno senza angoli retti:
Dim points As New PointF[3]
points[0] = New PointF(-160, -80) ' Vertice A
points[1] = New PointF(210, 50) ' Vertice B
points[2] = New PointF(50, 190) ' Vertice C
' Calcola le lunghezze dei lati:
Dim a As Float = Sqr((points[1].X - points[2].X) ^ 2 + (points[1].Y - points[2].Y) ^ 2) ' BC
Dim b As Float = Sqr((points[0].X - points[2].X) ^ 2 + (points[0].Y - points[2].Y) ^ 2) ' AC
Dim c As Float = Sqr((points[0].X - points[1].X) ^ 2 + (points[0].Y - points[1].Y) ^ 2) ' AB
' Calcola l'incentro:
Dim incentroX As Float = (a * points[0].X + b * points[1].X + c * points[2].X) / (a + b + c)
Dim incentroY As Float = (a * points[0].Y + b * points[1].Y + c * points[2].Y) / (a + b + c)
' Ruota i punti attorno all'incentro e trasla nel centro della DrawingArea:
For i As Integer = 0 To 2
Dim xOld As Float = points[i].X - incentroX
Dim yOld As Float = points[i].Y - incentroY
points[i].X = xOld * Cos(rotationAngle) - yOld * Sin(rotationAngle) + incentroX + cx
points[i].Y = xOld * Sin(rotationAngle) + yOld * Cos(rotationAngle) + incentroY + cy
Next
With Paint
.Brush = Paint.Color(Color.Black)
.LineWidth = 2
' Disegna il triangolo:
.MoveTo(points[0].X, points[0].Y)
For i As Integer = 1 To 2
.LineTo(points[i].X, points[i].Y)
Next
.LineTo(points[0].X, points[0].Y)
.Stroke
' Disegna il punto nero sull'incentro:
.Arc(cx + incentroX, cy + incentroY, 5, Rad(0), Rad(360), False)
.Fill
End With
End
Rotazione in 3D
Rotazione 3D attorno all'asse Y
Nel seguente codice faremo ruotare un triangolo isoscele attorno all'asse Y (cioè in spazio 3D):
Private angle As Float ' Variabile globale per memorizzare l'angolo corrente della rotazione Public Sub Form_Open() With Me .Title = "Rotazione di un Triangolo isoscele attorno all'asse Y" .Move(0, 0, Screen.AvailableWidth, Screen.AvailableHeight) .Arrangement = Arrange.Fill End With Timer1.Delay = 16 Timer1.Start() End Public Sub Timer1_Timer() ' Aumenta l’angolo di rotazione: angle += 2 If angle >= 360 Then angle = 0 ' Richiede il ridisegno della DrawingArea: DrawingArea1.Refresh End Public Sub DrawingArea1_Draw() ' Calcola il centro della DrawingArea: Dim cx As Float = DrawingArea1.Width / 2 Dim cy As Float = DrawingArea1.Height / 2 ' Parametri del triangolo: Dim baseHalf As Float = 1.0 ' Metà base Dim height As Float = 1.5 ' Altezza del triangolo Dim d As Float = 4.0 ' Distanza simulata dalla "camera", ossia dall'osservatore ' Angolo in radianti: Dim radAngle As Float = Rad(angle) ' Definizione dei 3 vertici del triangolo in coordinate 3D (x, y, z): Dim v1 As Float[] = [0.0, height / 2, 0.0] ' Vertice superiore Dim v2 As Float[] = [-baseHalf, -height / 2, 0.0] ' Vertice sinistro della base Dim v3 As Float[] = [baseHalf, -height / 2, 0.0] ' Vertice destro della base ' Applica la rotazione 3D attorno all’asse Y, quindi proietta in 2D: Dim p1 As PointF = Project3D(RotateY(v1, radAngle), d, cx, cy) Dim p2 As PointF = Project3D(RotateY(v2, radAngle), d, cx, cy) Dim p3 As PointF = Project3D(RotateY(v3, radAngle), d, cx, cy) ' Costruisce un array di coordinate [x0, y0, x1, y1, x2, y2]: Dim coords As Float[] = [p1.X, p1.Y, p2.X, p2.Y, p3.X, p3.Y] ' Disegna e riempie il triangolo: Paint.Brush = Paint.Color(Color.Red) ' Imposta il colore rosso Paint.Polygon(coords) ' Definisce la forma Paint.Fill() ' Riempe il triangolo Paint.End() ' Termina il disegno End Private Function RotateY(v As Float[], angle As Float) As Float[] ' Funzione che ruota un punto 3D attorno all’asse Y 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: Dim xr As Float = x * Cos(angle) + z * Sin(angle) Dim zr As Float = -x * Sin(angle) + z * Cos(angle) ' Restituisce il punto ruotato: Return [xr, y, zr] End Private Function Project3D(v As Float[], d As Float, cx As Float, cy As Float) As PointF ' Funzione che proietta un punto 3D nello spazio 2D (prospettiva) Dim x As Float = v[0] Dim y As Float = v[1] Dim z As Float = v[2] ' Fattore di proiezione prospettica (più z è grande, più il punto è vicino): Dim factor As Float = d / (z + d + 0.001) ' +0.001 per evitare divisione per zero ' Coordinate proiettate in 2D: Dim x2D As Float = x * factor Dim y2D As Float = y * factor ' Trasla e scala nel sistema della DrawingArea (inverte Y per avere l'alto verso l'alto): Return New PointF(cx + x2D * 100, cy - y2D * 100) End
Rotazione 3D attorno agli assi X, Y e Z
Nel seguente codice faremo ruotare un triangolo isoscele attorno ai suoi assi X, Y e Z:
' Variabili globali per gli angoli di rotazione su ciascun asse: Private angleX As Float Private angleY As Float Private angleZ As Float Public Sub Form_Open() With Me .Title = "Rotazione di un Triangolo isoscele attorno agli assi X, Y e Z" .Move(0, 0, Screen.AvailableWidth, Screen.AvailableHeight) .Arrangement = Arrange.Fill End With Timer1.Delay = 16 Timer1.Start() End Public Sub Timer1_Timer() ' Aumenta l’angolo di rotazione: angleX += 1 ' Ruota di 1 grado sull'asse X angleY += 2 ' Ruota di 2 gradi sull'asse Y angleZ += 1.5 ' Ruota di 1.5 gradi sull'asse Z ' Richiede il ridisegno della DrawingArea: DrawingArea1.Refresh End Public Sub DrawingArea1_Draw() ' Centro della DrawingArea (origine della scena): Dim cx As Float = DrawingArea1.Width / 2 Dim cy As Float = DrawingArea1.Height / 2 ' Dimensioni del triangolo: Dim baseHalf As Float = 1.0 ' metà della base (±x) Dim height As Float = 1.5 ' altezza verticale Dim d As Float = 4.0 ' distanza "camera", ossia dell'osservatore, per simulare la prospettiva ' Converte gli angoli da gradi a radianti (richiesto per Sin/Cos): Dim ax As Float = Rad(angleX) Dim ay As Float = Rad(angleY) Dim az As Float = Rad(angleZ) ' Vertici iniziali del triangolo in 3D (sul piano XZ): Dim v1 As Float[] = [0.0, height / 2, 0.0] ' vertice superiore (centro in alto) Dim v2 As Float[] = [-baseHalf, -height / 2, 0.0] ' vertice base sinistra Dim v3 As Float[] = [baseHalf, -height / 2, 0.0] ' vertice base destra ' Applica rotazione 3D a ciascun vertice: prima X, poi Y, poi Z: v1 = RotateZ(RotateY(RotateX(v1, ax), ay), az) v2 = RotateZ(RotateY(RotateX(v2, ax), ay), az) v3 = RotateZ(RotateY(RotateX(v3, ax), ay), az) ' Proietta i vertici ruotati da 3D → 2D (con prospettiva): Dim p1 As PointF = Project3D(v1, d, cx, cy) Dim p2 As PointF = Project3D(v2, d, cx, cy) Dim p3 As PointF = Project3D(v3, d, cx, cy) ' Costruisce l'array di coordinate 2D [x0, y0, x1, y1, x2, y2]: Dim coords As Float[] = [p1.X, p1.Y, p2.X, p2.Y, p3.X, p3.Y] ' Disegna e riempie il triangolo con colore rosso: Paint.Brush = Paint.Color(Color.Red) Paint.Polygon(coords) ' Definisce il contorno Paint.Fill() ' Riempe il triangolo Paint.End() End Private Function RotateX(v As Float[], angle As Float) As Float[] ' Ruota un punto attorno all'asse X (varia y, z) Dim x As Float = v[0] Dim y As Float = v[1] Dim z As Float = v[2] 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 Private Function RotateY(v As Float[], angle As Float) As Float[] ' Ruota un punto attorno all'asse Y (varia x, z) Dim x As Float = v[0] Dim y As Float = v[1] Dim z As Float = v[2] 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 Private Function RotateZ(v As Float[], angle As Float) As Float[] ' Ruota un punto attorno all'asse Z (varia x, y) Dim x As Float = v[0] Dim y As Float = v[1] Dim z As Float = v[2] 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 Private Function Project3D(v As Float[], d As Float, cx As Float, cy As Float) As PointF ' Proietta un punto 3D in coordinate 2D con prospettiva Dim x As Float = v[0] Dim y As Float = v[1] Dim z As Float = v[2] ' Calcola il fattore di scala prospettico: Dim factor As Float = d / (z + d + 0.001) ' Evita divisione per 0 ' Proietta x e y in base alla profondità (z): Dim x2D As Float = x * factor Dim y2D As Float = y * factor ' Trasla e scala nel sistema di coordinate della DrawingArea: Return New PointF(cx + x2D * 100, cy - y2D * 100) ' *100 = scala visiva End
Note
[1] Vedere anche queste pagine: