相交圆重叠

时间:2012-11-28 16:16:58

标签: java processing

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

two intersecting disks, with intersection being black and everything else being white

有办法做到这一点吗?

到目前为止,我有这个:

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,magentared来更好地查看混合工作。但是,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);
}

给了我这个:

two circles overlapping in Processing

5 个答案:

答案 0 :(得分:3)

这里试一试。这是使用两个PGraphics而不是PImages的混合方法。一个简单的例子。 编辑:基本椭圆的上角有一个奇怪的神器,当它们重叠时,现在不知道为什么......我正在寻找,如果我发现我会在这里发布它。 EDIT2:它似乎与antialias有关,如果你跳过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);
}

答案 1 :(得分:2)

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

您可以使用createGraphics btw。

将椭圆绘制到PImage中

答案 2 :(得分:1)

我想到了一个有趣的方法来做到这一点。使用以下代码创建一个新草图,并在画布中移动鼠标。

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);
        } 
      }
    }   
  }
}

这是一个显示概念的脏模型。我知道两个圆圈的中心点。我想象一个宽度和高度等于圆的直径的正方形,并且我将该正方形置于两个圆之间的中点处。当圆碰撞时,我检查该正方形内的每个像素,如果像素在两个圆内,我在那里画一个点。

我简化了直径相同的圆圈,但是对于可变直径来说,修改它是微不足道的。

Screenshot of circle intersection fill

显然你不必绘制绿色正方形和蓝色线条,这些仅供参考。

答案 3 :(得分:0)

如果它们的中心之间的距离小于它们的半径之和

,它们会相交

答案 4 :(得分:0)

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

白色背景:

background(255);

打电话给这样的话:

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

如果你想看看背后的数学,请查看this link。我想你也可以用像toxiclibs.geom这样的库来做到这一点。