Zum Inhalt springen

Gambas: Grafik

Aus Wikibooks


Zurück zu Gambas


DrawingArea, Image

[Bearbeiten]

Um unter Gambas Grafiken zu erstellen sollten Sie sich mit dem Steuerelement des Zeichnungsfeldes ( DrawingArea) vertraut machen.

Die Koordinaten der DrawingArea1

[Bearbeiten]

Folgendes kleine Programm liefert die Koordinaten der DrawingArea1

Machen Sie ein neues Projekt. Öffnen Sie eine neue Form: Mit der rechten Maus auf Form klicken. Geben Sie der Form irgendeinen Namen oder nehmen Sie den Vorschlag Form1. Holen Sie sich eine DrawingArea = Zeichenfeld aus der Werkzeugkiste. Benennen Sie diese nicht um.

Kopieren Sie den Code von unten ins Programm. Starten Sie das Programm mit F5. Die ausgegebenen Zahlen entsprechen den Zahlen bei den Eigenschaften ( = F4 = Properties) der DrawingArea1.

Beachten Sie folgendes : die linke obere Ecke ist (X,Y) , die rechte untere Ecke ist (X + DrawingArea1.Width, Y + DrawingArea1.Height )

Der Code:

PUBLIC SUB Form_Open()
 PRINT DrawingArea1.X
 PRINT DrawingArea1.Y
 PRINT DrawingArea1.Width
 PRINT DrawingArea1.Height
END

Ergebnis

Wenn Sie das Zeichengebiet am Anfang nicht verändert haben werden folgende Werte ausgegeben

0
0
64
32

Bilder

[Bearbeiten]

Siehe Gambas:_Bilder

PUBLIC SUB Form_Open()
 PRINT DrawingArea1.X
 PRINT DrawingArea1.Y
 PRINT DrawingArea1.Width
 PRINT DrawingArea1.Height
END

Farben

[Bearbeiten]

Siehe Gambas:_Farben

Mathematische Funktionen

[Bearbeiten]

Siehe Gambas: Rechnen

Punkt,Linie,Kreis

[Bearbeiten]

Zeichnen kann man in Gambas nur in einem Grafikfeld ( = DrawingArea ). In einem Grafikfeld kann man Punkte, Rechtecke, Ellipsen, Linien und anderes zeichnen. Man kann verschiedene Farben und Stiftbreiten benutzen.

Punkte

[Bearbeiten]

Das folgende Beispielprogramm zeichnet ein paar Punkte. Einen einzelnen Punkt sieht man schlecht.

Machen Sie dazu ein neues Projekt. Öffnen Sie eine neue Form: Mit der rechten Maus auf Form klicken. Geben Sie ihr den Namen Fmain. Holen Sie sich einen Befehlsknopf = Button aus der Werkzeugkiste . Holen Sie sich eine DrawingArea = Zeichenfeld aus der Werkzeugkiste.

Kopieren Sie den Code ins Programm. Starten Sie das Programm mit F5. Achten Sie auf die Farbgebung bei den Eigenschaften, sonst sehen Sie nichts.

PUBLIC SUB Button1_Click()
Draw.Begin(DrawingArea1)
Draw.Point(100,100)
Draw.Point(100,101)
Draw.Point(100,102)
Draw.Point(100,103)
Draw.Point(100,99)
Draw.Point(100,98)
Draw.Point(100,97)
Draw.Point(100,96)
Draw.End
END

Linien

[Bearbeiten]

Das nächste kleine Programm zeichnet ein paar Linien.

Machen Sie ein neues Projekt. Öffnen Sie eine neue Form: Mit der rechten Maus auf Form klicken. Geben Sie ihr den Namen Fmain. Holen Sie sich einen Befehlsknopf = Button aus der Werkzeugkiste . Holen Sie sich eine DrawingArea = Zeichenfeld aus der Werkzeugkiste.

Kopieren Sie den Code ins Programm. Starten Sie das Programm mit F5. Achten Sie auf die Farbgebung bei den Eigenschaften, sonst sehen Sie nichts.

PUBLIC SUB Button1_Click()
DIM B AS Integer ' Variable deklarieren. 
Draw.Begin(DrawingArea1)
FOR B = 1 TO 200 STEP 10 ' Schleife initialisieren. 
Draw.Line(1, B, 500, B)
NEXT 
Draw.End
END

Linienbreite

[Bearbeiten]

Dieses Grafikprogramm zeigt die Programmierung verschieden dicker Linien. Sie brauchen wieder einen Befehlsbutton und eine DrawingArea. Der entscheidende Befehl heißt hier Draw.LineWidth Hinter dem Befehl Linienbreite steht folgender Code :

PUBLIC SUB Button1_Click()
DIM B AS Integer ' Variable deklarieren. 
Draw.Begin(DrawingArea1)
Draw.Line(10,100, 20, 100)
FOR B = 1 TO 100 STEP 10 ' Schleife initialisieren. 
 Draw.LineWidth=B ' Stiftbreite einstellen. 
 Draw.Line(10+B,100, 20+B, 100)
NEXT 
Draw.End
END

Noch ein paar Linien

[Bearbeiten]
PUBLIC SUB Button1_Click()
Draw.Begin(DrawingArea1)
' Zeichnet eine Linie horizontal durch die Mitte der Form
Draw.Line (0, ME.Height / 2, ME.Width, ME.Height / 2)
' Zeichnet eine Linie senkrecht durch die Mitte der Form
Draw.Line (ME.Width / 2, 0,ME.Width / 2, ME.Height)
' Zeichnet eine Linie von der linken oberen zur unteren rechten Ecke
Draw.Line (0, 0,ME.Width, ME.Height)
' Zeichnet eine Linie von der rechten oberen zur unteren linken Ecke
Draw.Line (ME.Width, 0,0, ME.Height)
Draw.End
END

Warum werden die Linien nicht sauber zentriert ?

Fügen Sie direkt nach der ersten Zeile folgenden Code ein:

DrawingArea1.Resize(ME.Width, ME.Height)
DrawingArea1.Background = &HFFFFFF&

Schaut es jetzt besser aus ?

Wenn Sie die Zeile

DrawingArea1.Resize(ME.Width, ME.Height)

nach dem Befehl Draw.Begin(DrawingArea1) einfügen , gibt es eine Fehlermeldung:

QPaintDevice: Cannot destroy paint device that is being painted
X Error: BadDrawable (invalid Pixmap or Window parameter) 9
 Major opcode:  66
 Minor opcode:  0
 Resource id:  0x2e00010
X Error: RenderBadPicture (invalid Picture parameter) 180
 Major opcode:  153
 Minor opcode:  5
 Resource id:  0x2e00025

Farbe der Linie

[Bearbeiten]

Wenn Sie die Farbe Ihrer Linie verändern wollen, dann hilft folgendes Programm

Draw.Begin(DrawingArea1)
Draw.ForeColor = &HFFFFFF 
' weiße Farbe 
' Draw.ForeColor = &H0000FF& blaue Linie
' Draw.ForeColor = &HFF00FF& lila
' Draw.ForeColor = &HFF0000& rot
' Draw.ForeColor = &H00FF00& grün
' Draw.ForeColor = &HFFFF00& gelb
' Draw.ForeColor = &H00FFFF& türkis
' &H000000& = Schwarz 
Draw.Line(1, 130, 500, 400)
Draw.End

Rechteck

[Bearbeiten]

Das folgende Programm zeichnet ein Rechteck.

Machen Sie ein neues Projekt. Öffnen Sie eine neue Form: Mit der rechten Maus auf Form klicken. Geben Sie ihr den Namen Fmain. Holen Sie sich einen Befehlsknopf = Button aus der Werkzeugkiste . Holen Sie sich eine DrawingArea = Zeichenfeld aus der Werkzeugkiste.

Nennen Sie die Zeichenfläche da. Dazu markieren Sie die Zeichenfläche mit der Maus . Drücken Sie F4 und sie erhalten die Eigenschaften = Properties der Zeichenfläche. In der zweiten Zeile bei (Name) geben Sie statt DrawingArea den eigenen Namen da ein.

Kopieren Sie den Code ins Programm. Starten Sie das Programm mit F5. Achten Sie auf die Farbgebung bei den Eigenschaften, sonst sehen Sie nichts.

Beachten Sie folgendes:

Die Koordinaten der Drawing Area gehen von der linken Oberen Ecke ( DrawingArea.X = 0, DrawingArea.Y = 0) bis zur unteren rechten Ecke (DrawingArea.Width = beliebig, DrawingArea.Height = beliebig).

Bei den Koordinaten des Rechtecks geben die ersten 2 Ziffern die absoluten Koordinaten der linken oberen Ecke des Rechtecks in der Drawing Area an. Im Beispiel werden 100 und 100 gewählt. Die 2 weiteren Zahlen geben die Koordinaten der rechten unteren Ecke des Rechtecks relativ zur linken oberen Anfangsecke an. Im Beispiel 90 und 90. Die absoluten Koordinaten der rechten unteren Ecke sind im Beispiel dann 190 und 190 .

Beim Draw.Line Befehl ist das anders. Hier wurden absolute Koordinaten gewählt.

Als Übung können Sie versuchen in das Rechteck die 2 Diagonalen mit Drawline einzuzeichen.

Wie lauten dazu die Koordinaten. Lösung siehe unten.

PUBLIC SUB Button1_Click()
Draw.Begin(da)
Draw.Rect(100, 100, 90, 90)
Draw.End
END

Variante mit Diagonalen

PUBLIC SUB Button1_Click() 
Draw.Begin(da)
Draw.Rect(100, 100, 90, 90)
Draw.Line(100, 100, 190, 190)
Draw.Line(100, 190, 190, 100)
Draw.End
END

Rechteck mit Farbe füllen

[Bearbeiten]

Das Beispielprogramm zeichnet ein Rechteck und füllt es mit weißer Farbe.

PUBLIC SUB Button1_Click()
  Draw.Begin(DrawingArea1)     ' Verwende DrawinArea1 als "Leinwand"
  Draw.FillColor = Color.white
  Draw.FillStyle = 1
  Draw.ForeColor = Color.white ' der Rand wird auch weiß 
  Draw.Rect (100, 100,200,200)
  Draw.End
END

Kreis

[Bearbeiten]

Dieses Grafikprogramm zeigt die Programmierung einer Kreisgrafik:

Hinter dem Befehl ein paar Kreise steht der folgende Code:

PUBLIC SUB Button1_Click()
  Draw.Begin(Drawingarea1)
  Draw.Ellipse(10, 50, 90, 90)
  Draw.Ellipse(10, 50, 50, 50)
  Draw.Ellipse(10, 50, 20, 20)
  Draw.End
END

Sie brauchen eine Zeichenfläche (Klasse Drawingarea) und einen Knopf der Klasse Commandbutton auf Ihrem Formular, um das Programm in Gang zu bringen. Spielen Sie mit den einzelnen Größen etwas herum und beobachten Sie wie sich die Grafiken ändern.

Vereinfachen Sie das Programm so, daß nur noch ein Kreis gezeichnet wird.

Beachten Sie folgendes:

  • Die erste Zahl hinter dem Befehl Draw.Ellipse gibt die x Koordinate der linken oberen Ecke eines Rechtecks an, in die die Ellipse , bzw. der Kreis tangential eingebettet ist.
    • Man kann diesen Wert xloe ( x Wert linke obere Ecke) nennen
  • Die zweite Zahl gibt die y Koordinate der linken oberen Ecke an.
    • Man kann diesen Wert yloe ( y Wert linke obere Ecke) nennen
  • Die dritte Zahl gibt die x Koordinate der rechten unteren Ecke an. Der Wert ist kein Absolutwert sondern relativ zur linken oberen Ecke.
    • Man kann diesen Wert rxrue ( relativen x Wert rechte untere Ecke) nennen
  • Die vierte Zahl gibt die y Koordinate der rechten unteren Ecke an.
    • Man kann diesen Wert ryrue ( relativen y Wert rechte untere Ecke) nennen

Will man einen Kreis programmieren, dann müssen der dritte und der vierte Parameter gleich sein, denn nur so wird das berührende Rechteck ein Quadrat. Nur ein Quadrat kann mit allen 4 Seiten einen Kreis berühren.

Draw.Ellipse(xloe, yloe, rxrue, ryrue)
Für den Kreis gilt rxrue = ryrue 

Überprüfen Sie, ob im obigen Kreisprogramm diese Vorgaben eingehalten werden. Verändern Sie den Parameter 3 und 4 und schauen Sie sich an , was passiert.

Um das Ganze zu verdeutlichen programmiert man am besten einen Kreis und das umgebende Quadrat.

PUBLIC SUB Button1_Click()
Draw.Begin(Drawingarea1)
Draw.Ellipse(10, 50, 90, 90)
Draw.Rect(10, 50, 90, 90)
Draw.End
END

Aus diesen Vorgaben kann man den Radius des Kreises berechnen:

Radius = (dritte oder vierter Parameter von Draw.Ellipse) / 2) 

Aus diesen Vorgaben kann man auch die Koordinaten des Kreismittelpunktes berechnen.

mx = xloe + rxrue / 2
my = yloe + rxrue / 2

Wie kann man dann die 2 Brennpunkte einer Ellipse berechnen, wenn also rxrue und ryrue verschieden sind ??

Die Röhre

[Bearbeiten]

Ein weiteres Beispiel mit vielen verschiedenen Kreisen. Das Programm wurde mit Menusteuerung programmiert. Siehe Gambas: Menü Außerdem wird eine DrawingArea auf der Form gebraucht.

So schaut das Ganze aus:

Der Code dazu:

PUBLIC SUB Form_Open()
 DrawingArea1.Resize(ME.Width, ME.Height)
END
PUBLIC SUB Menu2_Click()
x AS Integer 
Draw.Begin(Drawingarea1)
FOR x = 0 TO 200 STEP 5
 Draw.Ellipse(10, 10, x + 100, x + 100,5)
NEXT
Draw.End
END
PUBLIC SUB Menu3_Click()
  ME.Close
END

Konzentrische Kreise

[Bearbeiten]

Im folgenden Beispiel werden mehrere konzentrische Kreise in eine DrawingArea gezeichnet. Sie brauchen

  • eine Drawingarea ( Grafikfeld)
  • einen Befehlsbutton

um das Programm in Gang zu bringen.

PUBLIC SUB Form_Open()
 Drawingarea1.cached = TRUE
 IF Drawingarea1.width > Drawingarea1.height THEN 
 Drawingarea1.width = Drawingarea1.height 
 ELSE 
 Drawingarea1.height = Drawingarea1.width 
ENDIF 
Button1.Text = "Kreise"
ME.Text = "Konzentrische Kreise"
END
PUBLIC SUB Button1_Click()
mx AS Integer 
'x Koordinate des Mittelpunktes
my AS Integer
'y Koordinate des Mittelpunktes 
'Radius = mx - a 
a AS Integer
'linke obere Ecke x Koordinate 
b AS Integer
'linke obere Ecke y Koordinate  
c AS Integer
'a + c ergibt die x Koordinate der rechten unteren Ecke 
d AS Integer
'b + d ergibt die y Koordinate der rechten unteren Ecke 
mx = Drawingarea1.width / 2
Draw.Begin(Drawingarea1)
a = 0
FOR a = 0 TO mx STEP 10
 b = a 
 c = 2 * (mx - a)
 d = c
draw.Ellipse (a,b,c,d)
NEXT 
draw.End
END

Die folgende Abbildung zeigt einen Screenshot des Programmes. Eine Kleinigkeit ist allerdings falsch. Fällt es Ihnen auf.

Der zweite Befehlsbutton und der Code dazu fehlt im obigen Programm.

PUBLIC SUB Button2_Click()
 ME.Close 
END

Tortengrafik

[Bearbeiten]

Fügt man dem Befehl Draw(Ellipse) außer den 4 notwendigen Parametern noch 2 weitere Parameter hinzu erhält man Kreissegmente, die man gut für eine Tortengrafik nutzen kann.

  • Parameter 5, Gradzahl bei der das Segment beginnen soll
  • Parameter 6, Gradzahl, bei der das Segment endet soll.

Beispiel:

PUBLIC SUB Button1_Click()
Draw.Begin(Drawingarea1)
Draw.Ellipse(10, 50, 90, 90, 10, 90)
Draw.End
END

Man erhält einen Viertelkreis , der bei zehn Grad im Westem beginnt und entgegen des Uhrzeigerssinnes läuft.

Siehe auch: http://www.binara.com/gambas-wiki/bin/view/Gambas/DrawFigures

Ellipse

[Bearbeiten]

Um die wichtigsten Parameter des Befehls Draw.Ellipse zu verstehen, können Sie folgendes Programm ausprobieren:

Layout

[Bearbeiten]

Sie brauchen:

  • 9 Textboxen auf Ihrer Form
  • 1 Drawingarea
  • 3 Befehlsbuttons
  • 2 Labelfelder

auf Ihrer Form um das Programm in Gang zu bringen.

Der Code

[Bearbeiten]
PUBLIC SUB Form_Open()
textbox1.Text = "0"
textbox2.Text = "0"
textbox3.Text = Str(Drawingarea1.Width)
textbox4.Text = Str(Drawingarea1.Height)
textbox5.Text = "10"  
textbox6.Text = "10" 
textbox7.Text = Str(0 + Drawingarea1.Width/2)
textbox8.Text = Str(0 + Drawingarea1.Height/2)
textbox9.Text = Str(Drawingarea1.Width/2)
Button1.Text = "Kreis"
END
PUBLIC SUB Button1_Click()
a AS Integer 
b AS Integer
c AS Integer
d AS Integer
a = Val(Textbox1.text)
b = Val(Textbox2.text)
c = Val(Textbox3.text)
d = Val(Textbox4.text)
Draw.Begin(Drawingarea1)
Draw.ellipse(a,b,c,d)
Draw.End 
textbox7.Text = Str(a + c/2)
textbox8.Text = Str(b + d/2)
textbox9.Text = Str(c/2) 
CATCH
message.Info("Bitte geben Sie in jedes Feld eine Zahl ein !")
END
PUBLIC SUB Button2_Click()
Draw.Begin(Drawingarea1)
Drawingarea1.Refresh
Draw.End 
END
PUBLIC SUB Button3_Click()
a AS Integer 
b AS Integer
c AS Integer
d AS Integer
e AS Float
f AS Float 
a = Val(Textbox1.text)
b = Val(Textbox2.text)
c = Val(Textbox3.text)
d = Val(Textbox4.text)
e = Val(Textbox5.text)
f = Val(Textbox6.text)
Draw.Begin(Drawingarea1)
Draw.ellipse(a,b,c,d,e,f)
Draw.End 
CATCH
message.Info("Bitte geben Sie in jedes Feld eine Zahl ein !")
END

Und so schaut das Programm zur Laufzeit aus :

Der Seestern

[Bearbeiten]

"Der kleine G. hatte gar nicht gewußt, dass man unterwasser auch so schöne Sterne finden konnte."

Das Seesternprogramm zeigt den Übergang von einer geordneten Struktur ins Chaos. Normalerweise haben Seesterne eigentlich 5 Beine. Bei unserem Programm ist eines verloren gegangen.

Um das Programm in Gang zu bringen, braucht man eine DrawingArea und einen Befehlsbutton.

Layout

[Bearbeiten]

Der Code

[Bearbeiten]
PUBLIC SUB Form_Open()
 DrawingArea1.Width = 1000
 DrawingArea1.H = 1000
 DrawingArea1.X = 0
 DrawingArea1.Y = 0
 DrawingArea1.Background = &HFFFFFF&
 Button1.Text = "Seestern"
END
PUBLIC SUB Button1_Click()
 E AS Integer 
AW AS Float 
H AS Integer 
X AS Float
Y AS Float 
I AS Integer 
A AS Float 
B AS Float
C AS Float 
Draw.Begin(DrawingArea1)
FOR E = 1 TO 13 
IF E = 1 THEN 
AW = 55 
H = 100 
ENDIF
IF E = 2 THEN 
AW = 80
H = 120 
ENDIF
IF E = 3 THEN 
AW = 88
H = 120
ENDIF 
IF E = 4 THEN 
AW = 90
H = 150 
ENDIF
IF E = 5 THEN 
AW = 90.1
H = 300 
ENDIF
IF E = 6 THEN 
AW = 90.2
H = 490 
ENDIF
IF E = 7 THEN 
AW = 90.21
H = 1000 
ENDIF
IF E = 8 THEN 
AW = 90.22
H = 600 
ENDIF
IF E = 9 THEN 
AW = 90.25
H = 250 
ENDIF
IF E = 10 THEN 
AW = 90.3
H = 180
ENDIF 
IF E = 11 THEN 
AW = 91
H = 100 
ENDIF
IF E = 12 THEN 
AW = 92
H = 100 
ENDIF
IF E = 13 THEN 
AW = 92.2
H = 410
ENDIF
X = 0.1513 
Y = -0.5388 
'Pi = 3.141593: 
A = AW * Pi / 180'
'Rem umrechnung d.360 Grad Winkels ins Bogenmass 
FOR I = 0 TO H 
B = X * Cos(A) - (Y - X * X) * Sin(A) 
C = X * Sin(A) + (Y - X * X) * Cos(A) 
X = B 
Y = C 
'Draw.Point (400 + E ,400 + E)
Draw.Point(B * 300 + 300, C * 300 + 300) 
'PRINT B, C 
NEXT  
'FOR z = 1 TO 1000000: NEXT z: Rem Zeitverzoegerung kann man variieren 
NEXT  
Draw.End
END