Почему мое приложение обработки не работает? - PullRequest
2 голосов
/ 06 октября 2009

Я учусь использовать Обработка , и изменил один из примеров, чтобы создать этот апплет . У меня два вопроса:

  1. Почему сферы сжаты? Сферы в примере, из которого я написал, были хорошими и круглыми.
  2. Почему я получаю свет, показывающий внешние края сфер, когда точечный источник находится между ними?

Вот источник этой маленькой программы:

int radius = 40;
int spheredist = 320;
int maxlevel = 7;
float ecc = 0.28;
int x1, x2, y1, y2;

void setup() {
  size(640, 360, P3D);
  fill(204);
  //smooth();  // makes spheres ugly
  translate(width/2, height/2, 0);
  x1 = -spheredist/2+radius;
  x2 = spheredist/2-radius;
  y1 =
  y2 = 0;
}

void drawLightning(int x1_,int y1_,int x2_,int y2_,int lvl){
   if (lvl < maxlevel){
     int midx = (x1_ + x2_)/2;
     int midy = (y1_ + y2_)/2;
     float d = dist(x1_, y1_, x2_, y2_);
     d *= ecc;
     midx += random(-d, d);
     midy += random(-d, d);
     drawLightning(x1_, y1_, midx, midy, lvl+1);
     drawLightning(midx, midy, x2_, y2_, lvl+1);
   } else {
     strokeWeight(10);
     stroke(60,100,255,100);
     line(x1_,y1_,x2_,y2_);
     strokeWeight(1);
     stroke(255);
     line(x1_,y1_,x2_,y2_);
   }
}

void draw() {
  background(0); 
  noStroke(); 
  int brt = 200;
  pointLight(brt/2, brt/2, brt/2, spheredist/2, -spheredist, spheredist); 
  ambientLight(brt/8,brt/8,brt/8);


  if ((mouseX > width/4 && mouseX < width*3/4) &&
      (mouseY > height/2-radius && mouseY < height/2+radius)) {
    pushMatrix();
    translate(width/2, height/2, 0);
    pointLight(100, 100, 255, 0, 0, 0); 
    popMatrix();
  }

  pushMatrix();
  translate(width/2 - spheredist/2, height/2, 0); 
  sphere(radius); 
  translate(spheredist, 0, 0); 
  sphere(radius); 
  popMatrix();

  if ((mouseX > width/4 && mouseX < width*3/4) &&
      (mouseY > height/2-radius && mouseY < height/2+radius)) {
    pushMatrix();
    translate(width/2, height/2, 0);  
    drawLightning(x1,y1,x2,y2,0);
    popMatrix();
  }
}

Ответы [ 2 ]

3 голосов
/ 05 декабря 2009

Функция сглаживания в этом случае не работает, потому что у вас есть прилегающие многоугольники. Немного сложно проследить без картинки, но подумайте о пикселе, который находится на границе между двумя полигонами. Для примера предположим, что фон имеет (0,0,0), а полигоны (255,255,255). Первый многоугольник рисует и попадает в этот пиксель. Он покрывает половину этого значения, поэтому он вычисляет 0,5 * (0,0,0) + 0,5 * (255,255,255) и сохраняет (126,126,126) в качестве нового значения для этого пикселя. Второй многоугольник рисует. Он также покрывает половину пикселя, поэтому он вычисляет 0,5 * (126 126 126) + 0,5 * (255 255 255) и сохраняет (190 190 190). Это не правильно, потому что каждый из двух полигонов должен был покрывать свою половину и иметь цвет (255,255,255). Но вы не сможете понять это, если будете рисовать каждый полигон отдельно и не сохраняете информацию о покрытии между ними.

Современные видеокарты поддерживают так называемое мультисэмплированное сглаживание . Это сохраняет некоторую информацию о том, какая часть пикселя покрыта первым многоугольником. Обработка пытается симулировать это без аппаратной поддержки, поэтому она использует прием, который работает довольно хорошо, когда у вас нет примыкающих примитивов, но разваливается, когда вы делаете.

Что касается сжатости. По умолчанию обработка заполняет все окно, и ваш размер не квадратный. Самый простой способ справиться с этим - использовать функцию орто, чтобы сделать соотношение сторон вашей камеры квадратным. Попробуйте добавить это к вашей настройке:

орто (-360360, -180180, -10,10);

0 голосов
/ 06 октября 2009

О хороших круглых краях, попробуйте вызвать метод smooth () в вашей настройке ():

void setup() {
  // ...
  smooth();
  // ...
}
...