View
499
Download
8
Category
Preview:
DESCRIPTION
Перевод практикума по компьютерной графике с использованием Processing.
Citation preview
Компьютерная графика3D в processing
Jordi Linares i PellicerEscola Politècnica Superior d’AlcoiDep. de Sistemes Informàtics i Computaciójlinares@dsic.upv.eshttp://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
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
• Измените предыдущую программу, чтобы нарисоватьповерхность в «твёрдом» режиме с использованиемпростой модели освещения (используйте lights() и fill())
Практика 7-2
• Измените предыдущую программу, чтобы нарисоватьповерхность с двухцветным градиентом (например, красный для малых значений z, а жёлтый для больших)
• Для этого используйте вызов fill() перед каждым вызовом vertex()
Практика 7-3
Recommended