Почему мое приложение обработки не работает?
-
19-09-2019 - |
Вопрос
Я учусь использовать Обработка, и изменили один из примеров, чтобы создать этот апплет.У меня есть два вопроса:
- Почему сферы сплюснуты?Сферы в примере, который я взял, были красивыми и круглыми.
- Почему свет появляется на внешних краях сфер, когда между ними находится точечный источник?
Вот исходный код этой маленькой программы:
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();
}
}
Решение
Функция сглаживания в этом случае не работает, потому что у вас есть примыкающие многоугольники.Без изображения это немного сложно понять, но представьте себе пиксель, который находится на границе между двумя многоугольниками.Для примера предположим, что фон — (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).Но вы не сможете этого понять, если будете рисовать каждый полигон отдельно и не сохранять между ними никакой информации о покрытии.
Современные видеокарты поддерживают то, что называется мультисэмпловое сглаживание.Это сохраняет некоторую информацию о том, какую часть пикселя покрыл первый многоугольник.Обработка пытается смоделировать это без аппаратной поддержки, поэтому она использует трюк, который работает очень хорошо, когда у вас нет примыкающих примитивов, но разваливается, когда они есть.
Что касается сжатости.По умолчанию «Обработка» заполняет все окно, и ваш размер не квадратный.Самый простой способ справиться с этим — использовать функцию орто, чтобы сделать соотношение сторон вашей камеры квадратным.Попробуйте добавить это в свою настройку:
орто(-360,360,-180,180,-10,10);
Другие советы
Что касается красивых круглых краев, попробуйте вызвать метод Smooth() в вашей настройке():
void setup() {
// ...
smooth();
// ...
}