Thomas Meinike: SVG - Matrix-Transformationen in Komponenten zerlegen

Hallo,

ich brauche mal etwas Unterstuetzung bei der Umsetzung einer Funktion, die (speziell fuer SVG) Matrix-Transformationen in die einzelnen Grundkomponenten translate, rotate, scale, skewX, skewY zurueck fuehrt.

Der Weg in Richtung matrix(a,b,c,d,e,f) mit dem Aufbau

|a c e|
|b d f|
|0 0 1|

kann relativ einfach durch nacheinander ausgefuehrte Matrizen-Multiplikation gegangen werden, siehe MatrixCalc.

Nun wurde die (eher akademische) Frage aufgeworfen, wie man das umkehren kann. Mein in zwei Tagen ausgetueftelter Ansatz ausgehend von der Belegung der Einzel-Matrizen ist vielleicht etwas naiv, funktioniert immerhin schon ganz gut, aber noch nicht allgemeingueltig und genau hier stellen sich Fragen wie:

  • Ist die angedachte Rueckfuehrung auf Teilkomponenten ueberhaupt eindeutig loesbar?
  • Ist mein Algorithmus ein sinnvoller Ansatz bzw. welche Umsetzung waere praktikabler?

Der aktuelle Code laeuft sowohl mit dem ASV 3/6 als auch unter Firefox 1.0+ ("Deer Park Alpha 1").

Aus "matrix(2.101802,0.954189,-1.331028,0.347296,20,30)"
ensteht zurzeit "skewY(0.327000) skewX(56.462975) scale(1.978126,1.015411) rotate(69.677985) translate(20,30)".

BTW: Eine Suche nach "reverse affine matrix transformations" hat zwar viel Input gebracht, aber noch keine wirkliche Loesung.

Danke vorab fuer kreative Hinweise.

MfG, Thomas

  1. Hi,

    ich brauche mal etwas Unterstuetzung bei der Umsetzung einer Funktion, die (speziell fuer SVG) Matrix-Transformationen in die einzelnen Grundkomponenten translate, rotate, scale, skewX, skewY zurueck fuehrt.

    • Ist die angedachte Rueckfuehrung auf Teilkomponenten ueberhaupt eindeutig loesbar?

    M.E: nein.

    Wenn Du das Produkt 24 hast, kannst Du auch nicht eindeutig auf die Faktoren schließen (2*12, 3*8, 4*6, 2*2*6, 2*2*2*3, …)

    Bei Matrizen ist das nicht anders.

    Du kannst vielleicht eine der möglichen Kombinationen herausfinden, vielleicht auch mehrere. Aber eindeutig ist das m.E. nicht.
    Beispiel:

    ein Einheitskreis um den Ursprung.
    Das wird mit Faktor 2 skaliert
    Dann wird um 4 Einheiten nach rechts verschoben.
    ==> Kreis mit Radius 2 um Punkt 4,0

    ein Einheitskreis um den Ursprung.
    Der wird um 2 Einheiten nach rechts verschoben.
    Dann wird das ganze um Faktor 2 skaliert
    ==> Kreis mit Radius 2 um Punkt 4,0

    Wenn Du nur den Ursprungszustand (Einheitskreis um den Ursprung) und das Ergebnis (Kreis mit Radius 2 um Punkt 4,0) kennst, kannst Du nicht eindeutig ermitteln, welche Transformationen verwendet wurden.

    cu,
    Andreas

    --
    Warum nennt sich Andreas hier MudGuard?
    Schreinerei Waechter
    Fachfragen per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
    1. Hallo,

      Du kannst vielleicht eine der möglichen Kombinationen herausfinden, vielleicht auch mehrere. Aber eindeutig ist das m.E. nicht.

      Diese Annahme habe ich auch im Hinterkopf, wobei mir _eine_ uebereinstimmende Kombination ja reichen wuerde. Im SVG-Kontext ist die matrix()-Schreibweise ideal und es besteht kaum Grund, das rueckgaengig zu machen.

      Nun suche ich einen Ansatz fuer den Fall, dass eine SVG-Matrix-Form vorliegt, aber in einer anderen Software nur die Einzel-Transformationen moeglich sind und eben diese von Interesse sind.

      MfG, Thomas

      1. Hallo Thomas,

        Eindeutig ist das auf keinen Fall. Da kann man sich ja schnell ein paar Beispiele von Transformationen überlegen, die sich wieder aufheben lassen.

        Abgesehen davon sind die Matrizen M der Form [[a,b,c],[d,e,f],[0,0,1]] für -ae + bd != 0 invertierbar, sofern ich meinem Formelmanipulationsprogramm trauen kann. Das von Hand zu rechnen ist mir jetzt zu aufwendig.

        Daraus kann man dann auch einen Beweis basteln, warum sich nicht alle Matrizen M durch die anderen Transformationen darstellen lassen.

        Zuerst schließen wir den Fall a = 0 v b = 0 aus.
        M ist dann immer noch nicht in allen Fällen invertierbar, aber alle anderen Transformationen sind es.
        Damit sind auch alle Matrizen, die aus diesen Transformationen zusammengesetzt werden können invertierbar.

        ==> Nicht alle Matrizen sind durch die anderen Transformationen darstellbar.

        Grüße

        Daniel

    2. Hallo,

      Du kannst vielleicht eine der möglichen Kombinationen herausfinden, vielleicht auch mehrere.

      Es sollte wohl darauf hinauslaufen, dass man sich eine Reihenfolge der Operationen (= eine Loesung) vorgibt, diese als Matrizengleichung aufschreibt und das enstehende Produkt-Gleichungssystem entsprechend nach den gewueschten Parametern aufloest, z. B. so:

      |   1     0 0|   |1 tan(skx) 0|   |scx 0  0|   |cos(ro) -sin(ro) 0|   |1 0 tx|   |a c e|
      |tan(sky) 1 0| * |0    1     0| * | 0 scy 0| * |sin(ro)  cos(ro) 0| * |0 1 ty| = |b d f|
      |   0     0 1|   |0    0     1|   | 0  0  1|   |   0        0    1|   |0 0  1|   |0 0 1|

      skewY            skewX           scale            rotate          translate   matrix

      MfG, Thomas

  2. Hallo,

    • Ist mein Algorithmus ein sinnvoller Ansatz bzw. welche Umsetzung waere praktikabler?

    Ausgehend von meinem Denkansatz konnte ich unter Verwendung von MuPAD einen brauchbar erscheinenden Algorithmus fuer den Fall skewY=0 ableiten: [numerisch | analytisch] und in JavaScript-Code umsetzen.

    Mein spezieller Dank geht an Daniel Thoma fuer den Austausch hilfreicher Hinweise zu MuPAD per Mail.

    MfG, Thomas