How to merge shapes that overlaps another?

Hi, as title described, here is my code:

PShape grp, head, head2;

void setup() {
  size(200, 200);
  grp = createShape(GROUP);

  noStroke();

  head = createShape(ELLIPSE, 70, 70, 100, 100);
  head.setFill(color(255, 255, 255, 150));

  head2 = createShape(ELLIPSE, 120, 120, 100, 100);
  head2.setFill(color(255, 255, 255, 150));

  grp.addChild(head2);
  grp.addChild(head);
}

void draw() {
  background(150);
  shape(grp);
}

The result is:

However, what I want is like this:

Researched a bit but had no luck, is there any way to do this? Either Processing or p5.js solution is welcome, I'll be grateful. Thanks.

Answers

  • edited April 2017

    head.setFill(color(255, 255, 255, 150));

    You are making your child shapes solid white, but partially transparent (150 is the alpha channel). Two partially transparent shapes that overlap will be brighter at the intersection -- that is how transparency works. If you don't want this, just make them both the same solid color. This will achieve what you want:

    head.setFill(color(200, 200, 200)); ... head2.setFill(color(200, 200, 200));

  • Thank you Jeremy.

    Actually, they are intended to be transparent. what I want to achieve is to merge them into a single shape without that overlapping part.

    This is a simulation using Adobe Illustrator:

    That's why I use a group instead of just putting 2 circle together.

  • edited April 2017 Answer ✓

    I see. Some untested ideas:

    1. Try using blendMode() while rendering out the two child shapes to a PGraphics buffer such that they become one transparent region. https://processing.org/reference/blendMode_.html
    2. Try constructing the intersection of two circles using curveVertex() https://processing.org/reference/curveVertex_.html or other shape vertex primitives.
    3. Try using beginContour() / endContour()https://processing.org/reference/PShape_beginContour_.html as per the PShape Tutorial https://processing.org/tutorials/pshape/ ... if this doesn't work in an additive way, use it to cut two circles out of a rectangle and reverse that / use that as a mask().
  • Answer ✓

    This works, using PGraphics. However I am not sure if it is going to work on a PShape. When the group PShape is loaded, it will draw the children. How it will know how to manage the transparency of overlapping objects, add vs. replace? t will be good to know if it is possible.

    Kf

    PShape  head, head2;
    PGraphics a;
    
    void setup() {
      size(200, 200);
    
      noStroke();
      head = createShape(ELLIPSE, 70, 70, 100, 100);
      head.setFill(color(255, 255, 255, 150));
    
      head2 = createShape(ELLIPSE, 120, 120, 100, 100);
      head2.setFill(color(255, 255, 255, 150));
    
    
      a=createGraphics(200, 200);
      a.beginDraw();
      a.blendMode(REPLACE);
      a.shape(head);
      a.shape(head2);
      a.endDraw();
    }
    
    void draw() {
      background(150);
      image(a, 0, 0);
    } 
    
  • Thank you so much Jeremy and Kf, the solution 1 and code works well. For solution 2, I have no idea how to draw a perfect circle with curveVertex().. Solution 3, seems only vertex() can work within a beginContour & endContour pair, but not createShape(). So I will use the solution 1, though not sure will it cause performance impact. Anyway, thank you guys again.

Sign In or Register to comment.