Transformar formas vectoriales en más del 100 % (extrapolación de formas)

Estoy buscando la herramienta que pueda realizar la combinación/transformación de dos formas vectoriales en más del 100 %, es decir, la extrapolación. La herramienta independiente o en línea o el complemento / secuencia de comandos funcionarán para mí.

No debería ser muy inteligente, está bien si requiere que ambas formas tengan la misma cantidad de puntos.

El siguiente ejemplo se realizó con el comando Blend de Illustrator. La forma más grande se dibujó manualmente, así es como espero que funcione la extrapolación de formas vectoriales.

formas extrapoladas

Estoy seguro de que las matemáticas detrás de esto son lo suficientemente simples, pero actualmente preferiría evitar profundizar en la programación bezier.

¡Hola y bienvenido a GD.SE!

Respuestas (1)

Es solo una interpolación lineal de posiciones de puntos. Aquí hay un ejemplo de script ilustrador rápido:

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

         }
}

Esta secuencia de comandos necesitaría un código adicional para la interpolación de ancho de línea/color, esquinas duras, etc. Aun así, podría ser bastante útil tal como está, y ciertamente cubre lo que pide.

resultado

Imagen 1 : interpolación de 2 líneas, colores y anotaciones agregadas para mayor claridad

algo en JavaScript dentro del navegador

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);
    }
}

Ver documento de prueba en este violín: https://jsfiddle.net/5j48geLj/

No he buscado una solución JS específica (de lo contrario, le preguntaría a SO), pero tanto la IA como el script del navegador hacen un excelente trabajo, gracias. Supongo que tendré que arreglarlo de alguna manera para interpolar bien entre los segmentos de línea y bezier.
Puede intentar extender los mangos de la línea primero y mantenerla como una línea.
@ordo como jsfiddle.net/5j48geLj/1 , por supuesto, hay formas ilimitadas de interpolar cosas, especialmente líneas.
Me refiero a problemas más triviales, por ejemplo, las rutas con la misma cantidad de vértices pueden tener una estructura de comando de ruta SVG diferente, por lo que deben convertirse primero para que coincidan entre sí. Parece una buena pregunta para SO, pero supongo que las bibliotecas de terceros (snap.svg) son de alguna ayuda.