Skip to main content
Known Participant
August 24, 2016
Answered

Cutting angled points only

  • August 24, 2016
  • 2 replies
  • 1506 views

Odd question but one I've had for a while. In my work there have been times when I needed to convert a shape to a series of lines, keeping the curved parts but breaking the line where it angles. Anybody know of a trick to this other than manually selecting them?

This topic has been closed for replies.
Correct answer o-marat

kylwell, maybe this script will do.

/**

* ai.jsx (c)MaratShagiev m_js@bk.ru 27.08.2016

*

* cutPathByCornerPoints_v1.0

*

* Using:

* * Select a single path item;

* * Run the script

*

* Great destination:

* * cutting path item into pieces;

* * the point of cutting path item - corner points;

* * cut closed and open paths;

*

* What is really going on here:

* * source circuit is used as a model;

* * on top of the original path created new paths;

* * the original path is deleted;

*/

//@target illustrator

cutByCornPnts (selection[0]);

function cutByCornPnts (pth) {

  if (_cut (pth)) pth.remove ();

  function _cut (pth) {

    var remPth = false;

    if (pth.closed) {

      for (var i = 0; i < pth.pathPoints.length; i++) {

        var pnt = pth.pathPoints;

        if (!__isCornerPoint (pnt)) continue;

        __addPathByTmpl (pth, i);

        remPth = true;

      }

    } else {

      for (var i = 0; i < pth.pathPoints.length; i++) {

        var pnt = pth.pathPoints;

        i       = __addPathByTmpl (pth, i);

        remPth  = true;

      }

    }

    return remPth;

    function __addPathByTmpl (pathTmpl, iStartPnt) {

      var doc       = activeDocument,

          j, pntTmpl, pthDupl, pnt,

          endPthAdd = 0,

          pnts      = [pathTmpl.pathPoints [iStartPnt]];

      if (pathTmpl.closed) endPthAdd = 1;

      try {

        for (j = iStartPnt + 1; j < pathTmpl.pathPoints.length + endPthAdd; j++) {

          pntTmpl = pathTmpl.pathPoints;

          if (__isCornerPoint (pntTmpl)) {

            pnts.push (pntTmpl);

            break;

          }

          pntTmpl = pathTmpl.pathPoints;

          pnts.push (pntTmpl);

        }

      } catch (e) {

        for (j = 0; j < iStartPnt + endPthAdd; j++) {

          pntTmpl = pathTmpl.pathPoints;

          if (__isCornerPoint (pntTmpl)) {

            pnts.push (pntTmpl);

            break;

          }

          pntTmpl = pathTmpl.pathPoints;

          pnts.push (pntTmpl);

        }

      }

      if (pnts.length > 1) {

        pthDupl = doc.pathItems.add ();

        for (var i = 0; i < pnts.length; i++) {

          var pnt          = pnts;

          var p            = pthDupl.pathPoints.add ();

          p.anchor         = [pnt.anchor[0], pnt.anchor[1]];

          p.leftDirection  = [pnt.leftDirection[0], pnt.leftDirection[1]];

          p.rightDirection = [pnt.rightDirection[0], pnt.rightDirection[1]];

          p.pointType      = pnt.pointType;

        }

      }

      iStartPnt = j; // for closed paths

      return --j; // for open paths

    }

    /**

     * Unfortunately the Pen Tool creates all the points as smooth.

     * Even if in fact they are corner.

     * One way to solve this problem -

     * check all the points with this helper.

     *

     * @param {Object} pnt - object of class PathPoint

     * @return {Boolean}

     * */

    function __isCornerPoint (pnt) {

      if (pnt.pointType == PointType.CORNER) return true;

      var x_1, x_2, x_3,

          y_1, y_2, y_3,

          prec    = 100000,

          precLow = 10;

      x_1 = Math.round (pnt.leftDirection [0] * prec) / prec; // x

      y_1 = Math.round (pnt.leftDirection [1] * prec) / prec; // y

      x_2 = Math.round (pnt.rightDirection [0] * prec) / prec;

      y_2 = Math.round (pnt.rightDirection [1] * prec) / prec;

      x_3 = Math.round (pnt.anchor [0] * prec) / prec;

      y_3 = Math.round (pnt.anchor [1] * prec) / prec;

      if ((x_1 == x_2 && x_2 == x_3) && (y_1 == y_2 && y_2 == y_3)) return true;

      if ((x_1 == x_2) && (y_1 == y_2)) return true; // directions is equals

      if ((x_1 == x_3) && (y_1 == y_3)) return true; // left directon equals with anchor

      if ((x_2 == x_3) && (y_2 == y_3)) return true; // right direction equals with anchor

      // The equation of a straight line

      // points 1, 2, 3 are not equal and don't lie on one straight line

      if (

        Math.ceil (((x_3 - x_1) * (y_2 - y_1)) * precLow) / precLow !=

        Math.ceil (((x_2 - x_1) * (y_3 - y_1)) * precLow) / precLow

      ) return true;

      return false;

    }

  }

}

2 replies

o-marat
Inspiring
August 25, 2016

Another way - to draw  the new paths (by/using data of) the points of the initial path. Then initial path is removed...

kylwellAuthor
Known Participant
August 25, 2016

The only problem with that is I would be redrawing some 100+ paths. The stuff I create can get... complex. While I've done it before I was hoping somebody knew of a script that could help speed the process up. That and it gets really annoying to cut everything and then realize it doesn't work and I need to adjust my offsets.

o-marat
o-maratCorrect answer
Inspiring
August 27, 2016

kylwell, maybe this script will do.

/**

* ai.jsx (c)MaratShagiev m_js@bk.ru 27.08.2016

*

* cutPathByCornerPoints_v1.0

*

* Using:

* * Select a single path item;

* * Run the script

*

* Great destination:

* * cutting path item into pieces;

* * the point of cutting path item - corner points;

* * cut closed and open paths;

*

* What is really going on here:

* * source circuit is used as a model;

* * on top of the original path created new paths;

* * the original path is deleted;

*/

//@target illustrator

cutByCornPnts (selection[0]);

function cutByCornPnts (pth) {

  if (_cut (pth)) pth.remove ();

  function _cut (pth) {

    var remPth = false;

    if (pth.closed) {

      for (var i = 0; i < pth.pathPoints.length; i++) {

        var pnt = pth.pathPoints;

        if (!__isCornerPoint (pnt)) continue;

        __addPathByTmpl (pth, i);

        remPth = true;

      }

    } else {

      for (var i = 0; i < pth.pathPoints.length; i++) {

        var pnt = pth.pathPoints;

        i       = __addPathByTmpl (pth, i);

        remPth  = true;

      }

    }

    return remPth;

    function __addPathByTmpl (pathTmpl, iStartPnt) {

      var doc       = activeDocument,

          j, pntTmpl, pthDupl, pnt,

          endPthAdd = 0,

          pnts      = [pathTmpl.pathPoints [iStartPnt]];

      if (pathTmpl.closed) endPthAdd = 1;

      try {

        for (j = iStartPnt + 1; j < pathTmpl.pathPoints.length + endPthAdd; j++) {

          pntTmpl = pathTmpl.pathPoints;

          if (__isCornerPoint (pntTmpl)) {

            pnts.push (pntTmpl);

            break;

          }

          pntTmpl = pathTmpl.pathPoints;

          pnts.push (pntTmpl);

        }

      } catch (e) {

        for (j = 0; j < iStartPnt + endPthAdd; j++) {

          pntTmpl = pathTmpl.pathPoints;

          if (__isCornerPoint (pntTmpl)) {

            pnts.push (pntTmpl);

            break;

          }

          pntTmpl = pathTmpl.pathPoints;

          pnts.push (pntTmpl);

        }

      }

      if (pnts.length > 1) {

        pthDupl = doc.pathItems.add ();

        for (var i = 0; i < pnts.length; i++) {

          var pnt          = pnts;

          var p            = pthDupl.pathPoints.add ();

          p.anchor         = [pnt.anchor[0], pnt.anchor[1]];

          p.leftDirection  = [pnt.leftDirection[0], pnt.leftDirection[1]];

          p.rightDirection = [pnt.rightDirection[0], pnt.rightDirection[1]];

          p.pointType      = pnt.pointType;

        }

      }

      iStartPnt = j; // for closed paths

      return --j; // for open paths

    }

    /**

     * Unfortunately the Pen Tool creates all the points as smooth.

     * Even if in fact they are corner.

     * One way to solve this problem -

     * check all the points with this helper.

     *

     * @param {Object} pnt - object of class PathPoint

     * @return {Boolean}

     * */

    function __isCornerPoint (pnt) {

      if (pnt.pointType == PointType.CORNER) return true;

      var x_1, x_2, x_3,

          y_1, y_2, y_3,

          prec    = 100000,

          precLow = 10;

      x_1 = Math.round (pnt.leftDirection [0] * prec) / prec; // x

      y_1 = Math.round (pnt.leftDirection [1] * prec) / prec; // y

      x_2 = Math.round (pnt.rightDirection [0] * prec) / prec;

      y_2 = Math.round (pnt.rightDirection [1] * prec) / prec;

      x_3 = Math.round (pnt.anchor [0] * prec) / prec;

      y_3 = Math.round (pnt.anchor [1] * prec) / prec;

      if ((x_1 == x_2 && x_2 == x_3) && (y_1 == y_2 && y_2 == y_3)) return true;

      if ((x_1 == x_2) && (y_1 == y_2)) return true; // directions is equals

      if ((x_1 == x_3) && (y_1 == y_3)) return true; // left directon equals with anchor

      if ((x_2 == x_3) && (y_2 == y_3)) return true; // right direction equals with anchor

      // The equation of a straight line

      // points 1, 2, 3 are not equal and don't lie on one straight line

      if (

        Math.ceil (((x_3 - x_1) * (y_2 - y_1)) * precLow) / precLow !=

        Math.ceil (((x_2 - x_1) * (y_3 - y_1)) * precLow) / precLow

      ) return true;

      return false;

    }

  }

}

o-marat
Inspiring
August 24, 2016

kylwell​, hi!

This is a function (compatible CS6+) that cuts the shape, which consists only of the corner points (star, poligon, rectangle).

If I'm on the right way I can add code to handle any paths.

Before running the script, you need to select the shape.

//@target illustrator

(function cutCornerShapeByPoints (pth) {

  var i, pnt, nextPnt, pthCut;

  executeMenuCommand ('deselectall');

  for (i = 0; i < pth.pathPoints.length; i++) {

    try {

      pnt     = pth.pathPoints;

      nextPnt = pth.pathPoints[i + 1];

    } catch (e) {

      nextPnt = pth.pathPoints[0];

    }

    pnt.selected = PathPointSelection.ANCHORPOINT;

      executeMenuCommand ('copy');

      executeMenuCommand ('pasteFront');

      pthCut = selection[0];

      pthCut.pathPoints[0].remove ();

      executeMenuCommand ('deselectall');

    } 

  pth.remove ();

} (selection[0]));