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

В 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

Перенос

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

Вращение вокруг y
Масштаб
Вращение вокруг z
3D в processing
Геометрические преобразования в 3D
Перенос
translate(tx, ty, tz)
Масштабирование
scale(sx, sy, sz)
Вращение вокруг оси
rotateX(), rotateY(), rotateZ()
3D в processing
•
•
•

По умолчанию используется перспективная проекция
(0,0,0) находится в верхнем левом углу
-z уходит вдаль
-z
(0,0,0)
yx+z
3D в processing
// Эллипс, вращающийся
// вокруг оси y
float 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;
}
Практика 7-1
•
•
•
•

Измените предыдущую программу так, чтобы было
возможно увеличение, путём перемещения куба по оси z
Для этого необходимо добавить компонент z в операцию
переноса
Изначально эта координата будет 0 и будет изменяться от
0 до -500 по шагам в 10
Используйте клавиши UP и DOWN, чтобы поймать событие
keyPressed() и изменить увеличение
3D в processing
// Теперь сделаем через 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.*;
// Рисование функции в 3D
float rotX = 0.0, rotY = 0.0;
int lastX, lastY;
float distX = 0.0, distY = 0.0;
// Шаги функции
int steps = 50;
// Масштабирование по оси z
float scaleZ = 200.0;
// Увеличение по оси z
float 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
Практика 7-2
•

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

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

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

More Related Content

PDF
JQuery UI
PPTX
Creating Objects in Python
PDF
Présentation de Django @ Orange Labs (FR)
PDF
Atelier Python 2eme partie par Achraf Kacimi El Hassani
PDF
Tutoriel GIT
PPTX
Formation python
PPTX
Android Application Component: BroadcastReceiver Tutorial
PDF
Android Architecture
JQuery UI
Creating Objects in Python
Présentation de Django @ Orange Labs (FR)
Atelier Python 2eme partie par Achraf Kacimi El Hassani
Tutoriel GIT
Formation python
Android Application Component: BroadcastReceiver Tutorial
Android Architecture

What's hot (20)

PDF
Android - Tp3 - intents
PDF
Java - programmation concurrente
PPTX
Android UI
PDF
Android-Tp4: stockage
PPTX
Add an interactive command line to your C++ application
PDF
Course 102: Lecture 25: Devices and Device Drivers
PPSX
User Administration in Linux
PDF
Développement mobile multi-plateforme avec Flutter
PDF
Tp python dauphine
PDF
Redo log
PDF
Android Threading
PPTX
complete case study on the chrome os ppt
PPTX
Introduction to Android and Android Studio
PDF
Présentation Flutter
PDF
Course 102: Lecture 9: Input Output Internals
PPTX
Introduction JavaEE
PPTX
Adama Coulibaly.pptx
PDF
Chapitre 5 classes abstraites et interfaces
PPTX
Role of java in android app development
PPTX
Linux User Management
Android - Tp3 - intents
Java - programmation concurrente
Android UI
Android-Tp4: stockage
Add an interactive command line to your C++ application
Course 102: Lecture 25: Devices and Device Drivers
User Administration in Linux
Développement mobile multi-plateforme avec Flutter
Tp python dauphine
Redo log
Android Threading
complete case study on the chrome os ppt
Introduction to Android and Android Studio
Présentation Flutter
Course 102: Lecture 9: Input Output Internals
Introduction JavaEE
Adama Coulibaly.pptx
Chapitre 5 classes abstraites et interfaces
Role of java in android app development
Linux User Management
Ad

Viewers also liked (20)

PDF
Компьютерная графика в Processing, часть 3. Изображения и текст
PDF
Компьютерная графика. Введение в Processing
PDF
Компьютерная графика в Processing, часть 2. Основные 2D-примитивы
PDF
Компьютерная графика в Processing, часть 4. Преобразования на плоскости
PDF
Arduino и бионика (Bionic Arduino). Часть 4. ШИМ, сервомашинки, I2C, акселеро...
PDF
Компьютерная графика в Processing, часть 5. Анимация
PDF
Компьютерная графика в Processing, часть 6. Взаимодействие.
DOC
Project planning forms_0210revised
PPTX
Կայքի հաջողության մի քանի քայլեր
PDF
Efficient Query Answering against Dynamic RDF Databases
PPS
一公分鉛筆的故事
PDF
Unlocking Mobile Feedback Webinar - June 2016
PPTX
Newsbrands and social media
PPTX
motivation & knowledge management
PPTX
Presentación sobre curso de asignatura
PDF
Project: Food map
DOCX
Universidad nacional de chimborazo katty
PPTX
Redaccion de textos
PPTX
Evaluation question 03
PPTX
今後のスマートフォンの在り方に関するユーザー
Компьютерная графика в Processing, часть 3. Изображения и текст
Компьютерная графика. Введение в Processing
Компьютерная графика в Processing, часть 2. Основные 2D-примитивы
Компьютерная графика в Processing, часть 4. Преобразования на плоскости
Arduino и бионика (Bionic Arduino). Часть 4. ШИМ, сервомашинки, I2C, акселеро...
Компьютерная графика в Processing, часть 5. Анимация
Компьютерная графика в Processing, часть 6. Взаимодействие.
Project planning forms_0210revised
Կայքի հաջողության մի քանի քայլեր
Efficient Query Answering against Dynamic RDF Databases
一公分鉛筆的故事
Unlocking Mobile Feedback Webinar - June 2016
Newsbrands and social media
motivation & knowledge management
Presentación sobre curso de asignatura
Project: Food map
Universidad nacional de chimborazo katty
Redaccion de textos
Evaluation question 03
今後のスマートフォンの在り方に関するユーザー
Ad

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

PPTX
Анимационные эффекты
KEY
Kwp2 091203
KEY
Kwp2 091210
PPTX
DSLs in Lisp and Clojure
PDF
Использование GNU OCTAVE для инженерных и математических расчетов
PPSX
создание HTML игр на элементе canvas
PDF
Лекция 8: Графы. Обходы графов
PDF
Векторизация кода (семинар 3)
PDF
Векторизация кода (семинар 2)
PPT
графика Pascal ABC
PPTX
аппроксимация функции нескольких переменных
PDF
Об особенностях использования значимых типов в .NET
PDF
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
Анимационные эффекты
Kwp2 091203
Kwp2 091210
DSLs in Lisp and Clojure
Использование GNU OCTAVE для инженерных и математических расчетов
создание HTML игр на элементе canvas
Лекция 8: Графы. Обходы графов
Векторизация кода (семинар 3)
Векторизация кода (семинар 2)
графика Pascal ABC
аппроксимация функции нескольких переменных
Об особенностях использования значимых типов в .NET
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM

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

  • 1. Компьютерная графика 3D в processing Jordi Linares i Pellicer Escola Politècnica Superior d’Alcoi Dep. de Sistemes Informàtics i Computació jlinares@dsic.upv.es http://www.dsic.upv.es/~jlinares
  • 2. 3D в processing • • • • • • В 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
  • 3. 3D в processing Геометрические преобразования в 3D Перенос Вращение вокруг x Вращение вокруг y Масштаб Вращение вокруг z
  • 4. 3D в processing Геометрические преобразования в 3D Перенос translate(tx, ty, tz) Масштабирование scale(sx, sy, sz) Вращение вокруг оси rotateX(), rotateY(), rotateZ()
  • 5. 3D в processing • • • По умолчанию используется перспективная проекция (0,0,0) находится в верхнем левом углу -z уходит вдаль -z (0,0,0) yx+z
  • 6. 3D в processing // Эллипс, вращающийся // вокруг оси y float 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); }
  • 7. 3D в processing box(width, height, depth) • Рисует кубоид, правильную призму, с центром в (0,0,0) с шириной (x), высотой (y) и глубиной (z) в качестве аргументов sphere(radius) • • Рисует сферу с центром в (0,0,0) с заданным радиусом Уровень детализации, с которой рисуется сфера, можно настроить через функцию sphereDetail(n), где n означает, что вершины будут порождаться через каждые 360º/n (по умолчанию, n = 30)
  • 8. 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); }
  • 9. 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); }
  • 10. 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); }
  • 11. 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; }
  • 12. Практика 7-1 • • • • Измените предыдущую программу так, чтобы было возможно увеличение, путём перемещения куба по оси z Для этого необходимо добавить компонент z в операцию переноса Изначально эта координата будет 0 и будет изменяться от 0 до -500 по шагам в 10 Используйте клавиши UP и DOWN, чтобы поймать событие keyPressed() и изменить увеличение
  • 13. 3D в processing // Теперь сделаем через 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; }
  • 15. 3D в processing import processing.opengl.*; // Рисование функции в 3D float rotX = 0.0, rotY = 0.0; int lastX, lastY; float distX = 0.0, distY = 0.0; // Шаги функции int steps = 50; // Масштабирование по оси z float scaleZ = 200.0; // Увеличение по оси z float 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; }
  • 17. Практика 7-2 • Измените предыдущую программу, чтобы нарисовать поверхность в «твёрдом» режиме с использованием простой модели освещения (используйте lights() и fill())
  • 18. Практика 7-3 • • Измените предыдущую программу, чтобы нарисовать поверхность с двухцветным градиентом (например, красный для малых значений z, а жёлтый для больших) Для этого используйте вызов fill() перед каждым вызовом vertex()
  • 19. Практика 7-4 • Снова измените предыдущую программу, чтобы вместо рисования функции загружать изображение, и после перевода в серую шкалу, использовать значения пикселей как координаты по z для полосы четырёхугольников