Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Intermittent "Invalid number of points in LinearRing" when using PGS_ShapeBoolean.subtract() #22

Closed
mrwoodo opened this issue May 21, 2021 · 3 comments

Comments

@mrwoodo
Copy link

mrwoodo commented May 21, 2021

Hi @micycle1, I'm using PGS to do hidden line removal for my old Roland plotter. The idea is that because the plotter has no concept of .fill(), I'm progressively subtracting / merging shapes from each other.

It seems to work for the most part, but I intermittently get an illegal arg exception - Invalid number of points in LinearRing (found 2 - must be 0 or >= 4) when calling PGS_ShapeBoolean.subtract()

I've tried to mock this up in the below code - it will stop at the offending PShape and draw in pink. All the 'valid' PShapes above that one will be drawn in black.

Hoping for some pointers please, maybe I'm misusing the subtract / shape group ? Apologies in advance, I'm new to both Java & Processing!

subtract

import micycle.pgs.*;

void setup() 
{
  size(3000, 1800);
}

void draw()
{  
  noLoop();
  ArrayList<RandomPoly> polys = new ArrayList<RandomPoly>();
  int max = 20;

  //create objects, randomly placed over each other
  for (int i = 0; i < max; i++)
  {
    boolean intersectsPrevious = false;
    while (!intersectsPrevious)
    {
      RandomPoly p = new RandomPoly();

      if (i == 0)
        intersectsPrevious = true;
      else 
      intersectsPrevious = PGS_ShapePredicates.intersect(polys.get(i - 1).shape, p.shape);

      if (intersectsPrevious)
      {
        polys.add(p);
      }
    }
  }

  //now plot them in reverse order
  PShape group = polys.get(polys.size() - 1).shape;
  for (int i = polys.size() - 2; i >= 0; i--)
  {
    RandomPoly background = polys.get(i);
    PShape merged = mergeShapes(background.shape, group);

    if (merged == null)
    {
      shape(background.shape); //draw invalid shape in pink and stop
      break;
    } else
    {
      group = merged;
    }
  }

  PGS_Conversion.setAllStrokeColor(group, color(0), 1);
  shape(group);
}

//Here we are taking a background and foreground shape, and making a group of out of 
// 1 - the foreground shape, and 
// 2 - the subtraction of foreground from background
//This allows us to send to a plotter that has no concept of fill() 
PShape mergeShapes(PShape backgroundShape, PShape foregroundShape)
{
  PShape g = createShape(GROUP);

  g.addChild(foregroundShape);
  try
  {
    g.addChild(PGS_ShapeBoolean.subtract(backgroundShape, foregroundShape));
  }
  catch(Exception e) //java.lang.IllegalArgumentException: Invalid number of points in LinearRing (found 2 - must be 0 or >= 4)
  {
    print(e);
    return null;
  }

  return g;
}

class RandomPoly
{
  PShape shape;
  PVector pos;

  RandomPoly()
  {
    float xStart = randomGaussian() * 200 + width / 2;
    float yStart = randomGaussian() * 200 + height / 2;

    pos = new PVector(xStart, yStart);
    shape = PGS_Transformation.translate(
      PGS_Construction.createRandomPolygon(4, width / 4, height / 4), 
      pos.x, 
      pos.y);
  }
}

@micycle1
Copy link
Owner

The library assumed that PShapes with isClosed() as true would have to be polygonal, but seems that some lines (shapes with 2 vertices) are slipping through as 'closed', causing an error trying to create a polygon from them. I've made a code change to fix this.


With the way you've coded the approach you're generating lots of group PShapes with nested components. These can all be seen when we translate them randomly.

image

Another approach could be: for each layer, subtract from it the union of all its upper layers (however I haven't tested this).

@mrwoodo
Copy link
Author

mrwoodo commented May 26, 2021

Thank you @micycle1 can't wait to try it out!
I tried to use the updated .jar from jitpack - It is a lot smaller (140kb) compared to the original I grabbed from /releases. I'm guessing it doesn't have all the dependencies bundled in, sorry it's all a dark art to me at the moment.

@micycle1
Copy link
Owner

Yeah, that's correct. The Jitpack version doesn't include dependencies. As it's a maven artifact, it's designed to be used with Maven which will download all dependencies automatically.

I'll release a new version at some point -- now I'm working on some other features to be included in it.

@micycle1 micycle1 changed the title Intermittent "Invalid number of points in LinearRing" when using PGS_ShapeBoolean.subtract Intermittent _"Invalid number of points in LinearRing"_ when using PGS_ShapeBoolean.subtract() Jan 4, 2022
@micycle1 micycle1 changed the title Intermittent _"Invalid number of points in LinearRing"_ when using PGS_ShapeBoolean.subtract() Intermittent "Invalid number of points in LinearRing" when using PGS_ShapeBoolean.subtract() Jan 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants