Компьютерная графика в Processing, часть 7. 3D в Processing

19
Компьютерная графика 3D в processing Jordi Linares i Pellicer Escola Politècnica Superior d’Alcoi Dep. de Sistemes Informàtics i Computació [email protected] http://www.dsic.upv.es/~jlinares

description

Перевод практикума по компьютерной графике с использованием Processing.

Transcript of Компьютерная графика в Processing, часть 7. 3D в Processing

Компьютерная графика3D в processing

Jordi Linares i PellicerEscola Politècnica Superior d’AlcoiDep. de Sistemes Informàtics i Computació[email protected]://www.dsic.upv.es/~jlinares

• В processing есть 2 режима отображения 3D: P3D и OPENGL• P3D основано на программной реализации, OPENGL

выполняется через OpenGL («железо»). За несколькими исключениями, в них одни и те же функции и примитивы

• 2D примитивы и функции можно использовать в 3D(возможно, с несколькими исключениями)

• Некоторые из примитивов, такие как линии (line), точки (point), кривые и фигуры (примитив vertex), могут задаваться через 3 координаты: x, y, z

• Остальные 2D примитивы тоже можно использовать (сz=0 по умолчанию)

• Функции stroke, fill, text и image (текстуры) тоже можноиспользовать в 3D

3D в processing

Геометрические преобразования в 3D

3D в processing

Вращение вокруг x

Вращение вокруг y

Вращение вокруг z

Перенос

Масштаб

Геометрические преобразования в 3D

Переносtranslate(tx, ty, tz)

Масштабированиеscale(sx, sy, sz)

Вращение вокруг осиrotateX(), rotateY(), rotateZ()

3D в processing

• По умолчанию используется перспективная проекция• (0,0,0) находится в верхнем левом углу• -z уходит вдаль

yx+z

-z

(0,0,0)

3D в processing

// Эллипс, вращающийся// вокруг оси yfloat ang = 0.0;

void setup(){ size(400, 400, P3D); stroke(255, 0, 0); noFill();}

void draw(){ background(0); // Рисование с центром в // (0,0,0) translate(width/2, height/2); rotateY(ang += 0.1); ellipse(0, 0, 300, 200);}

3D в processing

box(width, height, depth)

• Рисует кубоид, правильную призму, с центром в (0,0,0) с шириной (x), высотой (y) и глубиной (z) в качествеаргументов

sphere(radius)

• Рисует сферу с центром в (0,0,0) с заданным радиусом

• Уровень детализации, с которой рисуется сфера, можнонастроить через функцию sphereDetail(n), где nозначает, что вершины будут порождаться через каждые 360º/n (по умолчанию, n = 30)

3D в processing

// Куб, вращающийся// вокруг трёх осей

// Версия с каркасом

void setup(){ size(400, 400, P3D); stroke(255, 0, 0); noFill();}

void draw(){ background(0); // Рисование с центром // в (0,0,0) translate(width/2, height/2); rotateX(frameCount*PI/60.0); rotateY(frameCount*PI/120.0); rotateZ(frameCount*PI/180.0); box(200, 200, 200);}

3D в processing

// Куб, вращающийся// вокруг трёх осей

// Версия с гранями

void setup(){ size(400, 400, P3D); fill(255, 0, 0);}

void draw(){ background(0); // Рисование с центром // в (0,0,0) translate(width/2, height/2); rotateX(frameCount*PI/60.0); rotateY(frameCount*PI/120.0); rotateZ(frameCount*PI/180.0); box(200, 200, 200);}

3D в processing

// Куб, вращающийся// вокруг трёх осей

// Версия с простым освещением

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

void draw(){ background(0); // Простое освещение lights();

// Рисование с центром // в (0,0,0) translate(width/2, height/2); rotateX(frameCount*PI/60.0); rotateY(frameCount*PI/120.0); rotateZ(frameCount*PI/180.0); box(200, 200, 200);}

3D в processing

// Интерактивный кубfloat rotX = 0.0, rotY = 0.0;int lastX, lastY;float distX = 0.0, distY = 0.0;

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

void draw(){ background(0); lights(); translate(width/2, height/2); rotateX(rotX + distY); rotateY(rotY + distX);

box(200, 200, 200);}

void mousePressed(){ lastX = mouseX; lastY = mouseY;}void mouseDragged(){ distX = radians(mouseX - lastX); distY = radians(lastY - mouseY);}

void mouseReleased(){ rotX += distY; rotY += distX; distX = distY = 0.0;}

3D в processing

Практика 7-1

• Измените предыдущую программу так, чтобы было возможно увеличение, путём перемещения куба по оси z

• Для этого необходимо добавить компонент z в операциюпереноса

• Изначально эта координата будет 0 и будет изменяться от 0 до -500 по шагам в 10

• Используйте клавиши UP и DOWN, чтобы поймать событие keyPressed() и изменить увеличение

// Теперь сделаем через OpenGL// Этот import - обязателенimport processing.opengl.*;

float rotX = 0.0, rotY = 0.0;int lastX, lastY;float distX = 0.0, distY = 0.0;

// ТекстураPImage foto;

void setup(){ size(400, 400, OPENGL); noStroke(); foto = loadImage("foto.jpg"); // Мы хотим работать с текстурой в // координатах от (0,0) до (1,1) textureMode(NORMALIZED);} void draw(){ background(0); translate(width/2, height/2); rotateX(rotX + distY); rotateY(rotY + distX); // Хотим куб 200 x 200 x 200 // Рисуем от -1 до 1 scale(100, 100, 100);

beginShape(QUADS); texture(foto);

// Мы задаём вершины каждого // лица на кубе. // Последние два значения - // координаты текстуры, // которая соответствует // вершине // +Z "передняя" грань vertex(-1, -1, 1, 0, 0); vertex( 1, -1, 1, 1, 0); vertex( 1, 1, 1, 1, 1); vertex(-1, 1, 1, 0, 1);

// -Z "задняя" грань vertex( 1, -1, -1, 0, 0); vertex(-1, -1, -1, 1, 0); vertex(-1, 1, -1, 1, 1); vertex( 1, 1, -1, 0, 1);

// +Y "нижняя" грань vertex(-1, 1, 1, 0, 0); vertex( 1, 1, 1, 1, 0); vertex( 1, 1, -1, 1, 1); vertex(-1, 1, -1, 0, 1);

// -Y "верхняя" грань vertex(-1, -1, -1, 0, 0); vertex( 1, -1, -1, 1, 0); vertex( 1, -1, 1, 1, 1); vertex(-1, -1, 1, 0, 1);

// +X "правая" грань vertex( 1, -1, 1, 0, 0); vertex( 1, -1, -1, 1, 0); vertex( 1, 1, -1, 1, 1); vertex( 1, 1, 1, 0, 1);

// -X "левая" грань vertex(-1, -1, -1, 0, 0); vertex(-1, -1, 1, 1, 0); vertex(-1, 1, 1, 1, 1); vertex(-1, 1, -1, 0, 1);

endShape();

}

void mousePressed(){ lastX = mouseX; lastY = mouseY;}void mouseDragged(){ distX = radians(mouseX - lastX); distY = radians(lastY - mouseY);}

void mouseReleased(){ rotX += distY; rotY += distX; distX = distY = 0.0;}

3D в processing

3D в processing

import processing.opengl.*;

// Рисование функции в 3Dfloat rotX = 0.0, rotY = 0.0;int lastX, lastY;float distX = 0.0, distY = 0.0;

// Шаги функцииint steps = 50;

// Масштабирование по оси zfloat scaleZ = 200.0;

// Увеличение по оси zfloat zoomZ = -300.0;

// Размер графикаfloat gX = 500.0, gY = 500.0;

void setup(){ size(500, 500, OPENGL); noFill();} float function(float x, float y){ return x*x*x + y*y*y;}

void draw(){ background(0); // Поместим результат в центр окна translate(gX/2, gY/2, zoomZ); // Вращение rotateY(rotY + distX); rotateX(rotX + distY);

// Перенос центра в (0, 0); translate(-gX/2, -gY/2); // Функция покрывает // 400 x 400 x scaleZ scale(gX, gY, scaleZ); // Рисование функции stroke(255); drawFunction(); // Рисование осей stroke(255, 0, 0); line(0,0,0,2000,0,0); stroke(0,255,0); line(0,0,0,0,2000,0); stroke(0,0,255); line(0,0,0,0,0,2000);}

void drawFunction(){ float x, y, z; int i = 0, j = 0; float in_steps = 1.0 / steps; float[][] matrix = new float[steps+1][steps+1]; for (y = 0.0, j = 0; y <= 1.0; y+=in_steps, j++) for (x = 0.0, i = 0; x <= 1.0; x+=in_steps, i++) matrix[i][j] = function(x, y); for (j = 0, y = 0.0; j < steps; j++, y+=in_steps) { beginShape(QUAD_STRIP); for (i = 0, x = 0.0; i <= steps; i++, x+=in_steps) { vertex(x, y, matrix[i][j]); vertex(x, y + in_steps, matrix[i][j+1]); } endShape(); }}void mousePressed(){ lastX = mouseX; lastY = mouseY;}void mouseDragged(){ distX = radians(mouseX - lastX); distY = radians(lastY - mouseY);}

void mouseReleased(){ rotX += distY; rotY += distX; distX = distY = 0.0;}

3D в processing

3D в processing

• Измените предыдущую программу, чтобы нарисоватьповерхность в «твёрдом» режиме с использованиемпростой модели освещения (используйте lights() и fill())

Практика 7-2

• Измените предыдущую программу, чтобы нарисоватьповерхность с двухцветным градиентом (например, красный для малых значений z, а жёлтый для больших)

• Для этого используйте вызов fill() перед каждым вызовом vertex()

Практика 7-3

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

Практика 7-4