Differenze tra le versioni di "Disegnare in una DrawingArea dei punti"
(5 versioni intermedie di uno stesso utente non sono mostrate) | |||
Riga 1: | Riga 1: | ||
=Istruzioni fondamentali per disegnare un punto su una ''DrawingArea''= | =Istruzioni fondamentali per disegnare un punto su una ''DrawingArea''= | ||
− | Per disegnare da codice dei punti su una ''DrawingArea'', si potrà fare uso dei seguenti Metodi | + | Per disegnare da codice dei punti su una ''DrawingArea'', si potrà fare uso dei seguenti Metodi della Classe ''Paint'' : <SUP>[[[#Note|nota 1]]]</sup> |
* Metodo ".Arc()"; | * Metodo ".Arc()"; | ||
* Metodo ".Ellipse()"; | * Metodo ".Ellipse()"; | ||
Riga 48: | Riga 48: | ||
− | + | Public Sub _new() | |
With Me | With Me | ||
Riga 59: | Riga 59: | ||
End With | End With | ||
− | + | End | |
+ | |||
− | + | Public Sub DrawingArea1_MouseWheel() | |
t += (Mouse.Delta) + (PASSO * Mouse.Delta) | t += (Mouse.Delta) + (PASSO * Mouse.Delta) | ||
Riga 67: | Riga 68: | ||
DrawingArea1.Refresh | DrawingArea1.Refresh | ||
− | + | End | |
− | + | ||
+ | Public Sub DrawingArea1_Draw() | ||
Dim x, y, r As Short | Dim x, y, r As Short | ||
Riga 84: | Riga 86: | ||
End With | End With | ||
− | + | End | |
===Con l'uso del ''Timer''=== | ===Con l'uso del ''Timer''=== | ||
Riga 93: | Riga 95: | ||
− | + | Public Sub _new() | |
With Me | With Me | ||
Riga 110: | Riga 112: | ||
End With | End With | ||
− | + | End | |
− | + | ||
+ | Public Sub Form_Open() | ||
With Me | With Me | ||
Riga 121: | Riga 124: | ||
Timer1.Start | Timer1.Start | ||
− | + | End | |
+ | |||
− | + | Public Sub Timer1_Timer() | |
DrawingArea1.Refresh() | DrawingArea1.Refresh() | ||
− | + | End | |
− | + | ||
+ | Public Sub DrawingArea1_Draw() | ||
Dim i As Short | Dim i As Short | ||
Riga 144: | Riga 149: | ||
If i > DrawingArea1.W Then c = 0 | If i > DrawingArea1.W Then c = 0 | ||
− | + | End | |
====Il punto percorre una traiettoria sinusoidale==== | ====Il punto percorre una traiettoria sinusoidale==== | ||
Riga 155: | Riga 160: | ||
− | + | Public Sub _new() | |
With Me | With Me | ||
Riga 171: | Riga 176: | ||
w = DrawingArea1.W | w = DrawingArea1.W | ||
− | + | End | |
+ | |||
− | + | Public Sub Form_Open() | |
With Me | With Me | ||
Riga 182: | Riga 188: | ||
Timer1.Start | Timer1.Start | ||
− | + | End | |
+ | |||
− | + | Public Sub Timer1_Timer() | |
Dec w | Dec w | ||
Riga 191: | Riga 198: | ||
DrawingArea1.Refresh() | DrawingArea1.Refresh() | ||
− | + | End | |
+ | |||
− | + | Public Sub DrawingArea1_Draw() | |
Dim y As Short | Dim y As Short | ||
Riga 215: | Riga 223: | ||
End With | End With | ||
− | + | End | |
===Usando un ciclo=== | ===Usando un ciclo=== | ||
Riga 246: | Riga 254: | ||
Do | Do | ||
Inc x | Inc x | ||
− | If x > DrawingArea1. | + | If Not Object.IsValid(DrawingArea1) Then Break |
+ | If x > DrawingArea1.W Then x = 0 | ||
DrawingArea1.Refresh | DrawingArea1.Refresh | ||
Wait 0.01 | Wait 0.01 | ||
Riga 275: | Riga 284: | ||
− | + | Public Sub Form_Open() | |
Dim c As Short | Dim c As Short | ||
Riga 298: | Riga 307: | ||
Wend | Wend | ||
− | + | End | |
+ | |||
− | + | Public Sub DrawingArea1_Draw() | |
With Paint | With Paint | ||
Riga 309: | Riga 319: | ||
End With | End With | ||
− | + | End | |
Riga 319: | Riga 329: | ||
− | + | Public Sub _new() | |
With Me | With Me | ||
Riga 330: | Riga 340: | ||
End With | End With | ||
− | + | End | |
− | + | ||
+ | Public Sub Form_Open() | ||
Me.Show | Me.Show | ||
Riga 350: | Riga 361: | ||
Until (p[0] == arrivo[0]) And (p[1] == arrivo[1]) <FONT Color=gray>' ''Si esce dal ciclo, quando il punto avrà raggiunto le coordinate di destinazione''</font> | Until (p[0] == arrivo[0]) And (p[1] == arrivo[1]) <FONT Color=gray>' ''Si esce dal ciclo, quando il punto avrà raggiunto le coordinate di destinazione''</font> | ||
− | + | End | |
− | + | ||
+ | Public Sub DrawingArea1_Draw() | ||
With Paint | With Paint | ||
Riga 361: | Riga 373: | ||
End With | End With | ||
− | + | End | |
==Visibili il punto corrente disegnato e tutti i punti precedentemente disegnati== | ==Visibili il punto corrente disegnato e tutti i punti precedentemente disegnati== | ||
In quest'altro caso, invece, resteranno <Span Style="text-decoration:underline">visibili</span> tutti i punti precedentemente disegnati e descriveranno andamento sinusoidale: | In quest'altro caso, invece, resteranno <Span Style="text-decoration:underline">visibili</span> tutti i punti precedentemente disegnati e descriveranno andamento sinusoidale: | ||
− | + | Public Sub DrawingArea1_Draw() | |
Dim x, y As Short | Dim x, y As Short | ||
Riga 382: | Riga 394: | ||
End With | End With | ||
− | + | End | |
− | |||
+ | ====Usando il Metodo ".FillRect()" della Classe ''Paint''==== | ||
In quest'altro esempio sarà usato il Metodo ".FillRect()" della Classe ''Paint'' e, per imporre il ritardo temporale nel disegno dei punti useremo il ''Timer''. | In quest'altro esempio sarà usato il Metodo ".FillRect()" della Classe ''Paint'' e, per imporre il ritardo temporale nel disegno dei punti useremo il ''Timer''. | ||
Private DrawingArea1 As DrawingArea | Private DrawingArea1 As DrawingArea | ||
Riga 391: | Riga 403: | ||
Private d As Short | Private d As Short | ||
− | + | Public Sub _new() | |
With Me | With Me | ||
Riga 402: | Riga 414: | ||
End With | End With | ||
− | + | End | |
+ | |||
− | + | Public Sub Form_Arrange() | |
pnt = New Short[] | pnt = New Short[] | ||
Riga 413: | Riga 426: | ||
End With | End With | ||
− | + | End | |
+ | |||
− | + | Public Sub Timer1_Timer() | |
DrawingArea1.Refresh() | DrawingArea1.Refresh() | ||
− | |||
− | |||
− | + | End | |
+ | |||
+ | |||
+ | Public Sub DrawingArea1_Draw() | ||
Dim c As Short | Dim c As Short | ||
Riga 436: | Riga 451: | ||
d += 4 | d += 4 | ||
− | + | End | |
====Disegnare punto per punto una Spirale di Archimede==== | ====Disegnare punto per punto una Spirale di Archimede==== | ||
− | In quest'altro esempio verrà riprodotta una [https://it.wikipedia.org/wiki/Spirale_archimedea Spirale di Archimede]: <SUP>[[[#Note|nota | + | In quest'altro esempio verrà riprodotta una [https://it.wikipedia.org/wiki/Spirale_archimedea Spirale di Archimede]: <SUP>[[[#Note|nota 2]]]</sup> |
Private DrAr As DrawingArea | Private DrAr As DrawingArea | ||
Private Const A As Float = 4.0 | Private Const A As Float = 4.0 | ||
Riga 448: | Riga 463: | ||
− | + | Public Sub Form_Open() | |
With Me | With Me | ||
Riga 459: | Riga 474: | ||
End With | End With | ||
− | + | End | |
+ | |||
+ | |||
+ | Public Sub DrawingArea1_Draw() | ||
− | |||
− | |||
Dim x, y As Integer | Dim x, y As Integer | ||
Dim i As Float | Dim i As Float | ||
− | + | ||
x = DrAr.W / 2 | x = DrAr.W / 2 | ||
y = DrAr.H / 2 | y = DrAr.H / 2 | ||
− | + | ||
With Paint | With Paint | ||
.Brush = .Color(Color.Red) | .Brush = .Color(Color.Red) | ||
Riga 478: | Riga 494: | ||
.End | .End | ||
End With | End With | ||
− | + | ||
− | + | End | |
====Disegnare punto per punto un cerchio==== | ====Disegnare punto per punto un cerchio==== | ||
Riga 499: | Riga 515: | ||
y + (r * Sin(Rad(t))) | y + (r * Sin(Rad(t))) | ||
Sarà utilizzato il Metodo "Paint.Arc()" per creare i punti: | Sarà utilizzato il Metodo "Paint.Arc()" per creare i punti: | ||
− | + | Public Sub DrawingArea1_Draw() | |
Dim x, y, r, t As Short | Dim x, y, r, t As Short | ||
Riga 516: | Riga 532: | ||
End With | End With | ||
− | + | End | |
Riga 526: | Riga 542: | ||
Private punti As New Short[] | Private punti As New Short[] | ||
− | + | Public Sub _new() | |
With Me | With Me | ||
Riga 537: | Riga 553: | ||
End With | End With | ||
− | + | End | |
+ | |||
− | + | Public Sub DrawingArea1_Draw() | |
Dim i As Integer | Dim i As Integer | ||
Riga 552: | Riga 569: | ||
End With | End With | ||
− | + | End | |
− | + | ||
+ | Public Sub DrawingArea1_MouseDown() | ||
StartX = Mouse.X | StartX = Mouse.X | ||
StartY = Mouse.Y | StartY = Mouse.Y | ||
− | + | End | |
'''Public''' Sub DrawingArea1_MouseUp() | '''Public''' Sub DrawingArea1_MouseUp() | ||
Riga 568: | Riga 586: | ||
DrawingArea1.Refresh() | DrawingArea1.Refresh() | ||
− | + | End | |
===Ottenere l'immagine di una linea disegnando più punti contigui in sequenza=== | ===Ottenere l'immagine di una linea disegnando più punti contigui in sequenza=== | ||
− | Per disegnare linee e punti su una ''DrawingArea'' <SUP>[[[#Note|nota | + | Per disegnare linee e punti su una ''DrawingArea'' <SUP>[[[#Note|nota 3]]]</sup>, è possibile usare il codice che segue. |
<BR><SPAN Style="text-decoration:underline">Tenendo premuto il tasto destro del mouse</span>, disegnare qualcosa nella ''DrawingArea''. | <BR><SPAN Style="text-decoration:underline">Tenendo premuto il tasto destro del mouse</span>, disegnare qualcosa nella ''DrawingArea''. | ||
Private DrawingArea1 As DrawingArea | Private DrawingArea1 As DrawingArea | ||
Riga 579: | Riga 597: | ||
− | + | Public Sub _new() | |
With Me | With Me | ||
Riga 590: | Riga 608: | ||
End With | End With | ||
− | + | End | |
+ | |||
− | + | Public Sub Form_Arrange() | |
DrawingArea1.Cursor = New Cursor(Picture["icon:/16/pen"], 2, 13) | DrawingArea1.Cursor = New Cursor(Picture["icon:/16/pen"], 2, 13) | ||
− | + | End | |
+ | |||
− | + | Public Sub DrawingArea1_Draw() | |
Dim i As Integer | Dim i As Integer | ||
Riga 611: | Riga 631: | ||
End With | End With | ||
− | + | End | |
− | + | ||
+ | Public Sub DrawingArea1_MouseDown() | ||
x = Mouse.X | x = Mouse.X | ||
y = Mouse.Y | y = Mouse.Y | ||
− | + | End | |
+ | |||
− | + | Public Sub DrawingArea1_MouseMove() | |
punti.Push(Mouse.X) | punti.Push(Mouse.X) | ||
Riga 627: | Riga 649: | ||
DrawingArea1.Refresh() | DrawingArea1.Refresh() | ||
− | + | End | |
− | + | ||
+ | Public Sub DrawingArea1_MouseUp() | ||
punti.Push(x) | punti.Push(x) | ||
Riga 636: | Riga 659: | ||
DrawingArea1.Refresh() | DrawingArea1.Refresh() | ||
− | + | End | |
Riga 649: | Riga 672: | ||
− | + | Public Sub _new() | |
With Me | With Me | ||
Riga 660: | Riga 683: | ||
End With | End With | ||
− | + | End | |
+ | |||
− | + | Public Sub Form_Arrange() | |
DrawingArea1.Cursor = New Cursor(Picture["icon:/16/pen"], 2, 13) | DrawingArea1.Cursor = New Cursor(Picture["icon:/16/pen"], 2, 13) | ||
− | + | End | |
+ | |||
− | + | Public Sub DrawingArea1_Draw() | |
Dim i As Integer | Dim i As Integer | ||
Riga 681: | Riga 706: | ||
End With | End With | ||
− | + | End | |
+ | |||
− | + | Public Sub DrawingArea1_MouseDown() | |
x = Mouse.X | x = Mouse.X | ||
y = Mouse.Y | y = Mouse.Y | ||
− | + | End | |
+ | |||
− | + | Public Sub DrawingArea1_MouseMove() | |
With punti | With punti | ||
Riga 700: | Riga 727: | ||
DrawingArea1.Refresh() | DrawingArea1.Refresh() | ||
− | + | End | |
+ | |||
− | + | Public Sub DrawingArea1_MouseUp() | |
<FONT Color=gray>' ''Se si clicca sul tasto centrale del mouse, si cambia colore, e, se si stava disegnando in rosso, si ottiene l'effetto gomma per cancellare; altrimenti si torna al colore rosso.''</font> | <FONT Color=gray>' ''Se si clicca sul tasto centrale del mouse, si cambia colore, e, se si stava disegnando in rosso, si ottiene l'effetto gomma per cancellare; altrimenti si torna al colore rosso.''</font> | ||
Riga 713: | Riga 741: | ||
Endif | Endif | ||
− | + | End | |
=Disegnare in una DrawingArea un punto con le funzioni esterne del API di X11= | =Disegnare in una DrawingArea un punto con le funzioni esterne del API di X11= | ||
Con le risorse del API di [https://tronche.com/gui/x/xlib/graphics/drawing/XDrawPoint.html X11] è possibile disegnare un punto colorato su una ''DrawingArea''. | Con le risorse del API di [https://tronche.com/gui/x/xlib/graphics/drawing/XDrawPoint.html X11] è possibile disegnare un punto colorato su una ''DrawingArea''. | ||
− | Sarà necessario richiamare in Gambas la libreria di X11: "''libX11.so.6.4.0'' " | + | Sarà necessario richiamare in Gambas la libreria di X11: "''libX11.so.6.4.0'' ". |
− | + | ||
Mostriamo un esempio pratico: | Mostriamo un esempio pratico: | ||
Library "libX11:6.4.0" | Library "libX11:6.4.0" | ||
Riga 748: | Riga 776: | ||
− | + | Public Sub Form_Open() | |
With DrawingArea1 | With DrawingArea1 | ||
Riga 758: | Riga 786: | ||
End With | End With | ||
− | + | End | |
− | + | Public Sub Button1_Click() | |
Dim dsp, gc As Pointer | Dim dsp, gc As Pointer | ||
Riga 781: | Riga 809: | ||
XCloseDisplay(dsp) | XCloseDisplay(dsp) | ||
− | + | End | |
− | Potrebbe accadere che alla prima pressione del ''Button'' non appaia il puntino giallo, ma che sia necessario un secondo clic. In tal caso, al fine di ottenere la comparsa del punto giallo al primo clic del ''Button'', è necessario porre una riga di comando | + | Potrebbe accadere che alla prima pressione del ''Button'' non appaia il puntino giallo, ma che sia necessario un secondo clic. In tal caso, al fine di evitare di dover cliccare due volte sul tasto del mouse e di ottenere così la comparsa del punto giallo al primo clic del ''Button'', è necessario porre una riga di comando: |
Wait 0.01 | Wait 0.01 | ||
− | o valore superiore dopo la riga di verifica della funzione "XCreateGC( | + | o valore superiore dopo la riga di verifica della funzione "XCreateGC()". |
=Note= | =Note= | ||
− | [1] Vedere anche questa pagina: [[Disegnare_in_una_DrawingArea_una_spirale#Disegnare_una_Spirale_Archimedea|Disegnare in una DrawingArea una spirale di Archimede]] | + | [1] Bisogna ricordare che la Classe "''Draw'' " è <SPAN Style="text-decoration:underline">obsoleta</span>. |
+ | |||
+ | [2] Vedere anche questa pagina: [[Disegnare_in_una_DrawingArea_una_spirale#Disegnare_una_Spirale_Archimedea|Disegnare in una DrawingArea una spirale di Archimede]] | ||
− | [ | + | [3] Vedere anche la seguente pagina: [[Disegnare in una DrawingArea più linee rette con il mouse]] |
Versione attuale delle 06:42, 16 ott 2024
Indice
- 1 Istruzioni fondamentali per disegnare un punto su una DrawingArea
- 2 Disegnare in successione dei punti in una DrawingArea
- 3 Disegnare punti con il mouse in una DrawingArea
- 4 Disegnare in una DrawingArea un punto con le funzioni esterne del API di X11
- 5 Note
Istruzioni fondamentali per disegnare un punto su una DrawingArea
Per disegnare da codice dei punti su una DrawingArea, si potrà fare uso dei seguenti Metodi della Classe Paint : [nota 1]
- Metodo ".Arc()";
- Metodo ".Ellipse()";
- Metodo ".FillRect()";
- Metodo ".Rectangle()".
Mostriamo un semplice esempio, nel quale si mostrerà l'uso dei predetti quattro Metodi:
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 = .Color(Color.Red) .Arc(200, 200, 2, Rad(0), Rad(360), False) .Fill .Brush = .Color(Color.Blue) .Ellipse(400, 400, 2, 2, Rad(0), Rad(360), False) .Brush = .Color(Color.Orange) .Rectangle(500, 200, 2, 2, 0.0) .Fill .FillRect(600, 200, 2, 2, Color.Green) .End End With End
Disegnare in successione dei punti in una DrawingArea
Visibile soltanto il punto corrente disegnato usando la Classe Paint
In questo caso si utilizzerà la Classe Paint e verrà mostrato soltanto il nuovo punto disegnato: quelli precedentemente disegnati non saranno più visibili.
Nell'esempio che segue, ruotando la rotellina del mouse avanti o indietro sulla DrawingArea saranno mostrati in successione dei punti lungo la circonferenza di un cerchio predefinito dal codice. L'effetto visivo ottenuto, sarà quello di un punto che si sposta lungo una circonferenza immaginaria.
Private DrawingArea1 As DrawingArea Private Const PASSO As Byte = 2 Private t As Short Public Sub _new() 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_MouseWheel() t += (Mouse.Delta) + (PASSO * Mouse.Delta) DrawingArea1.Refresh End Public Sub DrawingArea1_Draw() Dim x, y, r As Short x = DrawingArea1.W / 2 y = DrawingArea1.H / 2 r = 100 With Paint .Brush = .Color(Color.Red) .Arc(x + (r * Cos(Rad(t))), y + (r * Sin(Rad(t))), 2, Rad(0), Rad(360), False) .Fill .End End With End
Con l'uso del Timer
In quest'altro caso imporremo un ritardo temporale nel disegno dei punti con l'uso dell'oggetto Timer:
Private DrawingArea1 As DrawingArea Private Timer1 As Timer Private c As Short Public Sub _new() With Me .W = Screen.AvailableWidth * 0.7 .H = Screen.AvailableHeight * 0.75 End With With DrawingArea1 = New DrawingArea(Me) As "DrawingArea1" .X = 0 .Y = Me.H * 0.15 .W = Me.Width .H = Me.H * 0.7 .Background = &FFFFBF End With With Timer1 = New Timer As "Timer1" .Delay = 500 ' Ritardo = 0,5 secondi End With End Public Sub Form_Open() With Me .Center .Y = Screen.AvailableHeight * 0.1 End With Timer1.Start End Public Sub Timer1_Timer() DrawingArea1.Refresh() End Public Sub DrawingArea1_Draw() Dim i As Short i = 50 * c With Paint .FillRect(i, 100, 3, 3, Color.Red) .End End With Inc c If i > DrawingArea1.W Then c = 0 End
Il punto percorre una traiettoria sinusoidale
In quest'altro esempio usando il Timer il punto percorrerà una traiettoria sinusoidale:
Private DrawingArea1 As DrawingArea Private Timer1 As Timer Private Const FREQUENZA As Float = 440.0 Private w As Short Private t As Short Public Sub _new() With Me .W = Screen.AvailableWidth .H = Screen.AvailableHeight .Arrangement = Arrange.Fill End With With DrawingArea1 = New DrawingArea(Me) As "DrawingArea1" .Background = &FFFFBF End With With Timer1 = New Timer As "Timer1" .Delay = 10 ' Ritardo = 0,01 secondi End With w = DrawingArea1.W End Public Sub Form_Open() With Me .Center .Y = Screen.AvailableHeight * 0.1 End With Timer1.Start End Public Sub Timer1_Timer() Dec w If w == 0 Then w = DrawingArea1.W DrawingArea1.Refresh() End Public Sub DrawingArea1_Draw() Dim y As Short Dim d As Short Inc t ' s = A * sin(2π*(1/T)*t) ' https://www.youtube.com/watch?v=YijlJ2Ekj4k y = DrawingArea1.H / 2 * Sin(((2 * Pi) * (1 / FREQUENZA)) * t) ' Centra l'onda nel mezzo della "DrawingArea": y += DrawingArea1.H / 2 d = Ceil(DrawingArea1.W / DrawingArea1.Font.TextWidth("- ")) + 2 With Paint .FillRect(w, y, 4, 4, Color.Red) .DrawText(String(d, "- "), 0, DrawingArea1.H / 2, d, 3, Align.Left) .End End With End
Usando un ciclo
Invece dell'Oggetto "Timer" si potrà usare anche un ciclo.
Il punto percorre una traiettoria sinusoidale
Private DrawingArea1 As DrawingArea Private Const AMPIEZZA As Float = 100.0 Private Const FREQUENZA As Float = 440.0 Private t As Integer Private x As Integer 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_MouseUp() Do Inc x If Not Object.IsValid(DrawingArea1) Then Break If x > DrawingArea1.W Then x = 0 DrawingArea1.Refresh Wait 0.01 Loop End Public Sub DrawingArea1_Draw() Dim y, f As Float f = 1 / FREQUENZA Inc t y = AMPIEZZA * Sin(2 * Pi * f * t) ' Centra l'onda nel mezzo della "DrawingArea": y += DrawingArea1.H / 2 With Paint .FillRect(x, y, 4, 4, Color.Red) .End End With End
Altri tipi di esempi
In quest'altro esempio verrà disegnato un punto rosso che mediante l'uso della funzione "Cos()" si sposterà in orizzontale oscillando da un estremo all'altro della DrawingArea.
Private DrawingArea1 As DrawingArea Private f As Float Public Sub Form_Open() Dim c As Short With Me .W = Screen.AvailableWidth .H = Screen.AvailableHeight .Arrangement = Arrange.Fill End With With DrawingArea1 = New DrawingArea(Me) As "DrawingArea1" .Background = Color.SoftYellow End With Me.Show ' Esegue un ciclo infinito sin tanto che l'Oggetto "DrawingArea" è valido: se la finestra del "Form" viene chiusa, allora l'Oggetto "DrawingArea" viene distrutto e, non essendo esso più valido, si esce dal ciclo: While Object.IsValid(DrawingArea1) f = Cos(Rad(c)) * (DrawingArea1.W / 2) DrawingArea1.Refresh Wait 0.01 Inc c If c == 360 Then c = 0 Wend End Public Sub DrawingArea1_Draw() With Paint .Brush = .Color(Color.Red) .Arc(f + (DrawingArea1.W / 2), DrawingArea1.H / 2, 2, Rad(0), Rad(360), False) .Fill .End End With End
In questo esempio nella DrawingArea verrà disegnato un punto che, partendo da coordinate x,y iniziali, dovrà raggiungere - spostandosi poco alla volta - altrettante coordinate di destinazione.
Private DrawingArea1 As DrawingArea Private p As Short[] = [410, 430] ' Imposta le coordinate di partenza del punto mobile Private arrivo As Short[] = [320, 480] ' Imposta le coordinate di destinazione del punto mobile Private b As Byte = 1 Public Sub _new() With Me .W = Screen.AvailableWidth .H = Screen.AvailableHeight .Arrangement = Arrange.Fill End With With DrawingArea1 = New DrawingArea(Me) As "DrawingArea1" .Background = Color.Lighter(Color.Yellow) End With End Public Sub Form_Open() Me.Show Wait 1 Repeat If p[0] > arrivo[0] Then p[0] -= 1 If p[0] < arrivo[0] Then p[0] += 1 If p[1] > arrivo[1] Then p[1] -= 1 If p[1] < arrivo[1] Then p[1] += 1 Me.Text = "X = " & CStr(p[0]) & " Y = " & CStr(p[1]) & " Arrivo: " & CStr(arrivo[0]) & "," & CStr(arrivo[1]) If (p[0] == arrivo[0]) And (p[1] == arrivo[1]) Then b = 2 DrawingArea1.Refresh ' Usando un ciclo, avere cura di porre un tempo, seppur minimo, di attesa, per non utilizzare eccessivamente le risorse: Wait 0.1 Until (p[0] == arrivo[0]) And (p[1] == arrivo[1]) ' Si esce dal ciclo, quando il punto avrà raggiunto le coordinate di destinazione End Public Sub DrawingArea1_Draw() With Paint .Brush = .Color(Color.Red) .Arc(p[0], p[1], b, Rad(0), Rad(360), False) .Fill .End End With End
Visibili il punto corrente disegnato e tutti i punti precedentemente disegnati
In quest'altro caso, invece, resteranno visibili tutti i punti precedentemente disegnati e descriveranno andamento sinusoidale:
Public Sub DrawingArea1_Draw() Dim x, y As Short With Paint .Brush = .Color(Color.Red) For x = 1 To 360 y = DrawingArea1.H / 2 * Sin(((2 * Pi) * (1 / 100)) * x) ' Centriamo il disegno dell'onda rispetto all'altezza della "DrawingArea": y += DrawingArea1.H / 2 .Arc(x, y, 1.5, Rad(0), Rad(360), False) .Fill Next .End End With End
Usando il Metodo ".FillRect()" della Classe Paint
In quest'altro esempio sarà usato il Metodo ".FillRect()" della Classe Paint e, per imporre il ritardo temporale nel disegno dei punti useremo il Timer.
Private DrawingArea1 As DrawingArea Private Timer1 As Timer Private pnt As Short[] Private d As Short Public Sub _new() 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 Form_Arrange() pnt = New Short[] With Timer1 = New Timer As "Timer1" .Delay = 500 ' Ritardo = 1/2 secondo .Start() End With End Public Sub Timer1_Timer() DrawingArea1.Refresh() End Public Sub DrawingArea1_Draw() Dim c As Short With Paint For c = 0 To pnt.Max .FillRect(pnt[c], DrawingArea1.H / 2, 3, 3, Color.Red) Next .End End With d += 4 pnt.Push(d) d += 4 End
Disegnare punto per punto una Spirale di Archimede
In quest'altro esempio verrà riprodotta una Spirale di Archimede: [nota 2]
Private DrAr As DrawingArea Private Const A As Float = 4.0 Private Const B As Float = 4.0 Private Const KYKLOS As Float = 26.0 Private Const PASSI As Integer = 200 Private incr As Float = 1.0 / PASSI Public Sub Form_Open() With Me .W = Screen.AvailableWidth .H = Screen.AvailableHeight .Arrangement = Arrange.Fill End With With DrAr = New DrawingArea(Me) As "DrawingArea1" .Background = Color.White End With End Public Sub DrawingArea1_Draw() Dim x, y As Integer Dim i As Float x = DrAr.W / 2 y = DrAr.H / 2 With Paint .Brush = .Color(Color.Red) While i <= KYKLOS * Pi .Arc(x + (A + B * i) * Cos(i), y + (A + B * i) * Sin(i), 0.8, Rad(0), Rad(360), False) .Fill i += incr Wend .End End With End
Disegnare punto per punto un cerchio
In quest'altro esempio, conoscendo raggio e centro della circonferenza, nonché il relativo angolo, è possibile disegnare un cerchio, o parte di esso disegnandolo punto per punto mediante una formula trigonometrica.:
Da notare che la seguente impostazione:
x + (r * Cos(Rad(t))) y + (r * Sin(Rad(t)))
disegnerà l'arco in senso orario;
la seguente impostazione:
x + (r * Cos(Rad(t))) y - (r * Sin(Rad(t)))
disegnerà l'arco in senso orario.
Provare anche le altre due possibilità:
x - (r * Cos(Rad(t))) y - (r * Sin(Rad(t)))
e
x - (r * Cos(Rad(t))) y + (r * Sin(Rad(t)))
Sarà utilizzato il Metodo "Paint.Arc()" per creare i punti:
Public Sub DrawingArea1_Draw() Dim x, y, r, t As Short x = DrawingArea1.W / 2 y = DrawingArea1.H / 2 r = 100 With Paint .Brush = .Color(Color.Red) For t = 0 To 360 .Arc(x + (r * Cos(Rad(t))), y + (r * Sin(Rad(t))), 1.0, Rad(0), Rad(360), False) Next .Fill .End End With End
Disegnare punti con il mouse in una DrawingArea
Per disegnare a mano libera, ossia con il mouse, due o più punti in modo tale che, i punti precedentemente disegnati, restino visibili sulla DrawingArea ad ogni disegno di un nuovo punto, potremo adottare un codice come il seguente:
Private DrawingArea1 As DrawingArea Private StartX As Short Private StartY As Short Private punti As New Short[] Public Sub _new() 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() Dim i As Integer With Paint .Brush = .Color(Color.Red) For i = 0 To punti.Max Step 2 .Arc(punti[i], punti[i + 1], 1.5, Rad(0), Rad(360), False) .Fill Next .End End With End Public Sub DrawingArea1_MouseDown() StartX = Mouse.X StartY = Mouse.Y End Public Sub DrawingArea1_MouseUp() punti.Push(StartX) punti.Push(StartY) DrawingArea1.Refresh() End
Ottenere l'immagine di una linea disegnando più punti contigui in sequenza
Per disegnare linee e punti su una DrawingArea [nota 3], è possibile usare il codice che segue.
Tenendo premuto il tasto destro del mouse, disegnare qualcosa nella DrawingArea.
Private DrawingArea1 As DrawingArea Private x As Short Private y As Short Private punti As New Short[] Public Sub _new() 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 Form_Arrange() DrawingArea1.Cursor = New Cursor(Picture["icon:/16/pen"], 2, 13) End Public Sub DrawingArea1_Draw() Dim i As Integer With Paint .Brush = .Color(Color.Red) For i = 0 To punti.Max Step 2 .Arc(punti[i], punti[i + 1], 1.5, Rad(0), Rad(360), False) .Fill Next .End End With End Public Sub DrawingArea1_MouseDown() x = Mouse.X y = Mouse.Y End Public Sub DrawingArea1_MouseMove() punti.Push(Mouse.X) punti.Push(Mouse.Y) DrawingArea1.Refresh() End Public Sub DrawingArea1_MouseUp() punti.Push(x) punti.Push(y) DrawingArea1.Refresh() End
Ottenere un effetto gomma per cancellare
In questo esempio, dopo aver disegnato qualcosa nella "DrawingArea", cliccare sul tasto "Effetto gomma" e passare il puntatore del mouse (tenendo premuto sul tasto destro del mouse) su quanto è stato già disegnato: sarà sostituito dal colore giallo di fondo della "DrawingArea" restituendo così un effetto "gomma per cancellare".
Private DrawingArea1 As DrawingArea Private Const GRANDEZZA_PUNTO As Float = 2.0 Private x As Integer Private y As Integer Private cl As Integer = &FF0000 Private punti As New Integer[] Public Sub _new() With Me .W = Screen.AvailableWidth .H = Screen.AvailableHeight .Arrangement = Arrange.Fill End With With DrawingArea1 = New DrawingArea(Me) As "DrawingArea1" .Background = Color.Yellow End With End Public Sub Form_Arrange() DrawingArea1.Cursor = New Cursor(Picture["icon:/16/pen"], 2, 13) End Public Sub DrawingArea1_Draw() Dim i As Integer With Paint For i = 0 To punti.Max Step 3 .Brush = .Color(punti[i + 2]) .Arc(punti[i], punti[i + 1], GRANDEZZA_PUNTO, Rad(0), Rad(360), False) .Fill Next .End End With End Public Sub DrawingArea1_MouseDown() x = Mouse.X y = Mouse.Y End Public Sub DrawingArea1_MouseMove() With punti .Push(Mouse.X) .Push(Mouse.Y) .Push(cl) End With DrawingArea1.Refresh() End Public Sub DrawingArea1_MouseUp() ' Se si clicca sul tasto centrale del mouse, si cambia colore, e, se si stava disegnando in rosso, si ottiene l'effetto gomma per cancellare; altrimenti si torna al colore rosso. If Mouse.Middle Then If cl == Color.Red Then cl = DrawingArea1.Background Else cl = Color.Red Endif Endif End
Disegnare in una DrawingArea un punto con le funzioni esterne del API di X11
Con le risorse del API di X11 è possibile disegnare un punto colorato su una DrawingArea.
Sarà necessario richiamare in Gambas la libreria di X11: "libX11.so.6.4.0 ".
Mostriamo un esempio pratico:
Library "libX11:6.4.0" ' Display *XOpenDisplay(char *display_name) ' Opens a connection to the X server that controls a display. Private Extern XOpenDisplay(display_name As Pointer) As Pointer ' GC XCreateGC(Display *display, Drawable d, unsigned long valuemask, XGCValues *values) ' Creates a graphics context and returns a GC. Private Extern XCreateGC(display As Pointer, d As Long, valuemask As Long, values As Pointer) As Pointer ' XSetForeground (Display *display, GC gc, unsigned long foreground) ' Sets the foreground. Private Extern XSetForeground(display As Pointer, gc As Pointer, foreground As Long) ' XDrawPoint(Display *display, Drawable d, GC gc, int x, int y) ' Draws a single point into the specified drawable. Private Extern XDrawPoint(display As Pointer, d As Long, gc As Pointer, x As Integer, y As Integer) ' XFreeGC(Display *display, GC gc) ' Destroys the specified GC as well as all the associated storage. Private Extern XFreeGC(display As Pointer, gc As Pointer) ' XCloseDisplay(Display *display) ' Closes the connection to the X server for the display specified in the Display structure and destroys all windows. Private Extern XCloseDisplay(display As Pointer) Public Sub Form_Open() With DrawingArea1 .X = 10 .Y = 10 .W = 400 .H = 400 .Background = Color.Black End With End Public Sub Button1_Click() Dim dsp, gc As Pointer dsp = XOpenDisplay(0) If dsp == 0 Then Error.Raise("Impossibile connettersi al server X !") gc = XCreateGC(dsp, DrawingArea1.Handle, 0, 0) If gc == 0 Then Error.Raise("Impossibile creare un contesto grafico !") ' Imposta il colore del punto: giallo. XSetForeground(dsp, gc, &FFFF00) ' Disegna il punto sulla "DrawingArea" alle coordinate x=200, y=200 : XDrawPoint(dsp, DrawingArea1.Handle, gc, 200, 200) ' Va in chiusura: XFreeGC(dsp, gc) XCloseDisplay(dsp) End
Potrebbe accadere che alla prima pressione del Button non appaia il puntino giallo, ma che sia necessario un secondo clic. In tal caso, al fine di evitare di dover cliccare due volte sul tasto del mouse e di ottenere così la comparsa del punto giallo al primo clic del Button, è necessario porre una riga di comando:
Wait 0.01
o valore superiore dopo la riga di verifica della funzione "XCreateGC()".
Note
[1] Bisogna ricordare che la Classe "Draw " è obsoleta.
[2] Vedere anche questa pagina: Disegnare in una DrawingArea una spirale di Archimede
[3] Vedere anche la seguente pagina: Disegnare in una DrawingArea più linee rette con il mouse