I’m using processing to generate SVG files for pen plotting.
I have a PShape object which is a custom geometry, I would like to use that geometry as a mask/intersection or a boolean check to then draw a some additional geometry within it as a fill.
I’m not able to use textures or PImage objects for the fill as I need to be able to export an SVG at the end of the script.
I’m aware of RShape from geometrive, which does offer a handy .intersection() function, although I’m not sure how to get that to play nicely with my PShape objects.
Are there any other methods I could investigate to solve my problem?
(I’m trying to avoid writing lengthy region checks)
For reference; the geometries that I would like to fill are these sections of a circle:
This is a bit of a hack, maybe not an answer you’re looking for …
Sometimes I render ‘whole’ shapes in the Processing sketch, then apply the ‘boolean’ operation I desire in Inkscape (you might even automate this using Inkscape’s command line mode). So, the fill is one set of shapes, and the mask another. Additionally, you can separate shapes into layers to make the Inkscape work easier.
I’d rather expedite the process of getting results onto paper when I’m plotting, even if the sketch isn’t ‘fully-automated.’
Yeah that is a bit of a hack…
I once lined some disparate parts of a plot up in Inkscape and still feel a little guilty about it.
I guess I take the opinion that the final drawing is only an abstraction of the input code if it remains as unadulterated as possible throughout the entire digital workflow.
I’m either a purist or a pedant and I’m not sure which is worse!
Excuse my messy code!
The idea is that I generate the sectioned circle as above and then fill each section with an alternating fill, leftFill & rightFill. Which are PShape objects made up of many diagonal lines with varying spacing.
I had hoped that .intersect() would allow me to make a masked PShape object to apply rightFill & leftFill to the main sectioned circle shape. Although I’m guessing that I’m getting my use cases mixed up…
Your approach was correct, but you were thrown off by the way geometry operations work. Lines are 1D objects (they have no “height”) so intersecting a line with a polygon returns nothing. The solution is to buffer the lines into actual 2D polygons so intersection() becomes a meaningful operation.
I’ve also had to replace line.rotate(a) with a PGS rotation method. The problem with .rotate() is that it affects the shape’s rotation matrix only and not the actual coordinates of its vertices. A PShape’s rotation matrix is not accessible and so the buffer() method would otherwise buffer the unrotated (vertical) lines.
So in the end only your createLineFills() method needed changing in the last few lines.
PShape createLineFills(float a, float maxspacing) {
float spacing = maxspacing;
PShape line = createShape();
line.beginShape(LINES);
for (float x=-height; x<=height; x+=spacing) {
line.vertex(x, -height);
line.vertex(x, height);
spacing = map(noise(x*0.01), 0, 1, 0, maxspacing);
}
line.endShape();
line = PGS_Transformation.rotateAroundCenter(line, a);
line = PGS_Morphology.buffer(line, 1);
return line;
}
Ah Thanks so much!
I think I’m going to spend some time exploring the quirks of PGS further.
Glad to be able to put a lid on this little project. The final output is interesting to look at, but I’m very excited to be able to quickly and easily create fills for custom geometry.
@micycle PGS is exactly the tool that will make one of my projects easier to do. There’s something in your above ‘createLineFills’ method here that’s baffling me though. It seems like all lines are somehow getting doubled? Even if I strip out the ‘for’ loops and use line.vertex to draw a single diagonal from the upper-left to the lower-right of the container, it renders (and saves as an SVG) with two diagonal lines separated by a few pixels. Is this a known quirk, and/or is there a way to have it draw just a single line?
Edit: I just read your response above about needing the lines to form a closed loop in order for the intersection operation to work.
What I said before was actually incorrect. PGS can (at least now) intersect a LINES shape with a polygon, returning the linework as expected. For instance, a hilbert curve intersected with a heart-shaped polygon: