Laden...

Linie langsam zeichnen (GDI)

Erstellt von cyanide vor 13 Jahren Letzter Beitrag vor 13 Jahren 7.896 Views
C
cyanide Themenstarter:in
88 Beiträge seit 2008
vor 13 Jahren
Linie langsam zeichnen (GDI)

Moin!

Ich möchte eine Linie zeichnen, die sich (zeitlich einstellbar) langsam aufbaut, also nicht direkt da ist sobald ich z.B DrawLine() aufrufe.

Habt ihr da einen Tipp für mich?

42 Beiträge seit 2009
vor 13 Jahren
Interne Datenhaltung

Du merkst dir einfach den Anfangs- und Endpunkt der Linie und änderst bspw. in einem Tick-Timer immer den End-Punkt. In der Draw-Methode zeichnest du dann einfach immer die Linie mithilfe des Anfangs- und Endpunkts. Es kommt dann auch drauf an, wann deine Form neu gezeichnet wird. Eventuell musst du im Tick-Timer-Eventhandler ein Invalidate() rufen.

C
2.122 Beiträge seit 2010
vor 13 Jahren

Dann könnte es aber sein dass die eigentlich deckungsgleichen Punkte der verschiedenen Linienstückchen doch nicht aufeinander liegen, wegen der unterschiedlichen Endpunkte.
Wirklich einneutig wäre es, den Algorithmus fürs zeichnen von Linien nachzubilden und dann immer nur die benötigten Pixel bzw. nur die wirklich neuen Linienstückchen zu malen.

C
cyanide Themenstarter:in
88 Beiträge seit 2008
vor 13 Jahren

Hallo Frankhammer,

gibt es noch andere Möglichkeiten?

Das Problem ist, dass ich auch Kreise zeichne, habe ich hier nicht erwähnt, der Einfachkeithalber.

Jeden einzelnen Pixel eines solchen Kreises herauszubekommen wäre (für mich zumindest) unmöglich.

@chilic: So in etwa habe ich mir das theoretisch auch gedacht, an der Umesetzung hapert es aber.

Gelöschter Account
vor 13 Jahren

versuchst du so eine art Animation zu machen?

Das wäre mit WPF deutlich einfacher zu gestalten...

C
cyanide Themenstarter:in
88 Beiträge seit 2008
vor 13 Jahren

JAck30lena: Genau, aber nichts besonders wie 3D oder hochwertige Grafiken, sondern einfach nur einfache Kreise/Rechtecke/Linien etc.

Mit WPF hab ich mich noch nicht beschäftigt und habe es, sofern es anders möglich ist, auch auf Grund mangelnder Erfahrung in dem Bereich, nicht vor.

Ich habe ein Textfeld, in dem Reihenweise Koordinaten stehen und meine Simulation soll genau diese abfahren können, ohne dass ich direkt das fertige Bild sehe.

Gelöschter Account
vor 13 Jahren

schwer....

Entweder du zeichnest immer blockweise. also ganze Linien und ganze Kreise aber dafür immer nur eine Linie und einen Kreis je tackt oder aber du zeichnest alles auf eine Bitmap und diese überträgst du dann nur stückweise auf die Anzeige wobei letzteres vermutlich beschissen aussehen würde....

nur in WPF sehe ich eine Möglichkeit eine Flüssige Animation vom aufbau eines Kreises/Linie zu erzeugen.

C
2.122 Beiträge seit 2010
vor 13 Jahren

@chilic: So in etwa habe ich mir das theoretisch auch gedacht, an der Umesetzung hapert es aber.

Wo genau hapert es? Da gibts doch sicher einiges in Google zu finden.

C
cyanide Themenstarter:in
88 Beiträge seit 2008
vor 13 Jahren

@JAck30lena: Wie aber hat man es vor WPF getan?

@Chilic:Ich habe natürlicher vorher gegooglet, das Problem ist aber manchmal, genau zu formulieren wonach man sucht. Suchwörter wie "C# Linie aufbauen" oder "C# Linie langsam zeichnen" brachten mir keinen Erfolg.

C
2.122 Beiträge seit 2010
vor 13 Jahren

Zum Beispiel der da
Ich hab nach "line algorithm" gesucht.
Es geht ja erst mal nicht darum wie man die langsam zeichnet, sondern wie man sie überhaupt als einzelne Punkte zeichnet. Dann kannst du die Punkte einzeln ausrechnen und setzen, bzw. Anfangs und Endpunkte eines kurzen Linienstücks berechnen.

Gelöschter Account
vor 13 Jahren

Um linien geht es nicht. Das ist Simpel. Es geht um Kreise oder weitaus komplexere Muster, welche mit GDI nun mal extrem einfach gezeichnet werden können aber auch nur in einem stück... dahinter steckt einiges an Mathematik... das kommt dann eine nachimplementierung von GDI gleich.

F
155 Beiträge seit 2009
vor 13 Jahren

Hallo,

in dem deutschen Artikel den chilic verlinkt hat, ist auch eine Implementierung eines Kreises und der Threadersteller braucht doch nur einfach nur einfache Kreise/Rechtecke/Linien.

fz

"We better hurry up and start coding, there are going to be a lot of bugs to fix."

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo zusammen,

man kann die Linie gleich und immer vom Start- zum endgültigen Endpunkt zeichnen, aber durch das Clipping (Graphics.Clip) bestimmen, wieviel davon momentan gezeichnet werden soll. Dann sollten bei Neuzeichnen des schon sichtbaren Teils exakt die gleichen Pixel gezeichnet werden. Das gilt natürlich nicht nur für Linien, sondern für alle Figuren analog.

herbivore

C
cyanide Themenstarter:in
88 Beiträge seit 2008
vor 13 Jahren

Danke für eure Antworten.

Habe Interesse das ganze mal mit WPF auszuprobieren. WIe genau könnte mein gesuchtes Problem hier beseitigt werden? Habe schon einiges zum Thema Animation gelesen aber wie ich eine Linie aufbaue habe ich noch nicht so herausfiltern können.

Habt ihr evtl. ein paar Stichworte für mich?

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo cyanide,

die Einschätzung, dass das mit WPF deutlich leichter ginge, teile ich nicht. Das du bei WPF nicht recht weitergekommen bist, bestätigt meine Einschätzung. Ich denke, dass die Einstiegshürde bei WPF deutlich höher ist ... dafür kann man dann natürlich auch mehr damit machen. Aber du willst ja nur eine recht einfach Animation machen. Schau in [Artikel] Zeichnen in Windows-Programmen. Da siehst du anhand von wirklich einfachen Beispielen, wie das geht. Es gibt sogar ein Animationsbeispiel. Wenn du dann noch meinen Tipp von weiter oben beherzigst, dann solltest du alles leicht in den Griff bekommen.

herbivore

Hinweis von herbivore vor 13 Jahren

Bitte kein WPF-WinForms-War. Es gibt schon eine Reihe von Threads, die sich mit dem Vergleich und den Vor- und Nachteilen beider Techniken beschäftigen ... und die bei Bedarf verlinkt werden können, ohne dass wir das Thema hier nochmal aufrollen müssen.

4.942 Beiträge seit 2008
vor 13 Jahren

Hallo herbivore,

für einfache Linien und Rechtecke funktioniert sicherlich die Benutzung von Graphics.Clip. Sobald man aber Polygone (bzw. sich sogar überlappende Linien) sowie Ellipsen/Kreise hat, so dreht man sich wieder "im Kreis", denn dann müßte man selber für die korrekte Berechnung des Clip-Rects (bzw. der Clip-Region) die einzelnen Pixel kennen, welche man anzeigen (bzw. ausblenden) will, um eine korrekte Animation hinzukriegen.
Bei einer Ellipse/Kreis kann man jedoch die Graphics.DrawArc()-Methode dafür benutzen, und sukzessive den Endwinkel erhöhen (gegebenfalls Überlauf bei 360° -> 0° abfangen, falls das die Methode noch nicht selber unterstützt).
Aber für komplexere Objekte kann man im allgemeinen Fall nur die Nachimplementierung von Linien, Kreisen sowie Polynom-, Spline- und Bezier-Kurven etc. empfehlen.

Und auch hallo cyanide,
bzgl.

Ich habe ein Textfeld, in dem Reihenweise Koordinaten stehen und meine Simulation soll genau diese abfahren können, ohne dass ich direkt das fertige Bild sehe.

Hier solltest du genauer erläutern, welche Interpolation du genau meinst, denn es gibt ja verschiedene:

  • lineare
  • höherpolynomische
  • Spline- bzw. Bezierkurven
  • ...
    ???
49.485 Beiträge seit 2005
vor 13 Jahren

Hallo Th69,

Graphics.Clip ist kein kein Rectangle, sondern eine Region. Das passt also für alle Figuren, nicht nur für Linien und Rechtecke.

herbivore

4.942 Beiträge seit 2008
vor 13 Jahren

Hallo herbivore,

ja, das habe ich ja auch geschrieben. Aber wie würdest du denn ein halb gezeichnetes Polygon bzw. Teilkreis damit definieren, denn Region unterstützt ja auch nur bestimmte Grundelemente (bzw. Kombinationen davon):

  • Region(GraphicsPath): also selbes Problem wie oben schon beschrieben
  • Region(Rectangle): rechteckig
  • Region(RegionData): nur Kopie einer anderen Region

Letztendlich hat man auch hier dasselbe Problem bzgl. der Interpolation der Linien.

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo Th69,

ich sehe das Problem irgendwie nicht. Wenn ich z.B. einen sich langsam im Uhrzeigersinn aufbauenden Kreis darstellen will, dann kriegt man das mit einen Graphics.Path doch ohne weiteres hin. Nehmen wir mal an, wir wären gerade bei fünf Uhr. Der Graphics.Path für die Clip-Region besteht dann aus folgenden Kanten: Eine der Länge r vom Kreismittelpunkt senkrecht nach oben, die nächste der Länge r waagerecht nach rechts. Dann wieder eine vom Kreismittelpunkt in Richtung fünf Uhr. Und eine letzte von oben rechts herunter bis sie die vorletzte schneidet. Klingt jetzt vielleicht aufwändiger als es wirklich ist. Sicher wäre in dem konkreten Fall die DrawArc-Methode einfacher, aber da wäre ich mir nicht sicher, ob es keine Problem mit aufgrund von Rundungsfehlern an verschieden Stellen positionierten Pixeln gibt. Wenn nicht, kann man die natürlich dabei vorziehen.

Aber wie auch immer. Wenn man eine langsam aufbauende Animation erstellt, muss man in irgendeiner Form definieren, welcher Teil zu welchem Zeitpunkt sichtbar sein soll. Da kommt man nicht drumrum.

herbivore