在Processing中读取/更改3D形状的像素

时间:2016-04-18 16:03:27

标签: 3d processing pixels

亲爱的收集智慧,

我正在尝试使用Processing处理以下图片来重新创建: my goal

我几乎需要创建两个半立方体,其轮廓应该更大胆,只要它们在视觉上位于"由背景中的灰色方块设置的边界。

到目前为止,我已经设法实现了大部分目标图片,但是我无法找到一种方法来读取需要变暗的各个像素。这就是我现在在视觉上的位置(立方体的旋转差异目前没有意义): what I did so far

这是我的代码:

 
PGraphics pg1;
PGraphics pg2;

void setup() {
  size(400,400,P3D);
  background(255);

  pg1 = createGraphics(200,400,P3D);
  pg2 = createGraphics(200,400,P3D);

  loadPixels();
  for (int y = 0; y < height; y++) {
    for (int x = 0; x < width; x++) {
      color grey = color(230);
      if (x > 99 && x < 300 && y > 99 && y < 300) { 
        pixels[y*width+x] = grey;
      }
    }
  }
  updatePixels();
}

void draw() {
  pg1.beginDraw(); 
    //left cube
    pg1.pushMatrix();
    pg1.ortho();
    pg1.translate(200,200,0);
    pg1.rotateX(-2.5289822);
    pg1.rotateY(-2.8117256);
    pg1.rotateZ(2.9670599);
    pg1.stroke(0,10);
    pg1.strokeWeight(0.5);
    pg1.noFill();
    pg1.box(200);
    pg1.popMatrix();

    //vertical line
    pg1.translate(200,200,0);
    pg1.stroke(230);
    pg1.strokeWeight(0.5);
    pg1.line(0,-200,0,0,200,0); 
  pg1.endDraw();

  pg2.beginDraw(); 
    //right cube
    pg2.pushMatrix();
    pg2.ortho();
    pg2.translate(0,200,0);
    pg2.rotateX(-1.24);
    pg2.rotateY(-2.0);
    pg2.rotateZ(-2.9670599);
    pg2.stroke(0,10);
    pg2.strokeWeight(0.5);
    pg2.noFill();
    pg2.box(200);
    pg2.popMatrix();

    //vertical line
    pg2.translate(0,200,0);
    pg2.stroke(230);
    pg2.strokeWeight(0.5);
    pg2.line(0,-200,0,0,200,0);
  pg2.endDraw();

  //display pgs
  image(pg1, 0, 0); 
  image(pg2, 200, 0);

  //how can I change specific pixels of the box outlines??
  loadPixels();
    for (int y = 0; y < height; y++) {
     for (int x = 0; x < width; x++) {
       if (x > 99 && x < 300 && y > 99 && y < 300) { 
         float r = red(pixels[y*width+x]);
         float g = green(pixels[y*width+x]);
         float b = blue(pixels[y*width+x]);
         pixels[y*width+x] =  color(r,g,b,255);
       }
     }
    }
    updatePixels();  
}

我一直在尝试各种版本的基于像素位置或通过改变笔画颜色的alpha值(在绘制立方体之前或之后)来改变笔画粗细,但显然我做错了。我不确定,如果这是可能的,因为我显然(?)试图从3D形状读取2D图像..

任何帮助将不胜感激! 非常感谢 - 伊利亚斯

2 个答案:

答案 0 :(得分:1)

这听起来像侵蚀过滤器的工作。

您可以使用filter()功能将滤镜应用于图片的该部分。处理带有一些预定义的过滤器,而侵蚀功能完全符合您的描述。

考虑以下代码:

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

void draw(){
  background(255);
  line(0, 0, width, height);
}

产生这个:

您可以应用侵蚀过滤器:

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

void draw(){
  background(255);
  line(0, 0, width, height);
  filter(ERODE);
}

这带来了黑线:

您可以多次应用不同的过滤器或相同的过滤器,以达到您想要的效果:

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

void draw(){
  background(255);
  line(0, 0, width, height);
  for(int i = 0; i < 10; i++){
    filter(ERODE);
  }
}

请注意,您还可以将filter()功能应用于PGraphics的实例,这是您想要做的事情。

答案 1 :(得分:1)

使用像素对于此任务来说可能很繁琐,尤其是因为您需要在某些区域绘制较粗的线条。

我建议使用另外两个PGraphics,它们渲染的内容几乎与现有的两个相同,但行程较粗。

您可以使用代码顶部更粗的轮廓,从PGraphics获得copy()blend()像素。

将重用的指令分组到函数中通常是个好主意。这是使用额外函数和两个PGraphics图层的代码的调整版本:

PGraphics pg1;
PGraphics pg2;
PGraphics pg3;
PGraphics pg4;

void setup() {
  size(400,400,P3D);
  background(255);
  noStroke();
  fill(0,32);

  pg1 = createGraphics(200,400,P3D);
  pg2 = createGraphics(200,400,P3D);
  pg3 = createGraphics(200,400,P3D);
  pg4 = createGraphics(200,400,P3D);

  box(pg1,200,200,0,//pg,x,y,z
          -2.5289822,-2.8117256,2.9670599,//rx,ry,rz
          0,1.5,200);//stroke,thickness,boxSize
  box(pg2,0  ,200,0,
         -1.24,-2.0,-2.9670599,
         127,1.5,200);
  //same as above, just using thicker strokes
  box(pg3,200,200,0,
         -2.5289822,-2.8117256,2.9670599,
          0,3.5,200);
  box(pg4,0  ,200,0,
         -1.24,-2.0,-2.9670599,
         64,3.5,200);

  //display pgs
  image(pg1, 0, 0); 
  image(pg2, 200, 0);
  //copy pixels from pgs drawn with thicker lines
  copy(pg3, 100, 100, 100, 200, 
            100, 100, 100, 200);
  copy(pg4, 0  , 100, 100, 200, 
            200, 100, 100, 200);
  //overlay transparent rectangle on top
  rect(100,100,200,200);
}

void draw() {

}
//render a box in a given PGraphics with options for position, rotation, stroke and size
void box(PGraphics pg,
         float x,float y,float z,
         float rx,float ry,float rz,
         int cubeStroke,float cubeStrokeWeight,float cubeSize){
  pg.beginDraw(); 
    //left cube
    pg.pushMatrix();
    pg.ortho();
    pg.translate(x,y,z);
    pg.rotateX(rx);
    pg.rotateY(ry);
    pg.rotateZ(rz);
    pg.stroke(cubeStroke);
    pg.strokeWeight(cubeStrokeWeight);
    pg.noFill();
    pg.box(cubeSize);
    pg.popMatrix();

    //vertical line
    pg.translate(200,200,0);
    pg.stroke(230);
    pg.strokeWeight(0.5);
    pg.line(0,-200,0,0,200,0); 
  pg.endDraw();
}

希望间距可以更容易地遵循许多论点。 这是一个概述:

Manfred Mohr Cube study Processing port test

因此...

clippy

您应该查看Golan Levin's courses上的大量资源,例如与Manfred Mohr相关的资源。另请查看ReCode Project