Gibt es für tkinter Vektorgrafik Bibliotheken?

Fragen zu Tkinter.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

BlackJack hat geschrieben:@Alfons Mittelmeyer: Wenn man etwas mit smooth macht und danach dann behauptet das wäre genau das was man beabsichtigt hatte, dann macht es natürlich das was man beabsichtigt. Man darf halt nur nichts beabsichtigen was nicht geht, also zum Beispiel den Vogel zeichnen. Nette ”Argumentation” die Du da gerade versuchst. :lol:
Was geht und was nicht geht, hängt davon ab, welche Informationen wir haben. Und die Informationen waren unvollständig, da man auch bei smooth gerade Linien zeichnen kann durch Koordinatenverdoppelung. Hier beide Mal smooth:

Bild

Links ohne die Information, wie man gerade Linien bei smooth bekommt. Rechts mit dieser Info und entsprechend geänderter Funktion line_to:

Code: Alles auswählen

def line_to(*args):
    for index in range(0,len(args),2):
        coordinates[0].append(args[index])
        coordinates[0].append(args[index+1])
        coordinates[0].append(args[index])
        coordinates[0].append(args[index+1])
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Sirius3 hat geschrieben:@Alfons Mittelmeyer: das sind keine Unwörter sondern die Mathematisch korrekte Wahrscheinlichkeitsangabe, dass jede nicht-triviale (nur aus einem Geradenstück bestehend) Kurve mit n Stützstellen und (n-1)*2 Kontrollpunkten wie sie bei SVG definiert sind, nicht durch eine äquivalente smooth-Kurve mit k Stützstellen wie sie bei TK definiert sind, darstellen läßt.
Woher willst Du wissen, dass sich das nicht darstellen läßt, hast Du das untersucht, oder woher hast Du diese Info?
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Also, ich habe es überprüft.

SVG verwendet sowohl quadratische als auch kubische Bezierkurven. Tkinter verwendet auch eine Bezierkurve, aber nur die quadratische. Das passt natürlich nicht für kubische Bezierkurven. Aber damit wissen wir, dass tkinter keine Kontrollpunkte rät, sondern eine quadratische Bezierkurve verwendet. Die passt natürlich gut für kreisförmige Rundungen.

Und die Kurve geht durch die Mitten von Geraden. Demnach sind die Eckpunkte dazwischen die Kontrollpunkte - nur jeweis einer statt 2 wie bei der kubischen - zwischen zwei Mitten sozusagen jeweils ein Eckpunkt als Kontrollpunkt. Aber nicht frei wählbar, da dieser Punkt zusammen mit den Mitten ja auch die beiden Eckpunkte vorher und nachher bestimmt.

Im Prinzip können wir dann eine Form durch Tangentenschnittpunkte beschreiben.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

@Sirius3 Hab es jetzt mal ausprobiert:

Bild

Grün die Polylinie bestehend aus 4 Punkten. Rot die kubische Bezierkurve. Blau die tkinter quadratische Bezierkurve. Schwarz geraten und manuell eingezeichnet eine eventuell passende Linie ebenfalls mit vier Punkten für eventuell passende Quadratische Bezierkurve. Gelb die dazu gehörige quadratische Bezierkurve.

Also es geht. Man müßte das nur mathematisch formulieren und wenn es zu ungenau werden sollte, könnte man ja auch doppelt soviele Punkte nehmen. Aber man braucht sicher nicht zehnmal so viel oder gar noch mehr, je nach erforderlicher Größe.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Die rechnerische Lösung wäre dann so: bei den kubischen Bezierkurven Tangenten berechnen, jeweils Begin und Ende und bei 1/4, 1/2, 3/4 zwischen Anfang und Ende. Die Schnittpunkte der Tangenten wären dann die Koordinaten für die Tkinter ge-smooth-te Kurve.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Nö paßt noch nicht ganz, denn zu berücksichtigen ist, dass die Kurve durch die Mitte der Tangenten geht und wir daher nicht beliebige Tangentenstücke nehmen können.

Man könnte etwa die Tangentenstücke gleich lang nehmen, oder nach welchen Kriterien sollte man sonst die Länge wählen? Gleich lang geht ja gar nicht, weil es dann in Fortführung keine Tangente mehr wäre.

Mathematisch ist das schwer hinzubekommen, daher wohl wie im vor5igen Post und sich damit abfinden, dass die Kurve dann nicht genau wie geplant durch die Mitte verläuft.
Zuletzt geändert von Alfons Mittelmeyer am Montag 30. November 2015, 19:01, insgesamt 1-mal geändert.
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

@Alfons: Bis auf Stochastik/Statistik hat Mathematik relativ wenig mit Raten zu tun. Selbst der Wikipediaartikel dazu erklärt, wie man das exakt konstruiert bzw. umrechnet - https://en.wikipedia.org/wiki/B%C3%A9zier_curve
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

@jerch Steht leider nicht drin, wie man eine kubische Bezierkurve in eine quadratische umrechnet. Steht eigentlich nur drin, wie man Bezierkurven in Werte umrechnet. Aber das haben wir ja schon implementiert.

Und eine exakte Umrechnung gibt es nicht, also muß es eine nicht exakte tun! Und die nicht Exakte wäre die Annahme, dass sich die Steigungen nicht so schnell ändern sollten, die beiden Tangentenstücke ungefähr gleich lang sein sollten und wenn es etwas abweicht, sind wir eben etwas daneben. Läßt sich aber kaum vermeiden.

Und Mathematik ist auch nicht exakt, exakt wird es in vielen Fällen erst bei n gegen unendlich. Und wir wollen nicht n gegen unendlich sondern n akzeptabel, bzw. minimal.

Und geraten hatte ich auch nicht - lediglich Augenmaßmäßig - die gelbe Kurve beruhte auf Schnittpunkt der Tangenten. War zu faul das zu berechnen und hab es pi mal Daumen eingezeichnet und war mit der Maus auch etwas neben der Tangente.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Das Problem ist, dass es doch keine quadratische Bezierkuve ist. Startpunk, Kontrollpunk, Endpunkt - hört man damit auf, ist es eine quadratische Bezierkurve, doch fährt man fort, wird es zum B-Spline und dann verschiebt sich der Endpunkt und auch die Kurve des vorletzten Teilstücks ändert sich.

Das macht es dann nicht einfach zu berechnen.
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@Alfons Mittelmeyer: es freut mich, dass Du angefangen hast, selbst Fragen zu stellen. Jetzt fehlt nur noch, dass Du daraus die richtigen Schlüsse ziehst. Du hast richtig erkannt, dass man kubische Splines nicht durch quadratische darstellen kann. Jetzt fehlt nur noch dass Du Dich fragst, was Tk macht, wenn smooth=True ist. Und was Du anderest machst, wenn Du einen kubischen Spline durch Geradenstücke annäherst.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

@Sirius3 Natürlich kann man kubische Splines durch quadratische Splines gut annähern. Die kubischen Splines sind selbst nur eine Annäherung an die Form. Exakt gibt es bei unendlichen Reihen und Folgen eh nichts, nur bis zu einer gewissen Genauigkeit auf soundsoviel Stellen und bis auf unendlich viel Stellen nach dem Komma wollen wir eh nicht rechnen, weil wir auch nicht unendlich viel Zeit haben und kein unendlich langes Papier.

Also kubische Splines lassen sich auch durch quadratische gut annähern. Allerdings sind es bei tk parabolische Splines, die tangential durch die Mitten von Geraden verlaufen oder als gerade Linie von Mitte zu Mitte, wenn die Tangenten sich nicht schneiden, weil sie gleiche oder annähernd gleiche Steigung haben.

Und ein dementsprechender Algorithmus wäre mir zu aufwändig.

Die andere Frage ist, bringt smooth etwas oder nichts? Der Unterschied ist nicht groß, wenn wir statt 3 Bezierpunkten 30 berechnete Punkte nehmen (Faktor 10):

Bild

Links ohne Smooth rechts mit Smooth bei 12 Splinesteps. Links sieht man kleine Unregelmäßigkeiten auf dem Rücken. Rechts ist es schön regelmäßig. Bei anderen Formen kann es ohne Smooth auch etwas mehr ausgefranst sein. Wie gesagt, der Unterschied ist nicht groß. Wer das links so schön regelmüäßg hinbringen möchte, kann ja die Anzahl der berechneten Punkte verzwölffachen. Dann kommt in etwa auch dasselbe so schön regelmäßig heraus wie rechts.

Nur wird dann das Ganze speicherintensiv. Eine Form durch Bezier ausgedrückt mit einer Filegröße von 4 KB wird vielleicht als TkInter Polygone bei einer Verzehnfachung der Punkte und mit tkinter Floatzahlen ausgedrückt bereits mit vielleicht 70 KB gespeichert. Wenn wir für links das nochmals verzwölffachen würden, dann wäre der Speicherplatzbedarf zum Abspeichern bereits etwa 1 MB. Und das muß ja wohl wirklich nicht sein. Außerdem werden bei solchen Datenmengen im Speicher auch Bewegungen mittels move verzögert.

Wem es auf schöne Regelmäßigkeit ankommt, sollte daher wohl besser den Smooth vorziehen statt speicherintensiver Datenmengen.

Was beim Smooth wichtig ist, ist, dass auch gerade Linien richtig kommen. Und dafür sind nicht nur die Linienendpunkte zu verdoppeln, sondern auch der Startpunkt:

Code: Alles auswählen

def line_to(*args):

            x0 = self.coordinates[-2]
            y0 = self.coordinates[-1]
            self.coordinates.extend((x0,y0))
            
            for index in range(0,len(args),2):
                self.coordinates.append(args[index])
                self.coordinates.append(args[index+1])
                self.coordinates.append(args[index])
                self.coordinates.append(args[index+1])
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Worum es bei smooth geht, ist nicht viel, lediglich dass das rechts auf seiner linken Seite etwas weniger zerrupft aussieht:

Bild

Würden wir aber mehr rechnerischen Aufwand betreiben, sollten wir bei verringerter Anzahl von Punkten die nur unzureichend durch Geradenstücke beschriebene Kurve besser bekommen, auch wenn parabolische Splines keine kubischen Bezierkurven sind.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Allmählich zeichnet sich doch eine Lösung ab. Parabolische Splines bei Polygonen durch die Mitten von Geraden, damit läßt sich wenig Vernünftiges anfangen.

Doch gibt es eine Lösung. Gibt man Anfang und Ende einer Kurve doppelt an, dann verläuft die Kurve durch diese Punkte. Ein Punkt dazwischen wäre dann ein Kontrollpunkt.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Also habe es mal ausprobiert, bringt aber ohne größeren Aufwand nichts. Zwar nähert man sich eher der gewünschten Form an, ist aber dennoch nicht exakt. Für Exaktkeit muß man auch in den Bereich derselben Auflösung (Faktor 10) gehen, sofern man nicht mehr mathematischen Aufwand betreibt. Ich hatte nur einen Punkt dazwischen als Kurvenpunkt gerechnet. Aber in diesem Bereich hört es mit mathematischer Exaktheit auf. Zwar mag ein Wert von 1.05 genauer sein als 0,95. Wenn es sich aber da um Pixel handelt, hat man zwar einen genaueren Wert berechnet, erhält aber einen unerwünschten Pixelsprung und hat den eingebauten Smooth Algorithmus wirksam ausgeschaltet, um die berechneten Werte durchzusetzen.

Besser man läßt es wie bisher und lässt den eingebauten Smooth Algorithmus auch zum Zuge kommen. Wenn es um ein Pixel hin oder her geht, so dass es auch gut aussieht und nicht zerfranst, ist der eingebaute Smooth keine schlechte Wahl.
Antworten