Trim primitive shapes

Hi there,

need a little help figuring this one out…

Ive had a search but havent found any topics that I think would help mw…

Basically Im trying to mask some lines ive generated with a rectangle.

I’ve seen a few posts about using image masking but I need to be able to save as a.pdf, to edit in vector image software.

In this image, I’d like the purple rectangle to trim/crop the diagonal lines.

thanks very much :slight_smile:

float blockSize = 100;

void setup() {
 size(480,480); 
}

void draw() {
  background(255);

  strokeWeight(2);
  stroke(255,0,255);
  rect(mouseX,mouseY,blockSize,blockSize);
  
  ladder(width/2,height/2+blockSize/2);  

}

//function to create diagonal lines
void ladder(float x_,float y_) {
  stroke(0);
  strokeWeight(1);
  
  float diag = sqrt(sq(blockSize) + sq(blockSize));
  float x = x_;
  float y = y_;
  float space = blockSize/10;
  
   pushMatrix();
     translate(x + blockSize/2,y);
     rotate(radians(45));
       for(int i = 0; i < diag; i += space) {
       line(-diag/2,i-diag/2,diag/2,i-diag/2); 
       }
   popMatrix();
}
1 Like

Do you require the intersection points? Or are you just after an image of the square masking the lines?

Yea, I think so…

Im using the .pdf library to save as a .pdf and open in Inkscape.

you could just use **get()** to get a part of the screen:

You need the version with 4 parameters:

get(x, y, w, h)

It returns a PImage p1 corresponding to the part of the original PImage

You could then use background, show the p1 and save the screen (or the image using p1.save())

https://www.processing.org/reference/get_.html

2 Likes

@Chrisir Brilliant!

such a simple solution. thank you.

1 Like

Oh, no… it seems I spoke too soon.
When it comes to recording to a .PDF it saves it as an embedded image of diagonal lines, which unfortunately is not what Im after.

I tried using the .SVG library, but that gives me a NPE error. the reference does state that the library does not work with images.

back to the drawing board.

oups.

Alternatively just draw 4 rects over the area you don’t want?

That won’t work for what I’m trying to achieve. Ultimately there will be a Lot of diagonal line (haches) next to each other in a grid.

The mask rects as you suggested would end up masking the neighbours too.

If the pink rectangle is the same proportion as the grid cells and you’re only working with rotated lines, you might be able to solve it as followed: You could write a function to calculate where the rotated lines intersect with the edges of the pink rectangle, save these x and y values, and use those to draw separate lines. Something like this:

int lines_amount = 7;
float cell_size = 200;
float[] line_intersects;

void setup() {
  size(400, 400);
}

void draw() {
  background(240);
  translate(width/4, height/4);

  line_intersects = new float[lines_amount];
  float lines_distance = cell_size / lines_amount;
  for (int i = 0; i < lines_amount; i++) {
    line_intersects[i] = lines_distance * i;
    println(line_intersects[i]);
    if(i == 0) {
      line(line_intersects[i], line_intersects[i], cell_size, cell_size);
    } else {
      line(line_intersects[i], 0, cell_size, cell_size - line_intersects[i]);
      line(0, line_intersects[i], cell_size - line_intersects[i], cell_size);
    }
  }
}

void mousePressed() {
  lines_amount++;
}

The code above isn’t pretty, but you get the idea. Perhaps you could convert it into a class or a shape to speed up the sketch’s performance. Think something like this might work for your situation?

1 Like

Thanks for the help @Tiemen this looks like it might help.

But I think I need to re-think my approach for what I’m trying to achieve instead.

thanks all :slight_smile:

I think you want something like this.

This is an amended take on my ray casting example, using light intersection. In this example I’ve only generated lines for one side of the rectangle, you would need to do this for all sides.
Alternatively amend the code to allow the lines to handle multiple intersections.

3 Likes

Raycasting!
What a great solution.

Thanks @paulgoux

Ive updated it with the rest of the lines.

Please note some of the lines will look a bit thicker as they are draw twice, I’m drawing a set of lines diagonally right down, and another set of lines diagonally up left, those which intersect with the square are trimmed the others however are not, and therefore are drawn twice.

1 Like

Just adding mouse interaction for the square, need to iron out glitches.

I’m sorry, guys, am I missing something or a simple clip(mouseX,mouseY,blockSize,blockSize); would do the job?

This example only draws the lines within the clip boundaries,

can this be reversed?

void setup() {
  size(200, 200);
  imageMode(CENTER);
}

void draw() {
  background(204);
  if (mousePressed) {
    clip(mouseX, mouseY, 100, 100);
  } else {
    noClip();
  }
  line(0, 0, width, height);
  line(0, height, width, 0);
}

drawing a rect with bg color after drawing the lines would :slight_smile:

It seems like the simplest solution, which was suggested initialy and I don’t think it was ever clarified whether the intersection lines were required. If they are I’m not sure the mask would fit that purpose which is why I suggested the intersection function. But yes the simplest solution is to just draw a square over the lines based on the mouse position.

All done, let me know if you want help explaining the code, or if you notice any bugs I didn’t catch.