2

I'm looking for the tool that can perform blending/morphing of two vector shapes by more than 100%, i.e. extrapolation. Standalone or online tool or plugin/script will work for me.

It shouldn't be very smart, it is ok if it requires both shapes to have the same number of points.

The following example was made with Illustrator Blend command. The biggest shape was drawn manually, that is how I expect vector shape extrapolation to work.

extrapolated shapes

I'm certain that the math behind it is simple enough but currently I would prefer to avoid digging into bezier programming.

  • Hello and welcome to GD.SE! – joojaa Jul 19 '15 at 12:54
2

Its just linear interpolation of point positions. Here is a quick illustrator script example:

#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])];

         }
}

This script would need additions code for line width/color interpolation, hard corners etc. Even so it might still pretty useful as is, and certainly covers what you ask.

result

Image 1: Interpolating 2 lines, colors and annotations added for clarity

something in JavaScript inside 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);
    }
}

See test document in this fiddle: https://jsfiddle.net/5j48geLj/

| improve this answer | |
  • I haven't looked for specific JS solution (I would ask at SO otherwise), but both AI and browser script do an excellent job, thank you. I guess I will have to fix it somehow to interpolate nicely between line and bezier segments. – ordo Jul 19 '15 at 17:56
  • You can try to extend the handles of the line first still keeping it a line. – joojaa Jul 19 '15 at 18:13
  • @ordo like jsfiddle.net/5j48geLj/1 off course there are unlimited ways to interpolate stuff, especially lines. – joojaa Jul 19 '15 at 20:47
  • I mean more trivial issues, e.g. paths with same amount of vertexes may have different SVG path command structure, so they should be converted first to match each other. It looks like a good question for SO, but I guess that third-party libraries (snap.svg) are of some help. – ordo Jul 20 '15 at 16:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.