Script para obtener posiciones x, y de una ruta en una imagen vectorial

En los viejos tiempos, si alguien tenía un gráfico científico, los lectores solo tenían acceso a la imagen rasterizada. Entonces, si desea obtener los datos sin procesar del gráfico, puede usar algo como DataThief o Webplotdigitizer en una imagen rasterizada como la que se muestra a continuación.

Ejemplo de imagen ráster

En estos días, las publicaciones científicas generalmente requieren que los autores envíen gráficos en formato vectorial (pdf o eps). Lo que significa que puede abrir directamente la trama en Illustrator y ver los datos que se trazan (¿generalmente como un objeto de ruta?). Por ejemplo, la Figura 5a de aquí es un gráfico vectorial al que se puede acceder desde el pdf (reproducido a continuación).

Del pdf referenciado Figura 5a

Mis preguntas son las siguientes:

  1. ¿Cuáles son los tipos de objetos habituales para una línea en un diagrama XY (consulte la Figura 5a en el pdf anterior )?
  2. ¿Cuál es la mejor manera de ejecutar un script sobre el objeto (en Illustrator o algún otro programa) para obtener la posición exacta de los puntos de la línea?

Editar: ya vi esta pregunta, pero en lugar de obtener un solo punto asociado con el objeto, quería la posición absoluta de todos los subpuntos (si eso tiene sentido). De esa manera puedo recrear el gráfico usando las posiciones de las etiquetas de los ejes.

Respuestas (1)

El tipo de objeto habitual para un gráfico en un gráfico vectorial es una ruta (denominada pathItem en la API JavaScript de Illustrator). Podría ser una línea irregular unida, una curva Bézier suave y, a veces, líneas rectas separadas. Depende del programa que genera el gráfico.

He escrito un pequeño guión para que empieces a extraer los puntos de un gráfico:

#target illustrator

// the current selection
var selection = app.activeDocument.selection;

// create a txt-file for the data
var file = File.saveDialog('Save a comma-separated list of the x and y coordinates of the points of the current selection, relative to the coordinate system of the artboard.', 'Comma-separated values:*.csv');

// enable writing to the file
file.open('w')

// iterate through each selected item
for (var i = 0; i < selection.length; i++) {
  var item = selection[i];

  // check if selection is a PathItem
  if (item.typename === "PathItem") {

    // every PathItem has a list of pathPoints
    var points = item.pathPoints;

    // iterate through each pathPoint of the item
    for (var j = 0; j < points.length; j++) {

      // the point in document coordinates, relative to the center of the whole document
      var documentPoint = points[j].anchor;

      // the point converted to artboard coordinates, relative to where you have placed the origin of the coordinate system
      var artboardPoint = app.activeDocument.convertCoordinate(documentPoint, app.coordinateSystem, CoordinateSystem.ARTBOARDCOORDINATESYSTEM);

      // write the artboard coordinates to the file
      file.write(artboardPoint[0] + "," + artboardPoint[1] + "\n");
    }
  }
}

// stop writing to the file and save it
file.close();

El script crea un archivo .csv que contiene una lista separada por comas de las coordenadas x e y de los puntos de la selección actual, en relación con el sistema de coordenadas de la mesa de trabajo.

Recomendaría primero mover el origen de la regla de la mesa de trabajo al origen del gráfico, luego seleccionar solo el gráfico y ejecutar el script.

Si su gráfico está hecho de líneas separadas, obtendrá muchos puntos duplicados. Puede eliminarlos en el archivo .csv o puede "limpiar" su gráfico primero usando mi script de esta respuesta o integrando los dos scripts.

Esto parece exactamente lo que quiero, voy a probarlo tan pronto como llegue a casa
Pregunta adicional, ¿qué sucede cuando la curva es más que líneas segmentadas y tiene algo así como curvas Bezier dentro de ella?
El script ignora la curva y solo devuelve la coordenada del punto de anclaje.
Ya veo, ¿hay una manera limpia de saber si el camino entre dos anclas es una línea recta, una curva bezier, etc.?
Los dos puntos de control de un pathPoint se almacenan en las propiedades "rightDirection" y "leftDirection". Si son diferentes del "ancla" es una curva, si son iguales es una línea recta. Puede consultar la documentación para obtener más información.