Loading...
Logo
Processing Forum
hey...

i am looking for a method to create the outline of a given path with a set of vertices. similar to the 'outline stroke' function you can use in illustrator.

example:
this path


should become this path:



i couldnt find any library handling this for me..

thanks for any advice!!

Replies(5)

...on my way there....
red line is the input path. with a given strokeWeight it generates the points on the outline.


i created a class in which you just have to chuck in an ArrayList<PVector> and the desired strokeWidth and it throws back an ArrayList<PVector> of the new points.

Main problem now is handling curves and bezierPoints. ANYONE ANY HINTS ON THAT?

Heres the class if anyone thinks its useful...
Copy code
  1. class PathCreator{

      ArrayList<PVector> points;
      ArrayList<PVector> newPoints;
      int strokeWeight;
      GeneralPath path;
      BasicStroke stroke;
      Shape stroked;
      Area area;
      PathIterator iter;
      PShape pShape;
       
      PathCreator(){
      }
     
      void init(ArrayList<PVector> _points, int _strokeWeight){
        newPoints = new ArrayList<PVector>();
        setPoints(_points);
        setStrokeWeight(_strokeWeight);
        createPShape();
        createGeneralPath();
        createArea();
        calcPointsFromArea();
      }
     
      void setPoints(ArrayList<PVector> _points){
        points = _points;
        println("Added Points: " + !points.isEmpty());
      }
     
      void setStrokeWeight(int weight){
        strokeWeight = weight;
        println("Set strokeWeight: " + strokeWeight);
      }
     
      void createPShape(){
        pShape = createShape();
        pShape.beginShape();
        for(int i=0; i<points.size(); i++){
          pShape.vertex(points.get(i).x, points.get(i).y);
        }
        pShape.noFill();
        pShape.endShape();
        pShape.setStrokeWeight(strokeWeight);
        pShape.setStrokeCap(2);
        pShape.setStrokeJoin(2);
        println("Created Shape");
      }
     
      void createGeneralPath(){
        path = new GeneralPath();
        for(int i=0; i<points.size(); i++){
          if(i==0){
            path.moveTo(points.get(i).x, points.get(i).y);
          }else{
            path.lineTo(points.get(i).x, points.get(i).y);
          }
        }
        println("Created Path: " + path.getCurrentPoint());
      }
     
      void createArea(){
        stroke = new BasicStroke(strokeWeight,
        BasicStroke.CAP_ROUND,
        BasicStroke.JOIN_ROUND,
        0.1f);
        stroked = stroke.createStrokedShape(path);
        area = new Area(stroked);
        iter = area.getPathIterator(null, 10.0f);
        println("Created Area: " + area.getBounds());
      }
     
      void calcPointsFromArea(){
        println("Starting to Calc points: ");
        float[] segment = new float[6];
        while(!iter.isDone()){
          int type = iter.currentSegment(segment);
          print("Type: " + type + ": ");
          print(Math.round(segment[0]) + " , " + Math.round(segment[1]) + ": ");     
          newPoints.add(new PVector(Math.round(segment[0]), Math.round(segment[1])));
          println("Added new point: " + newPoints.get(newPoints.size()-1));
          iter.next();
        }
        println("Finished adding points. Point count: " + newPoints.size());
      }
     
      ArrayList<PVector> getNewPoints(){
        return newPoints;
      }
     
      void displayPoints(){
        pushStyle();
        stroke(#00dcad);
        noFill();
        for(int i=0; i<newPoints.size(); i++){
          ellipse(newPoints.get(i).x, newPoints.get(i).y, 5, 5);
        }
        popStyle();
      }
     
      void displayLines(){
        pushStyle();
        stroke(#dcad00);
        noFill();
        beginShape();
        for(int i=0; i<newPoints.size(); i++){
          vertex(newPoints.get(i).x, newPoints.get(i).y);
        }
        endShape();
        popStyle();
      }
     
      void displayShape(){
        pushStyle();
        stroke(255,0,0);
        noFill();
        shape(pShape,0,0);
        popStyle();
      }
     
      void displayRawLine(){
        pushStyle();
        stroke(#ff0000);
        noFill();
        beginShape();
        for(int i=0; i<points.size(); i++){
          vertex(points.get(i).x, points.get(i).y);
        }
        endShape();
        popStyle();
      }
     
    }
An idea could be to take the points of the path, and to compute the vectors perpendicular to the curve at these points. With a constant distance in both directions, it should give you a collection of points away from the curve.
There is a Line2TriangleMesh example in my github repo that might be of interest to you:

https://github.com/AmnonOwed/P5_MathAndVectors
thanks for your hints and suggestions. i developed a good solution using the geomerative lib added to my previous approach.

greetings from berlin! happy coding