Pfeil zeichnen
-
Hallo Leute!
Ich habe mir ein Programm geschrieben, dass zwei aufeinanderfolgende Bilder ( oder auch zwei beliebige Bilder ) nach ähnlichen Bildblöcken untersucht. Die Blöcke, die am ähnlichsten sind, sollen in einer Art Overlay mit einer Linie verbunden werden. Das Zeichen der Linie habe ich mit dem Bresenham-Algorithmus gemacht. Soweit ganz nett.
Jetzt möchte ich aber gerne an das Ende meiner Linie einen Pfeil zeichnen, der in die Richtung der wahrscheinlichen Bewegung zeigt. Man könnte zwar einfach mal 5 Pixel horizontal und 5 Pixel vertikal vom letzten Linienpunkt zeichnen, jedoch sieht das ziemlich bescheiden aus, wenn der Vektor gerade keine 45 Grad hat ...
Kann mir jemand sagen, wo ich einen Algorithmus finde, der an das Ende meiner Linie einen Pfeil zeichnet?
Kann mir nicht vorstellen, dass ich der erste mit diesem Problem bin.
2Atlantis
-
Einfach anstatt hor/ver auch mit dem Bresenham in arbitrary Richtung?
-
Sgt. Nukem schrieb:
mit dem Bresenham in arbitrary Richtung?
Mhm ... also mal angenommen, ich habe ein Anfangspixel(x,y) von (0,0) und ein Endpixel (50,10). Wie setzt man dann die Endpunkte des Pfeils, so dass er dennoch einigermaßen rechtwinklig ist ... ???
-
5 Pixel vor ende bewegst du dich nach beiden Seiten 5 Pixel orthogonal zur Linie, 4 pixel davor nur noch 4 Pixel, ect.
-
Das mit den orthogonalen Pixeln funktioniert nur bei 45 Grad-Linien oder bei horizontalen und vertikalen Linien.
Bei einer solchen Linie:----------x
---------x-
-------xx--
------x----
----xx-----Gehts dann schon nichtmehr, denn dann würde das so hier aussehen: (y = Pfeil)
------yy----
--------yyy-
----------xy
---------x-y
-------xx-yy
------x----y
----xx------Hat jemand eine Idee? Oder einen Link im Netz?
-
Orthogonal zur Linie bedeutet im 90°-Winkel zur Linie..
.......... .......x.. .....xxx.. ....xxxxx. .....x.... .....x.... ....x.....
Du müsstest eben genau 90° versetzt zum Bresenham arbeiten..
-
DocJunioR schrieb:
Du müsstest eben genau 90° versetzt zum Bresenham arbeiten..
Hier ist mein Bresenham ... Der zeichnet zwischen einem Anfangs- und einem Endpunkt eine Linie ... :
( Aber wie realisiere ich das mit den 90° ??? )void Bresenham( InputPic, int x1, int x2, int y1, int y2, Outputpic) { int x = x1; // Startkoordinaten int y = y1; // Startkoordinaten int hx = x2-x1; // Piceldifferenz in x-Richtung int hy = y2-y1; // Piceldifferenz in y-Richtung int xinc = 1; // Schrittweite in x-Richtung int yinc = 1; // Schrittweite in y-Richtung int d = 0; // Differenz zwischen Ideal-Geraden-Wert und genäherterm Pixel if ( hx < 0 ) // Bewegungsvektor zeigt nach links { xinc = -1; hx = -hx; } if ( hy < 0 ) // Bewegungsvektor zeigt nach oben { yinc = -1; hy = -hy; } if ( hy <= hx ) // flacher Bewegungsvektor { int c = 2 * hx; int m = 2 * hy; while ( true ) { pOut->pImg[x+y* iImageWidth] = 255; if ( x == x2 ) { break; } x += xinc; d += m; if ( d > hx ) { y += yinc; d -= c; } } } else // steiler Bewegungsvektor { int c = 2 * hy; int m = 2 * hx; while ( true ) { pOut->pImg[x+y* iImageWidth] = 255; if ( y == y2 ) { break; } y+= yinc; d += m; if ( d > hy ) { x += xinc; d -= c; } } } }
-
Ich würde mittels dem Normalenvektor (zur Hauptlinie) zwei Punkte ausrechnen, die etwas von der Spitze entfernt liegen und von denen aus dann jeweils eine Linie zur Spitze zeichnen (mit Bresenham den Du ja schon hast)
Ergibt zwar keinen gefüllten Pfeil, aber das wäre auch nochmal heftiger...
-
Wie komme ich auf den Normalenvektor, ohne großartige mathematische Funktionen aufzurufen ... Bisher habe ich nur Integer-Operationen .. das fand ich ziemlich gut. Und wie bestimme ich mithilfe des Bresenham den Normalenvektor?
Mist, ich komm nicht weiter ...
-
Das Thema war schon vor kurzem hier im Forum.
Bye, TGGC (Pipe my World.)
-
TGGC schrieb:
Das Thema war schon vor kurzem hier im Forum.
Eine ID oder ein Link wären schon fein gewesen ...
-
das ist ein Link
-
Danke für den Link,
aber da gehts ja nun wohl wirklich nicht mehr um die Pfeile an Linien ...
-
Ist bestimmte nicht die effizienterste Lösung, aber das beste was mir innerhalb einer Minute eingefallen ist ;):
- Modelliere dir eine Pfeilspitze in einem lokalen Koordinatensystem - der Winkel der Pfeilspitze hat dabei x Grad
- Betrachte den Endpunkt deines Geradenstücks (da wo der Pfeil hin soll) als Drehpunkt
- rotiere die Pfeilspitze um x/2 Grad
- Verschiebe Pfeilspitze, so dass sie auf dem Endpunkt des Geradenstücks landet
- zeichne die Pfeilspitze
Cos und Sin kosten viel zeit – aber der Winkel der Pfeilspitze wird sich ja nicht oft verändern
-
2Atlantis schrieb:
Wie komme ich auf den Normalenvektor, ohne großartige mathematische Funktionen aufzurufen ... Bisher habe ich nur Integer-Operationen .. das fand ich ziemlich gut.
Wenn (x,y) der Richtungsvektor Deiner Linie ist, dann ist (y,-x) ein Normalvektor dazu.
-
2Atlantis schrieb:
Danke für den Link,
aber da gehts ja nun wohl wirklich nicht mehr um die Pfeile an Linien ...
Es geht darin auch nur darum, wie man eine orthogonale Linie berechnet
-
Okay, Normalenvektor:
Aber wenn ich den Bresesenham richtig verstanden habe, braucht der einen Anfangs- und einen Endpunkt. Wenn ich den Normalenvektor habe, also die Gerade, die senktrecht auf der eigentlichen Linie steht, brauche ich doch aber immernoch einen Endpunkt auf dem Normalenvektor. (Das sind dann meine äußersten Pfeilpixel) ... Wie kann man die bestimmen?
-
> Aber wenn ich den Bresesenham richtig verstanden habe, braucht der einen Anfangs- und einen Endpunkt. Wenn ich den Normalenvektor habe, also die Gerade, die senktrecht auf der eigentlichen Linie steht, brauche ich doch aber immernoch einen Endpunkt auf dem Normalenvektor. (Das sind dann meine äußersten Pfeilpixel) ... Wie kann man die bestimmen?
anscheinend hast du den Bresenham Algorithmus nicht verstanden
-
2Atlantis schrieb:
Wenn ich den Normalenvektor habe, also die Gerade, die senktrecht auf der eigentlichen Linie steht, brauche ich doch aber immernoch einen Endpunkt auf dem Normalenvektor. (Das sind dann meine äußersten Pfeilpixel) ... Wie kann man die bestimmen?
Ein Vektor kann als Richtung oder Koordinate interpretiert werden, aber nicht als beides gleichzeitig (also nicht als Gerade).
Hier mal ein kleiner Ansatz wie ich das gemeint hatte:
PfeilEnde1 = LinieStartpunkt + LinieVektor * 0.95 + LinieNormale * 0.1 PfeilEnde2 = LinieStartpunkt + LinieVektor * 0.95 - LinieNormale * 0.1
Du gehtst 95% entlang der Linie, dann biegst Du links oder rechts ab und läufst ein Stück davon weg. Die Längen sind so wahrscheinlich nicht hübsch, aber das wirst Du hinkriegen.