Ruotare qualsiasi elemento da disegnare in una DrawingArea

Da Gambas-it.org - Wikipedia.

Per ottenere la rotazione di un qualsiasi elemento da disegnare (carattere alfanumerico, linee, disegni vari, immagini, etc.) in una "DrawingArea" (e comunque in qualunque altro Oggetto grafico disegnabile: "Image", "Picture", "ScrollArea"), è necessario considerare almeno tre aspetti:

  • l'angolo di rotazione del disegno da ruotare;
  • la posizione del centro di rotazione (ossia il punto intorno al quale il disegno ruoterà) sulla superficie dell'Oggetto grafico disegnabile;
  • la distanza orizzontale e verticale del disegno dal suo centro di rotazione.

Tali aspetti vengono gestiti mediante alcuni Metodi della Classe "Paint" [nota 1], e in particolare:

1) l'angolo di rotazione è gestito dal Metodo "Paint.Rotate()";
2) la posizione del centro di rotazione è gestita dal Metodo "Paint.Translate()";
3) la distanza orizzontale e verticale del disegno dal suo centro di rotazione è gestita dagli argomenti "x" e "y" (ossia dal 2° e dal 3° parametro) dei Metodi per disegnare qualcosa (ad esempio ".DrawText()" con "Paint").

Il Metodo "Paint.Rotate()" quale motore della rotazione di ciò che viene disegnato

La rotazione di uno o più caratteri, come di ogni altro elemento da disegnare all'interno di un Oggetto grafico disegnabile ("DrawingArea", "Image", "Picture"), è effettuata attraverso il il Metodo ".Rotate()" della Classe "Paint".

Va precisto e ricordato che la rotazione con il Metodo ".Rotate()" di un elemento da disegnare avviene attorno a un punto di rotazione che rappresenta il centro di una circonferenza ideale. Si può far ruotare dunque il disegno lungo tale circonferenza, il cui centro è in modalità predefinita il vertice individuato dalle coordinate x=0, y=0 dell'Oggetto grafico disegnabile, ossia attorno al vertice superiore sinistro dell'Oggetto.
Inoltre, il 2° e il 3° parametro dei Metodi della Classe "Paint", come già detto, impongono semplicemente la distanza orizzontale e verticale dell'elemento da disegnare dal predetto centro di rotazione.

Mostriamo un semplice esempio dimostrativo, nel quale si farà ruotare un carattere alfabetico attorno al centro di rotazione predefinito (coordinate x= 0, y=0 della "DrawingArea").

Private DrawingArea1 As DrawingArea
Private Slider1 As Slider
 
 
Public Sub Form_Open()
 
 With Me
   .W = Screen.AvailableWidth * 0.5
   .H = Screen.AvailableHeight * 0.5
   .Center
 End With
 With DrawingArea1 = New DrawingArea(Me) As "DrawingArea1"
   .X = 0
   .Y = 0
   .W = Me.W * 0.8
   .H = Me.H
   .Background = Color.Orange
 End With
 With Slider1 = New Slider(Me) As "Slider1"
   .X = Me.W * 0.85
   .Y = Me.H * 0.02
   .W = Me.W * 0.1
   .H = Me.H * 0.95
   .MinValue = 0
   .MaxValue = 360
 End With
  
End
 

Public Sub DrawingArea1_Draw()
 
 Dim testo As String = "Gambas " & CStr(Slider1.Value) & "°"
 
 With Paint
' Impone la rotazione di tutto ciò che viene disegnato a seguire:
   .Rotate(Rad(Slider1.Value))
   .Brush = Paint.Color(Color.Yellow)
   .Font = Font["Sans Serif, 24"]
' Il carattere alfabetico ruoterà intorno al vertice in alto a sinistra della "DrawingArea":
   .DrawText(testo, 100, 100, .Font.TextWidth(testo), .Font.TextHeight(testo), Align.Center)
   .End
 End With
 
End
 

Public Sub Slider1_Change()
 
 DrawingArea1.Refresh
 
End


Modificare la posizione del centro di rotazione di ciò che si deve disegnare sulla superficie dell'Oggetto grafico utilizzato

Per modificare la posizione (ossia le coordinate) standard dell'elemento da disegnare sulla superficie del suo Oggetto grafico, si dovrà utilizzare il Metodo ".Translate()" della Classe "Paint".
In sostanza il Metodo ".Translate()" non trasferisce semplicemente la posizione (ossia le coordinate) di quanto deve essere disegnato sulla "DrawingArea" (poiché tale spostamento è ottenuto modificando - come sappiamo - gli argomenti "x" e "y" - ossia il 2° e il 3° parametro - dei Metodi della Classe "Paint" per disegnare - ad esempio ".DrawText()" - restando quindi comunque le coordinate "x=0" e "y=0 della "DrawingArea" come punto/centro di rotazione intorno al quale - simile al centro di una circonferenza immaginaria - ruota ciò che deve essere disegnato), bensì esso trasferisce il "centro di rotazione" dalle predette coordinate predefinite "x=0" e "y=0 della "DrawingArea" a quelle prescelte e impostate dal codice.

Nel seguente esempio, simile al precedente, il testo ruoterà intorno al suo centro, posto al centro della "DrawingArea". Il centro del testo diventa esso stesso il "centro di rotazione" del testo che sarà disegnato.

Private DrawingArea1 As DrawingArea
Private Slider1 As Slider
 
 
Public Sub Form_Open()
 
 With Me
   .W = Screen.AvailableWidth * 0.5
   .H = Screen.AvailableHeight * 0.5
   .Center
 End With
 With DrawingArea1 = New DrawingArea(Me) As "DrawingArea1"
   .X = 0
   .Y = 0
   .W = Me.W * 0.8
   .H = Me.H
   .Background = Color.Orange
 End With
 With Slider1 = New Slider(Me) As "Slider1"
   .X = Me.W * 0.85
   .Y = Me.H * 0.02
   .W = Me.W * 0.1
   .H = Me.H * 0.95
   .MinValue = 0
   .MaxValue = 360
 End With
  
End
 

Public Sub DrawingArea1_Draw()
 
 Dim testo As String = "Gambas " & CStr(Slider1.Value) & "°"
 
 With Paint
' Impone la rotazione del testo, disegnato, sempre al centro della "DrawingARea":
   .Translate(DrawingArea1.W / 2, DrawingArea1.H / 2)
   .Rotate(Rad(-Slider1.Value))
   .Brush = Paint.Color(Color.Yellow)
   .Font = Font["Sans Serif, 22"]
' Il testo ruoterà comunque intorno al suo centro verticale e orizzontale:
   .DrawText(testo, -Paint.TextExtents(testo).W / 2, Paint.TextExtents(testo).H / 2, -.TextExtents(testo).W / 2, -.TextExtents(testo).H / 2, Align.Center)
' oppure anche così:
' .DrawText(testo, -.Font.TextWidth(testo) / 2, -.Font.TextHeight(testo) / 2, .Font.TextWidth(testo), .Font.TextHeight(testo), Align.Center)
    .End
 End With
 
End
 

Public Sub Slider1_Change()
 
 DrawingArea1.Refresh
 
End


Note

[1] Vedere anche queste pagine: