Skip navigation
Currently Being Moderated

Delete unnecessary points

Nov 24, 2009 3:16 PM

Please see this post in the main forum. I am looking for a script (if one exists) that will delete unnecessary/redundant points.

 

My OP:

 

Let's say I have a rectangle, and in addition to the corner points, there are extra points along the paths. I want to get rid of these, as they have no purpose. Object> Path> Simplify doesn't do it, nor does Object> Path> Cleanup. I can use Remove Anchor points, but I have to select them all first.

 

Thanks.

 
Replies
  • Currently Being Moderated
    Nov 29, 2009 12:12 AM   in reply to Cheryl Graham

    if you`re looking for rectangle "simplify" here's a snipper that might help ... covering a wider range of shapes may take a few hours which i dun have atm ... anyway this should work with rectangle shapes ...:

     

    (script runs over the whole pathitems collection in a document)

     

    var Geometry2DHelper = {
        isCorner: function(pt, pt1, pt2) {
            var prnt = pt.parent;
            if((this.isVertical(pt, pt1) && this.isHorizontal(pt,pt2)) || (this.isVertical(pt, pt2) && this.isHorizontal(pt, pt1))) return true;
            var slope1 = (pt.anchor[1] - pt1.anchor[1]).toFixed(2) / (pt.anchor[0] - pt1.anchor[0]).toFixed(2);
            var slope2 = (pt.anchor[1] - pt2.anchor[1]).toFixed(2) / (pt.anchor[0] - pt2.anchor[0]).toFixed(2);
            if(slope1*slope2 == -1) return true;
            else return false;
        },
        isVertical: function(pt1, pt2) {
            if(pt1.anchor[0].toFixed(2) == pt2.anchor[0].toFixed(2)) return true;
            return false;
        },
        isHorizontal: function(pt1, pt2) {
            if(pt1.anchor[1].toFixed(2) == pt2.anchor[1].toFixed(2)) return true;
            return false;
        }
    }

     

    for(j = app.activeDocument.pathItems.length - 1; j >= 0; j--) {
        var sides = 0;
        var sel = app.activeDocument.pathItems[j];
        var removeArr = [];

        for(i = sel.pathPoints.length - 1; i >= 0 ; i--) {
            var pt1 = (i == sel.pathPoints.length-1) ? sel.pathPoints[0] : sel.pathPoints[i + 1];
            var pt2 = (i == 0) ? sel.pathPoints[sel.pathPoints.length-1] : sel.pathPoints[i - 1];       
            if(!Geometry2DHelper.isCorner(sel.pathPoints[i], pt1, pt2)) {
                removeArr.push(sel.pathPoints[i]);           
            } else sides++;
        }
        if(sides == 4 && removeArr.length > 0) {
            for(m = removeArr.length - 1; m >= 0; m--) {
                removeArr[m].remove();
                 app.activeDocument.pageItems[j].closed = true;
            }
        }
    }

     

     

    hope it somehow helps;

    cheers;

     

    *later edit* fixed the fact that the script was deleting paths other than rectangle ... well ... no shapes no problems or was it the other way

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 29, 2009 4:23 AM   in reply to sonicDream

    this may work simplyfing the straight lines in a document regardless of the shape ... since my coffee is not ready yet i didn't test it, but should work:

     

    var Geometry2DHelper = {
        getSlope: function(pt1, pt2){
            var i1 = pt1.anchor[1] - pt2.anchor[1];
            var i2 = pt1.anchor[0] - pt2.anchor[0];
            var slope = (i2 == 0) ? null : i1/i2;
            return (slope == 0) ? 0 : slope;
        },
        getConstructionPoints: function(path) {
            var pts = path.pathPoints;
            var ctspts = "";
            var x = 0;
            if(pts.length < 3) return [];
            for(i = pts.length - 1; i>=0;i--) {
                var pt1 = (i == pts.length - 1) ? pts[0] : pts[i + 1];
                var pt2 = (i == 0) ? pts[pts.length - 1] : pts[i - 1];
                var slope = (this.getSlope(pts[i], pt1)!=null) ? this.getSlope(pts[i], pt1).toFixed(2) : null;
                var slope2 = (this.getSlope(pts[i], pt2)!=null) ? this.getSlope(pts[i], pt2).toFixed(2) : null;
                if(slope != slope2) ctspts += "|" + i + "|";
            }
            return ctspts;
        },
        remove: function(path, whitelist) {
            var pts = path.pathPoints;
            if(whitelist=="") {
                for(i = pts.length - 1; i>= 0; i--) {
                    if(i != pts.length - 1 && i!= 0) {pts[i].remove(); continue;}
                }
                return;
            }       
            for(i = pts.length - 1; i>= 0; i--) {
                if(whitelist.indexOf("|" + i + "|") < 0) {pts[i].remove(); }
            }
        },
        isVertical: function(pt1, pt2) {
            if(pt1.anchor[0].toFixed(1) == pt2.anchor[0].toFixed(1)) return true;
            return false;
        },
        isHorizontal: function(pt1, pt2) {
            if(pt1.anchor[1].toFixed(1) == pt2.anchor[1].toFixed(1)) return true;
            return false;
        }
    }
    for(j = app.activeDocument.pathItems.length - 1; j >= 0; j--) {
        var x = Geometry2DHelper.getConstructionPoints(app.activeDocument.pathItems[j ]);
        Geometry2DHelper.remove(app.activeDocument.pageItems[j], x); 
    }

     

    hope it helps;

    cheers;

     
    |
    Mark as:
  • Currently Being Moderated
    Aug 26, 2010 7:42 PM   in reply to sonicDream

    Wow, thanks for the effort !

     

    However, when I run the script on the object, it returns this error :

     

    Screen shot 2010-08-26 at 11.39.54 PM.png

     

    This to me is greek, so can you figure it out ?

     

    Thanks

     
    |
    Mark as:
  • Currently Being Moderated
    Sep 5, 2011 7:24 PM   in reply to sonicDream

    My God, I've dreamed of it for years.
    Unfortunally, it doesn't work with paths that include smooth points, only sharp with no handles; otherwise it gives same error João Faraco encountered.
    Oh mighty sonicDream, hear my call from far-far russian city on the south-east shore: finish this script! Just make it ignore and skip bezier parts, or let it work only with selected points. Anyway, it is awesome. You have no idea how useful it is in my work. Bless you. Please.

     
    |
    Mark as:
  • Currently Being Moderated
    Sep 7, 2011 2:12 AM   in reply to achegr

    Actually is works with paths that include smooth points. The problem maybe relative to "Undo" operation. So I wrap it into a anonymous function and seems it's ok now.

     

    (function (){
         var Geometry2DHelper = {
              getSlope: function(pt1, pt2){
                   var i1 = pt1.anchor[1] - pt2.anchor[1];
                   var i2 = pt1.anchor[0] - pt2.anchor[0];
                   var slope = (i2 == 0) ? null : i1/i2;
                   return (slope == 0) ? 0 : slope;
              },
              getConstructionPoints: function(path) {
                   var pts = path.pathPoints;
                   var ctspts = "";
                   var x = 0;
                   if(pts.length < 3) return [];
                   for(i = pts.length - 1; i>=0;i--) {
                        var pt1 = (i == pts.length - 1) ? pts[0] : pts[i + 1];
                        var pt2 = (i == 0) ? pts[pts.length - 1] : pts[i - 1];
                        var slope = (this.getSlope(pts[i], pt1)!=null) ? this.getSlope(pts[i], pt1).toFixed(2) : null;
                        var slope2 = (this.getSlope(pts[i], pt2)!=null) ? this.getSlope(pts[i], pt2).toFixed(2) : null;
                        if(slope != slope2) ctspts += "|" + i + "|";
                   }
                   return ctspts;
              },
              remove: function(path, whitelist) {
                   var pts = path.pathPoints;
                   if(whitelist=="") {
                        for(i = pts.length - 1; i>= 0; i--) {
                             if(i != pts.length - 1 && i!= 0) {pts[i].remove(); continue;}
                        }
                        return;
                   }        
                   for(i = pts.length - 1; i>= 0; i--) {
                        if(whitelist.indexOf("|" + i + "|") < 0) {pts[i].remove(); }
                   }
              },
              isVertical: function(pt1, pt2) {
                   if(pt1.anchor[0].toFixed(1) == pt2.anchor[0].toFixed(1)) return true;
                   return false;
              },
              isHorizontal: function(pt1, pt2) {
                   if(pt1.anchor[1].toFixed(1) == pt2.anchor[1].toFixed(1)) return true;
                   return false;
              }
         }
         for(j = app.activeDocument.pathItems.length - 1; j >= 0; j--) {
              var x = Geometry2DHelper.getConstructionPoints(app.activeDocument.pathItems[j ]);
              Geometry2DHelper.remove(app.activeDocument.pageItems[j], x);  
         }
    })();
    

    And I have writed a Scriptographer script to do the same thing.

    
    document.getItems({ 
        type: Path, 
        hidden: false 
    }).each(function (path){
        var curves = path.curves, i = curves.length - 1, curve, curvePre;
        for (; i > 0; i--){
            curve = curves[i];
            curvePre = curve.previous;
            curve.isLinear() && curvePre.isLinear() &&
            (curve.point2 - curve.point1).angle.toFixed(0) == 
            (curvePre.point2 - curvePre.point1).angle.toFixed(0) &&
            path.remove(i);
        }
    });
     
    
     
    |
    Mark as:
  • Currently Being Moderated
    Sep 7, 2011 5:48 PM   in reply to moluapple

    Cool! It really helped! It can't handle compound paths, right? Shapes go to hell, but compounds.. I can uncompound them, apply subj and then hotkey stuff back (it gives almost the same result), but can it be done with a script also?

    And Scriptographer script, yes. It's still not very handy for me to use this tool (i can't change it's Enter hotkey for launching scripts and it freaks me out), but i will test it also.

    Again, many thanks for this very simple but handy script. I have only one script of my dreams left

     
    |
    Mark as:
  • Currently Being Moderated
    Sep 7, 2011 6:46 PM   in reply to achegr

    The Scriptographer script can also handle compound paths, check it.

     

    For the hotkey issue, make sure didn't select any script in the panel, then the "Enter" key come back to Illustrator.

     
    |
    Mark as:
  • Currently Being Moderated
    Jul 6, 2012 12:32 PM   in reply to Cheryl Graham

    I just used the "Simplify…" tool in Illustrator with decent results on a "pixellated" path (it's a QR code). I set it to 90º and "Straight lines"

     

    Ridiculously, I found that Fireworks' "Simplify…" tool (amount:10) worked better than Illustrator's, it left no unnecessary points at all while the latter left a few points here and there. It was a simple path, so I just copied/pasted it, simplified it, and exported it in .ai (the clipboard doesn't work the other way around)

     
    |
    Mark as:

More Like This

  • Retrieving data ...

Bookmarked By (0)

Answers + Points = Status

  • 10 points awarded for Correct Answers
  • 5 points awarded for Helpful Answers
  • 10,000+ points
  • 1,001-10,000 points
  • 501-1,000 points
  • 5-500 points