Entwickler-Ecke

Multimedia / Grafik - Linie zeichnen


Ritzeratze - Sa 12.07.14 12:03
Titel: Linie zeichnen
Moin,
ich möchte eine Linie von der Mittelposition aus jeweils nach oben und unten zeichnen. Per Timer soll sie immer schrittweise weitergezceihnet werden, bis sie den Fentserrand erreicht.


Ich habe bisher den folgenden Code


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Cshp11b_01_timer
{
    public partial class Form1 : Form
    {
        Pen stift;
        Graphics zeichenflaeche;

        public Form1()
        {
            InitializeComponent();
            //den Stift erzeugen und auf schwarz setzen
            stift = new Pen(Color.Black);
            //die Zeichenfläche beschaffen
            zeichenflaeche = CreateGraphics();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
         
          int xStart;
          int yStart;
          int yBottomMax;
          int yTopMax;


          //ermitteln des Mittelpunktes und Startposition
          xStart = ClientRectangle.Width / 2;
          yStart = ClientRectangle.Height / 2;
     
          //Maximalwerte für unten / Oben ermittteln 
          yBottomMax = ClientRectangle.Bottom-1;
          yTopMax= ClientRectangle.Top-1;
    
          
          zeichenflaeche.Clear(BackColor);

         while (yBottomMax < xStart)
          {
            zeichenflaeche.DrawLine(stift, xStart, yStart, 0,yBottomMax);
            xStart  = xStart + 5;
          }

          ////while (xStart < yTopMax)
          ////{
          ////  zeichenflaeche.DrawLine(stift,  xStart, yTopMax, xStart);
          ////  xStart = xStart + 5;
          ////}

        }

        private void buttonBeenden_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            timer1.Enabled = true;
        }
    }
}


Leider bringt mir das zeichnen nicht den gewünschten Effekt. Könnte mir jemand einen Tipp geben
Gruss Ritze

Moderiert von user profile iconTh69: Code- durch C#-Tags ersetzt
Moderiert von user profile iconChristian S.: Topic aus C# - Die Sprache verschoben am Sa 12.07.2014 um 15:20


Ralf Jansen - Sa 12.07.14 12:09

Du musst im Paint Event zeichnen am besten auf dem Graphics Object das du in den PaintEventArgs übergeben bekommst.
Jetzt zeichnest du woanders und das woanders wird immer durch das nichts im Paint Event ~übermalt~.
Im Timer Tick Event solltest du nur vorbereiten was gezeichnet werden soll also deine 4 integer Variablen passend setzen und dann Refresh aufrufen zum forcieren des zeichnen (das feuert den Paint Event).


Ritzeratze - So 13.07.14 12:54

Hallo Ralf,

Danke für die Antwort. Ich will eigentlich nur eine Linie vom Mittelpunkt des Zeichungsbereiches bis zum oberen Rand Zeichen. Aber irgendwie zeigt mir die Linie in allen möglichen Richtungen.


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
 
 int xStart = ClientRectangle.Width / 2;
 int yStart = ClientRectangle.Height / 2;

 //Maximalwerte für unten / Oben ermittteln 
 int yBottomMax = ClientRectangle.Bottom - 1;
 int yTopMax = ClientRectangle.Top - 1;
 int xLeftMax = ClientRectangle.Left - 1;
 int xRightMax = ClientRectangle.Right - 1;

zeichenflaeche.DrawLine(stift, xStart ,yStart, 0, yTopMax);


Moderiert von user profile iconChristian S.: Code- durch C#-Tags ersetzt


Ralf Jansen - So 13.07.14 14:47


C#-Quelltext
1:
2:
3:
4:
private void Form1_Paint(object sender, PaintEventArgs e)
{
    e.Graphics.DrawLine(new Pen(Color.Black), ClientRectangle.Width / 2, ClientRectangle.Height / 2, ClientRectangle.Width / 20);                          
}


Ritzeratze - Mo 28.07.14 22:53

Moin,

ich brauche Hilfe, weil ich mit meiner Aufgabe nicht weiterkomme.

Ich möchte einen Kreis , Rechteck und Linie in einer Picturebox zeichnen. Beim Start soll der Kreis und Rechteck von innen nach außen schrittweise vergrößert werden.
Beim Erreichen des Randes wieder von außen nach innen. Die Linie soll vom Mittelpunkt nach oben und unten gezeichnet werden. Jedesmal soll da Element neu gezeichnet und das alte gelöscht werden.
Anzahl und Geschwindigkeit der Animation sollen einstellbar sein.


Soweit bin ich: 3 Checkboxen für Figurauswahl, 2 Numeric Down Felder für Geschwindigkeit und Anzahl der Wiederholungen, einen Timer .

Komme mit der Aufgabe nicht wirklich klar. Kann mich jemand an die Hand nehmen und gemeinsam mit mir die Aufgabe lösen (nur Tipps wie ich es umsetze). Codieren möchte ich selbst.

Gruss Ritze


Th69 - Di 29.07.14 10:11

Hallo Ritzeratze,

bitte stelle konkrete Fragen, sonst wird eh kaum einer antworten.

Als Hinweis von mir:
- im Timer die Variablen ändern und control.Invalidate() aufrufen (statt einer PictureBox solltest du besser ein Panel zum Zeichnen benutzen).
- im Paint-Ereignis (des Panels) anhand der aktuellen Variablenwerte die verschiedenen Grafikobjekte zeichnen


C# - Di 29.07.14 15:09

Tach auch,

also ich hab mir dein Projekt mal angeschaut und eine Form2 hinzugefügt wie ich es machen würde. Der Code ist nicht fertig! Die grundlegende Animation funktioniert. Guck die am besten den Code an. Wenn was unklar ist frag ;). Hintergrund und Farben musst du noch implementieren.
Was funktioniert ist:
- Linie (vertikal, horizontal), Kreis und Rechteck
- Wachsen und schrumpfen Animation
- Animationswiederholungen
- Dauer für eine Animation (-> Geschwindigkeit)

Ich hoffe ich konnte helfen ohne dir zu viel Arbeit abzunehemen ;)


Ritzeratze - Do 31.07.14 00:58

Hi,

vielen Dank erstmal für Deine Mühe. Ich habe zwei Verständnisfragen
1. progress += shrink ? -timer1.Interval / 500f / (float)numTime.Value : timer1.Interval / 500f / (float)numTime.Value;
Könntest Du mir diese Zeile erklären?

2. AnimationType.TryParse(groupBoxFigures.Controls.OfType<RadioButton>().First(radioButton => radioButton.Checked).Tag.ToString(), out animationType);
Könntest Du mir diese Zeile erklären?

Bei der letzteren wird bei mir eine Ausnahme ausgelöst.


Ich habe die aktuelle Version noch einmal angehangen.


Gruss Ritze


Ritzeratze - Do 31.07.14 08:35

Hi,

den Fehler zu der Ausnahme habe ich gefunden. Zu der Checkbox war kein Tag definiert.

Trotzdem kommt die Animation nicht in Gang.


Gruss Ritze


Ralf Jansen - Do 31.07.14 12:25

Du solltest den Timer Tick Event auch mit dem Timer verdrahten und nicht nur einfach die Methode definieren ;) Das gleiche gilt für panel1_Paint.

Anmerkungen für später:
- Das globale Verwalten des Graphics Objects ist nicht hilfreich das wirst du mittelfristig kaum kontrollieren können. Ich empfehle dir alles was mit zeichnen zu tun hat ausschließlich im Paint Event zu machen und nur das dortige Graphics Object in den EventArgs zu verwenden.
- Die AnimationType Enumeration könnte einen None Eintrag gebrauchen (als erstes damit der auf 0 mappt). Damit würde sich der ~nichts zeichnen~ Teil im Paint Event leicht steuern lassen.
- Wenn du Tag zur Laufzeit zuweist kannst du direkt den Enum Wert nehmen (radioButtonKreis.Tag = AnimationType.Circle) und musst nicht mühsam parsen um den Text in einen Enum zu wandeln. Was natürlich auch schiefgeht wenn man Rechteck in den Tag schreibt der Enum aber Rectangle heißt.


Ritzeratze - Do 31.07.14 23:46

Hi Ralf.


Danke für die Hinweise. Muss jetzt erstmal ein bißchen nachlesen.
Evtl muss ich nochmal nachhaken, wenn ich was nicht verstehe.


Bis dahin, nochmal Danke und Gruss
Ritze