Vektorformen um mehr als 100 % morphen (Formextrapolation)

Ich suche nach dem Werkzeug, das zwei Vektorformen zu mehr als 100 % mischen/morphen kann, dh extrapoliert. Standalone- oder Online-Tool oder Plugin/Skript funktionieren für mich.

Es sollte nicht sehr schlau sein, es ist in Ordnung, wenn es erfordert, dass beide Formen die gleiche Anzahl von Punkten haben.

Das folgende Beispiel wurde mit dem Befehl „Illustrator Blend“ erstellt. Die größte Form wurde manuell gezeichnet, so erwarte ich, dass die Vektorform-Extrapolation funktioniert.

extrapolierte Formen

Ich bin mir sicher, dass die Mathematik dahinter einfach genug ist, aber derzeit würde ich es vorziehen, mich nicht mit der Bezier-Programmierung zu beschäftigen.

Hallo und willkommen bei GD.SE!

Antworten (1)

Es ist nur eine lineare Interpolation von Punktpositionen. Hier ist ein kurzes Beispiel für ein Illustrator-Skript:

#target illustrator


var sel = app.activeDocument.selection; 

if (sel.length === 2){
    if(sel[0].typename == "PathItem" && 
       sel[1].typename == "PathItem") {
         for (var incr=-0.4; incr < 1.5; incr += 0.2){
             if (incr != 0 && incr !=1)
                  interpolate2Curves(sel[0], sel[1], incr);
         }
    }
} else { 
    alert("select 2 curves");
}

function interpolate2Curves(c1,c2, amount) {
     var pts1 = sel[0].pathPoints;
     var pts2 = sel[1].pathPoints;
     var target = sel[0].duplicate();
     var t = target.pathPoints;
     for (var i=0;i<pts1.length;i++){
         var p1 = pts1[i].anchor;
         var p2 = pts2[i].anchor;
         t[i].anchor=[p1[0]+ amount*(p2[0]-p1[0]),
                      p1[1] + amount*(p2[1]-p1[1])];

         var p1 = pts1[i].rightDirection;
         var p2 = pts2[i].rightDirection;
         t[i].rightDirection=[p1[0]+ amount*(p2[0]-p1[0]),
                              p1[1] + amount*(p2[1]-p1[1])];

         var p1 = pts1[i].leftDirection;
         var p2 = pts2[i].leftDirection;
         t[i].leftDirection=[p1[0]+ amount*(p2[0]-p1[0]), 
                             p1[1] + amount*(p2[1]-p1[1])];

         }
}

Dieses Skript würde zusätzlichen Code für Linienbreiten-/Farbinterpolation, harte Ecken usw. benötigen. Trotzdem könnte es so wie es ist immer noch ziemlich nützlich sein und deckt sicherlich ab, was Sie fragen.

Ergebnis

Bild 1 : Interpolation von 2 Zeilen, Farben und Anmerkungen zur Verdeutlichung hinzugefügt

etwas in JavaScript im Browser

function interpolate2Curves(t){
    var path1 = document.getElementById('a');
    var path2 = document.getElementById('b');
    var path3 = document.getElementById('t');
    var sl1 = path1.pathSegList;
    var sl2 = path2.pathSegList;
    var sl3 = path3.pathSegList;
    for (var i=0,len=sl3.numberOfItems;i<len;++i){
        var s1 = sl1.getItem(i);
        var s2 = sl2.getItem(i);
        var s3 = sl3.getItem(i);
        s3.x = s1.x + t*(s2.x - s1.x);
        s3.y = s1.y + t*(s2.y - s1.y);

        s3.x1 = s1.x1 + t*(s2.x1 - s1.x1);
        s3.y1 = s1.y1 + t*(s2.y1 - s1.y1);

        s3.x2 = s1.x2 + t*(s2.x2 - s1.x2);
        s3.y2 = s1.y2 + t*(s2.y2 - s1.y2);
    }
}

Siehe Testdokument in dieser Geige: https://jsfiddle.net/5j48geLj/

Ich habe nicht nach einer bestimmten JS-Lösung gesucht (sonst würde ich bei SO nachfragen), aber sowohl die KI als auch das Browserskript leisten hervorragende Arbeit, danke. Ich denke, ich muss es irgendwie reparieren, um gut zwischen Linien- und Bezier-Segmenten zu interpolieren.
Sie können versuchen, zuerst die Griffe der Linie zu verlängern und dabei eine Linie beizubehalten.
@ordo wie jsfiddle.net/5j48geLj/1 Natürlich gibt es unbegrenzte Möglichkeiten, Dinge zu interpolieren, insbesondere Linien.
Ich meine trivialere Probleme, z. B. Pfade mit der gleichen Anzahl von Scheitelpunkten können unterschiedliche SVG-Pfadbefehlsstrukturen haben, daher sollten sie zuerst konvertiert werden, damit sie zueinander passen. Es sieht nach einer guten Frage für SO aus, aber ich denke, dass Bibliotheken von Drittanbietern (snap.svg) hilfreich sind.