Seite 1 von 1

[GELÖST] Fehler beim Rand malen von QGraphicsPolygonItem

Verfasst: 14. Januar 2010 10:09
von mabralume
Hallo, ich habe folgendes Problem ,

ich möchte beliebige geometrische Formen mit Hilfe von QGraphicsItems in einer GraphicsView so überlagern, das der Inhalt der geometrischen Figuren exakt gefüllt ist :

Folgende Figuren ...

Bild

werden mit QGraphicsPolygonItem überlagert :

Bild

Nahansicht :

Bild

... wie man sieht, paßt das Polygon exakt auf den geometrischen Untergrund. Nun will ich aber NUR die grüne Fläche haben, ich möchte den Rand ausblenden, also setze ich die Farbe für den Rand des Polygon auf Alphwert = 0 für vollständig transparent :

Bild

im Ergebnis sieht man nun aber, daß NUR die untere und die rechte Seite Transparent gesetzt wird, aber nicht die linke und die obere Seite. Ganz im Gegenteil, es wird einfach der linke und er obere Rand mit der Brushfarbe eingefärbt. Somit läßt sich das Polygon nicht mal mehr innerhalb der zugrundeliegenden geometrischen Form vermitteln ...

Bild

Ist das ein BUG oder muß ich noch irgendwas mit dem Polygon machen ? Wie gesagt, ich setze die Randfarbe nur auf transparent, ich nehme den Rand ja nicht weg. Er ist ja noch da !

Qt-Version 4.4.3 X11
FreeBSD 7.1
Xorg 7.3_2

Also, muß ich, nachdem ich die Randfarbe auf transparent gesetzt habe noch etwas mit dem Polygon machen, damit er wirklich den kompletten Rand transparent macht ? Oder ist es ein Fehler in den grafischen Routinen in der Version und mit einem neueren QT tritt dies nicht mehr auf ?

mfg
MB

p.s.:
Es ist übrigends egal, ob das Polygon geschlossen ist oder nicht. Ich habe extra mit isClosed() geprüft. Außerdem habe ich die Eckpunkte mit in's Polygon eingebunden (sieht man im Screenshot, das die da fehlen) und das Verhalten ist dasselbe :(

Verfasst: 14. Januar 2010 12:14
von upsala
Wenn es keinen Rand gibt, wird mit der Füllfarbe am Rand entlanggemalt. Aber nur so ungefähr...

Verfasst: 14. Januar 2010 12:20
von mabralume
Hmm, ja, aber es gibt ja einen Rand, der ist nur transparent. Und wenn der Rand mit der Füllfarbe gemalt wird, warum dann nicht der komplette Rand ? :?:

mfg
MB

Verfasst: 14. Januar 2010 12:53
von N¤X
Das ist wohl kein Bug sondern so beabsichtigt.
Der Gedanke dahinter: Wenn du zwei aneinander angrenzende Polygone zeichnen willst wirst du das wohl so machen, dass sie sich an der Kante an der sie sich berühren die Vertices teilen, die Kante gehört also zu beiden Polygonen. Mathematisch ist das kein Problem, weil die Kante unendlich dünn ist, aber gezeichnet wird sie halt doch einen Pixel breit (dünner geht ja nicht), weshalb bei Graphikbliotheken für gewöhnlich entweder die rechte oder die linke respektive die obere oder untere Kante von Polygonen nicht gezeichnet wird, um ein lückenloses Anschließen ohne Overdraw zu gewährleisten.
Ein Beispiel (in 1D): Du zeichnest eine bote Linie von 0 bis 5 und eine blaue von 5 bis 10. Würden beide Linien tatsächlich 6 Pixel lang gezeichnet würde die Farbe von Pixel 5 von der Reihenfolge abhängen in der gezeichnet wurde, weil sich die Linien an diesem Punkt überlagern. Also wird von 0 bis einschließlich 4 rot und von 5 bis einschließlich 9 (10 nicht!) blau gezeichnet.

Wenn man das erstmal weiß kann man bei pixelgenauem Zeichnen einfach die rechte und untere (oder wie es bei der Bib auch immer geregelt ist) Kante einen Pixel weiter nach außen setzen und bekommt das Ergebnis das man eigentlich wollte (und zwar konsistent, ist also kein hässlicher Workaround oder so). ;)

PS: Das gilt aber, wie du wohl festgestellt hast, nur für Randlose Polygone, da diese wohl eher dafür gedacht sind aneinandergefügt zu werden. Der Rahmen selbst wird an genau den Positionen gemalt, an denen du ihn haben willst, der ist ja auch kein Polygon sondern nur ne Linie, für die wieder andere Paradigmen gelten. Du könntest also auch einfach deine Rahmenfarbe auf die Füllfarbe setzen und so weitermachen. :roll:

Verfasst: 14. Januar 2010 13:32
von mabralume
Das ist wohl kein Bug sondern so beabsichtigt.
Der Gedanke dahinter: Wenn du zwei aneinander angrenzende Polygone zeichnen willst wirst du das wohl so machen, dass sie sich an der Kante an der sie sich berühren die Vertices teilen, die Kante gehört also zu beiden Polygonen. Mathematisch ist das kein Problem, weil die Kante unendlich dünn ist, aber gezeichnet wird sie halt doch einen Pixel breit (dünner geht ja nicht), weshalb bei Graphikbliotheken für gewöhnlich entweder die rechte oder die linke respektive die obere oder untere Kante von Polygonen nicht gezeichnet wird, um ein lückenloses Anschließen ohne Overdraw zu gewährleisten.
Ein Beispiel (in 1D): Du zeichnest eine bote Linie von 0 bis 5 und eine blaue von 5 bis 10. Würden beide Linien tatsächlich 6 Pixel lang gezeichnet würde die Farbe von Pixel 5 von der Reihenfolge abhängen in der gezeichnet wurde, weil sich die Linien an diesem Punkt überlagern. Also wird von 0 bis einschließlich 4 rot und von 5 bis einschließlich 9 (10 nicht!) blau gezeichnet.

Wenn man das erstmal weiß kann man bei pixelgenauem Zeichnen einfach die rechte und untere (oder wie es bei der Bib auch immer geregelt ist) Kante einen Pixel weiter nach außen setzen und bekommt das Ergebnis das man eigentlich wollte (und zwar konsistent, ist also kein hässlicher Workaround oder so). Wink
... hmm, okay, danke für den Tipp :D werd mal schauen wie ich das einbaue .
Das gilt aber, wie du wohl festgestellt hast, nur für Randlose Polygone,
... und genau das verstehe ich nicht. Ich hab mir nämlich sowas denken können und habe deshalb bewußt NICHT Qt::NoPen gewählt, sondern ich habe mir gesagt, das ne transparente Farbe eben eine Farbe ist und deshalb techn. gesehen der Rand noch da ist. Ich wußte nicht, das Qt dahergeht und sagt, wenn volle Transparenz,dann nicht vorhanden **schulterzuck** wieder was gelernt ...
Du könntest also auch einfach deine Rahmenfarbe auf die Füllfarbe setzen und so weitermachen.
:roll: das kann ich nicht, weil :

Bild

.. passiert. Ich habe einen Algorithmus geschrieben, welcher zu einem Polygon allle inneren Polygone erkennt und diese dann mit subtrcted vom Hauptpolygon abzieht. Dummerweise meint auch hier die Bibliothek mir das Denken abzunehmen und macht eben Verbindungslinien vom Hauptpolygon zu den inneren Polygonen. Damit man diese nicht sieht, habe ich halt auf Transparenz gesetzt ...

Wenn mir jemand sagen kann, wie ich sutracted bei Polygonen vernünfig einsetzen kann, OHNE das die Verbindungslinien gemalt werden, dann bin ich ganz Ohr :wink:

mfg
MB

p.s.:
Hier mit schwarzem Rand (standard)

Bild

... und hier mit transparenz :

Bild

Verfasst: 14. Januar 2010 15:59
von upsala
Verwendest du:

Code: Alles auswählen

QPainterPath subtracted ( const QPainterPath & p ) const

Verfasst: 14. Januar 2010 16:31
von mabralume
Nein, in QPolygon gibt es auch ne substracted - Funktion :

Code: Alles auswählen

QPolygonF QPolygonF::subtracted ( const QPolygonF & r ) const
Returns a polygon which is r subtracted from this polygon.
This function was introduced in Qt 4.3.
... kann natürlich sein, daß die in Ihrer QPolygon-Klasse eben die subtracted - Funktion von Painterpath benutzen, soo genau habe ich mir den Quellcode da nit angeschaut ... :oops:

Vlcht. darf ich die aber nicht nehmen ? Weiß nicht, wie ich sonst die Figuren "rausschneiden" soll. Also ich habe ein Polygon welches beliebige Polygone umfaßt. Ich möchte gerne dieses Polygon OHNE die inneren Polygone haben.

Vlcht. ist mein Ansatz ja auch falsch ...

@N¤X, Du bist doch Grafikprogramierer, hast Du vlcht. ne andere Richtung parat ?

thx schonmal an Euch für das Interesse :)

mfg
MB

Verfasst: 14. Januar 2010 16:56
von upsala
Dann mach mal einen QPainterPath daraus und subtrahiere. QPainterPath kann nämlich auch mit unterbrechungen umgehen. QPolygon nicht.

Verfasst: 14. Januar 2010 17:01
von mabralume
Oha :o , das muß ich ausprobieren ! THX :)

mfg
MB

Verfasst: 14. Januar 2010 17:43
von mabralume
:P :P :P :P :P :P :D :D :D

thx an Dir @upsala, mit QPainterPath funktioniert es. Sogar irgendwie schneller ... :?: , ach egal, danke DIR.

mfg
MB :) :)