2

我正在尝试做一个理论上简单的效果。例如,我有两个在窗口周围弹跳的白色圆圈。当它们相交时,我希望相交的圆圈部分为黑色,而其余圆圈保持白色,如下所示:

两个相交的圆盘,相交处为黑色,其他均为白色

有没有办法做到这一点?

到目前为止,我有这个:

for(int i = 0; i < balls.length; i++)
{
    balls[i].move();
    for(int j = 0; j < balls.length; j++)
    {
        if(i != j && balls[i].intersect(balls[j]) && !changed[i] && !changed[j])
        {
            balls[j].swapColor();
            changed[j] = true;
        }
        else
            changed[j] = false;
    }
    balls[i].display();
}

但是当它们相交时它会将圆圈完全变为黑色,而我只希望交叉点本身发生变化。


编辑:我尝试将 blend() 与两个 200x200 png、洋红色红色一起使用,以更好地查看混合工作。但是, blend() 参数似乎无助于正确定位圆圈。

void setup() {
  size(300, 300);
  background(255);
}

void draw() {  
  PImage img = loadImage("circle.png");
  PImage img2 = loadImage("circle2.png");

  img.blend(img2,0,0,200,200,10,10,200,200,DIFFERENCE);
  image(img,0,0);
  image(img2,50,50);
}

给了我这个:

两个圆圈在处理中重叠

4

5 回答 5

3

在这里试一试。这是使用两个 PGraphics 而不是 PImages 的混合方法。一个简单的例子。编辑:当它们重叠时,基本椭圆的上角有一个奇怪的工件,现在不知道为什么......我正在寻找,如果我找到我会在这里发布。EDIT2:它似乎与抗锯齿有关,如果你跳过 smooth() 工件就消失了......

PGraphics c;
PGraphics d;
void setup() {
  size(300, 300);
  background(255);
  c = createGraphics(width, height, JAVA2D);
  d = createGraphics(width, height, JAVA2D);
  c.beginDraw();
  c.smooth();
  c.endDraw();
  d.beginDraw();
  d.smooth();
  d.endDraw();
}

void draw() {  
  background(255);
  c.beginDraw();
  c.background(0, 0);
  c.fill(255);
  c.stroke(0);
  c.ellipse(mouseX, mouseY, 30, 30);
  c.endDraw();

  d.beginDraw();
  d.background(0, 0);
  d.fill(255);
  d.stroke(0);
  d.ellipse(width/2, height/2, 30, 30);
  d.endDraw();
  d.blend(c, 0, 0, width, height, 0, 0, width, height, DIFFERENCE);
  image(d, 0, 0);
}
于 2012-11-28T22:33:54.963 回答
2

不幸的是,我现在无法提供可运行的示例,但是对于视觉效果,您可以使用blend()函数(可能在DIFFERENCE模式上)。

您可以使用createGraphics btw将椭圆绘制到 PImage 中。

于 2012-11-28T16:33:33.853 回答
1

I thought of an amusing way to do this. Create a new sketch with the following code and move your mouse around within the canvas.

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

void draw() {
  background(0);

  int c1x = width/2;
  int c1y = height/2;
  int c2x = mouseX;
  int c2y = mouseY;

  int d = 100;

  boolean intersect = false;
  if(dist(c1x, c1y, c2x, c2y) < d) intersect = true;

  fill(255);
  stroke(0);
  ellipse(c1x, c1y, d, d);
  ellipse(c2x, c2y, d, d);
  noFill();
  ellipse(c1x, c1y, d, d);

  stroke(0, 0, 255);
  line(c1x, c1y, c2x, c2y);

  stroke(255, 0, 0);
  if(intersect) stroke(0, 255, 0);
  rectMode(CORNERS);
  int mx = (c1x+c2x)/2;
  int my = (c1y+c2y)/2;
  int r = d/2;
  rect(mx-r, my-r, mx+r, my+r); 

  if(intersect) {
    for(int j = my-r; j <= my+r; j++) {
      for(int i = mx-r; i <= mx+r; i++) {
        if(dist(i, j, c1x, c1y) <= r && dist(i, j, c2x, c2y) <= r) {
          stroke(0);
          point(i, j);
        } 
      }
    }   
  }
}

This is a dirty mock-up showing the concept. I know the center points of the two circles. I imagine a square with a width and height equal to the diameter of the circles, and I center that square at the midpoint between the two circles. When the circles collide, I check each pixel within that square, and if the pixel is within both circles, I draw a point there.

I simplified by having the circles with identical diameter, but it's trivial to modify it for variable diameters.

Screenshot of circle intersection fill

Obviously you don't have to draw the green square and blue line, those are there just for reference.

于 2012-11-29T21:07:27.397 回答
0

这将是带有白色交叉点和背景的深色椭圆,并且快速且肮脏但有效。

白色背景:

background(255);

调用这样的东西:

  blendMode(SUBTRACT);
  fill(0);
  ball1.display();
  fill(255);
  ball2.display();

如果您想了解其背后的数学原理,请查看此链接。我认为您也可以使用像toxiclibs.geom 这样的库来做到这一点。

于 2012-12-01T09:30:46.647 回答
0

如果它们的中心之间的距离小于它们的半径之和,它们就会相交

于 2012-11-28T16:20:10.673 回答