Работа графиками java - ПК журнал
Polytech-soft.com

ПК журнал
40 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Работа графиками java

Java Swing 2D. Введение

Обзор Java 2D API

Графический интерфейс джава довольно развит и включает классы графического вывода,методы работы с цветом, вывод контуров, фигур, изображений и текста, работу с областью отсечения, преобразование координат, и различные вспомогательные классы.

основные классы графического интерфейса

  • Graphics2D (расширение Graphics) — контекст вывода. Определяет текущее графическое состояние, а также методы графического вывода. Для обратной совместимости другие классы в определении своих методов указывают Graphics, хотя реально используют Graphics2D;
  • Color — цвет;
  • Font — шрифт;
  • Point (расширение Point2D) — точка;
  • Rectangle — четырехугольник;
  • Polygon — многоугольник;
  • BasicStroke — контур сложной духмерной фигуры;
  • AffineTransform — матрица преобразования координат;
  • BufferedImage (расширение Image) — изображение, можно использовать также для вне экранного вывода совместо с Graphics2D;
  • TexturePaint — используется для заполнения фигуры текстурой;
  • GradientPaint — используется для градиентного заполнения фигуры.

Цвет реализуется классом Color. В нем также определены статические члены стандартных цветов, как Color.white. Ниже приведен список методов Graphics2D для работы с цветом:

  • getBackground — получить цвет очищения области;
  • setBackground — установить цвет очищения области;
  • clearRect — очистить область;
  • setColor — установить текущий цвет вывода;
  • getColor — получить текущий цвет вывода;

фигуры

Поддерживаются следующие классы фигур:

  • Arc2D — дуга;
  • Area — область, составная фигура (например, четырехугольник минус эллипс);
  • CubicCurve2D — сегмент кубической кривой (сплайн);
  • Ellipse2D — эллипс;
  • QuadCurve2D — сегмент квадратичной кривой (сплайн);
  • Line2D — линия;
  • Rectangle2D — четырехугольник;
  • RoundRectangle2D — четырехугольник с закругленными углами;
  • Rectangle — четырехугольник;
  • Polygon — многоугольник;
  • BasicStroke — контур сложной духмерной фигуры.

Все эти классы реализуют интерфейс Shape:

  • contains — методы определения содержится ли указанная точка или четырехугольник внутри сложной фигуры;
  • intersects — определяет, пересекается ли сложная фигура с четырехугольником;
  • getBounds — возвращает ограничивающий сложную фигуру четырехугольник;
  • getPathIterator — возвращает итератор по сегментам сложной фигуры.

Ниже приведен список методов Graphics2D для вывода фигур. Методы с префиксом draw выводят контур фигуры, а с префиксом fill закрашенную фигуру. Кроме цвета для закраски могут использоваться изображения или цветовые градиенты, реализуемые классами TexturePaint, GradientPaint.

  • draw — сложная фигура;
  • draw3DRect — трехмерный четырехугольник;
  • drawArc — дуга;
  • drawLine — линия, также используется для вывода точки;
  • drawPolyline — вывод последовательности линий;
  • drawOval — овал;
  • drawPolygon — многоугольник;
  • drawRect — четырехугольник;
  • drawRoundRect — четырехугольник с закругленными углами.
  • fill — сложная фигура;
  • fill3DRect — трехмерный четырехугольник;
  • fillArc — дуга;
  • fillOval — овал;
  • fillPolygon — многоугольник;
  • fillRect — четырехугольник;
  • fillRoundRect — четырехугольник с закругленными углами.

текст и изображения

Методы Graphics2D для вывода символов и изображения:

  • drawBytes, drawChars — вывод символов;
  • drawString — вывод строки;
  • drawImage — вывод изображения.

преобразование координат

Методы Graphics2D для преобразование координат:

  • getTransform — получить копию текущей матрицы преобразований;
  • setTransform — установить матрицу преобразований;
  • rotate — добавление вращения к текущей матрице;
  • scale — добавление масштабирования к текущей матрице;
  • shear — добавления скоса к текущей матрице;
  • translate — добавление сдвига к текущей матрице.

область отсечения

Методы Graphics2D для работы с областью отсечения:

  • setClip — установить текущую область отсечения;
  • getClip — получить текущую область отсечения;
  • getClipBounds — получить четырехугольник окружающий область отсечения;
  • clipRect — сделать пересечение с текущией областью отсечения новой областью;
  • clip — сделать пересечение сложной фигуры с текущей областью отсечения новой областью.

интерактивность

Методы Graphics2D для интерактивности с пользователем:

  • hit — есть ли пересечение между фигурой и четырехугольником;
  • hitClip — есть ли пересечение между областью отсечения и четырехугольником;
  • дополнительно см. методы интерфейса Shape.

Пример вывода графики с помощью Swing 2D

Контекст вывода Graphics или Graphics2D забирает много системных ресурсов. Поэтому если вы их создаете явно из другого Graphics, компонента, BufferedImage и т.п. (обычно это метод getGraphics), то рекомендуется освободить ресурсы явно вызовом метода dispose.

Для вывода пользовательской графики обычно создается отдельный элемент управления, который затем размещается на главное окно. В нем перегружается метод paintComponent для Swing элементов, или методы paint и update для awt элементов.
В этих случаях ресурсы контекста вывода освобождаются автоматически.

Для сохранения родительского облика в методе можно сделать вызов super.paintComponent(g);. И далее дорисовать поверх. Для примера в нижеследующем коде замените JComponent на JButton и удалите очищение фона.

Работа с изображениями в Swing 2D

Изображения в java описываются классом BufferedImage, который объединяет в себе объект растровых данных Raster и объект цветовой модели ColorModel.

В свою очередь объект растровых данных состоит из объекта DataBuffer, содержащего
четырехугольный массив значений пикселей, и объекта SampleModel, описывающего организацию данных в массиве: число банков в DataBuffer, ширину и высоту изображения, тип значений в DataBuffer (например, TYPE_INT).

Объект ColorModel нужен для преобразования данных пикселя в значения составляющих цвета.

вывод в изображение

Для вывода в изображение всего лишь надо получить контекст вывода изображения. Например, в следующем коде создается изображение белого многоугольника на сиреневом фоне.

вывод изображения

Для вывода изображения в объекте контекста вывода Graphics2d есть несколько методов. Для краткости я опущу типы аргументов:

  • drawImage(img, x, y, observer)
  • drawImage(img, x, y, bgcolor,observer)
  • drawImage(img, x, y, width, height, bgcolor, observer)
  • drawImage(img, x, y, width, height, observer)
  • drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, bgcolor, observer)
  • drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, observer)

Первый аргумент везде само изображение.

x, y, width, height — четырехугольная область вывода.

dx1, dy1, dx2, dy2 — координаты четырехугольной области вывода.

sx1, sy1, sx2, sy2 — координаты четырехугольной части изображения, которая будет выведена.

В качестве значения аргумента observer можно указывать null. Данный аргумент нужен только при асинхронной работе с изображением.

bgcolor — цвет заднего фона для прозрачных частей изображения.

Если область вывода не соответствует выводимой части изображения, то растровые данные автоматически масштабируются.

Графические форматы файлов.

Для манипуляций с графическими файлами в Java определен класс ImageIO.
При чтении ImageIO сам определяет формат файла. Список поддерживаемых форматов зависит от реализации Java, однако гарантируется поддержка jpeg, png, gif, bmp и wbmp. Список поддерживаемых форматов можно получить вызовом ImageIO.getWriterFormatNames()

Читать еще:  Ошибка сервисов гугл плей как устранить

Для теста создадим компонент, который при создании будет загружать изображение с диска, тут же его запишет обратно на диск в другом формате. А само изображение будет использоваться для оформления компонента.

Графика в Java. Graphics

Графический контекст компонентов

Графику в Java обслуживают классы Graphics и Graphics2D.

Работа с графикой осуществляется в графическом контексте элементов, унаследованных от класса Component. Понимать это можно так: на элементах управления, например, JFrame, JPanel, JButton и других, есть возможность рисовать. Такие элементы обладают графическим контекстом, в этом контескте мы и рисуем. Всё, что нарисуем в контексте будет показано на элементе. Классы Graphics и Graphics2D нужны для работы с графическим контекстом. Мы должны получить экземпляр такого класса и, используя его методы, рисовать. Получить экземпляр контекста можно в методе paint:

этот метод наследуется из класса Component. Аргумент Graphics g создаётся системой, а мы берём его в готовом виде и используем для рисования. При создании элемента метод paint будет вызван автоматически.

Начнём изучать работу с графикой в Java с класса Graphics.

Graphics

Рассмотрим простой пример использования методов класса Graphics в Java:

Получаем:

Ниже разбираются все методы, использованные в примере.

Как начертить прямую линию?

Метод drawLine класса Graphics начертит прямую линию:

здесь 20, 30 — это координаты x, y начала линии,
360, 30 — координаты конца линии.

Как задать цвет?

Метод setColor класса Graphics сделает текущим новый цвет:

Аргументы конструктора new Color(0, 0, 255) — это красный, зелёный и синий цвета соответственно (rgb).

Как задать rgb цвета? В примере задан чисто синий цвет, т.к. значения других составляющих равны нулю. Вот чисто красный цвет:

А это чисто зеленый цвет:

Значения составляющих цвета изменяются от 0 до 255.

Светло-синий цвет, который мы использовали для заливки прямоугольника:

Как задать цвет фона?

Задать цвет фона можно методом setBackground:

Как нарисовать прямоугольник?

Методом drawRect класса Graphics:

20, 40 — это координаты верхнего левого угла прямоугольника;
340 — длина;
20 — высота прямоугольника.

Как залить прямоугольник цветом?

Методом fillRect класса Graphics:

Как нарисовать прямоугольник с закругленными углами?

Методом drawRoundRect класса Graphics.

Сопряжение, т.е. закругление на углах, делается с помощью частей овала.

первые 4 аргумента как у обычного прямоугольника. Пятый аргумент — 20 — это ширина прямоугольника, в который вписана часть овала сопряжения. Шестой аргумент — 15 — это высота прямоугольника, в который вписана часть овала сопряжения.

Как нарисовать овал?

Методом drawOval класса Graphics:

Аргументы определяют прямоугольник, в который вписан овал.

Как нарисовать окружность?

Методом drawOval класса Graphics:

Аргументы определяют прямоугольник, в который вписана окружность. Здесь рисуем овал, но длина и высота описанного прямоугольника равны, что и даёт окружность.

Как нарисовать дугу?

Методом drawArc класса Graphics:

первые 4 аргумента как у обычного прямоугольника. Пятый аргумент — 0 — это угол, от которого отсчитывается угол самой дуги. 180 — это угол дуги. Углы отсчитывают от горизонтальной оси: по часовой стрелке отрицательное направление, протв — положительное. В примере 180 градусов (величина дуги) отсчитываем от горизонтальной линии.

Как нарисовать многоугольник?

Методом drawPolygon класса Graphics:

Здесь создаём объект класса Polygon. arrayX — это х-координаты вершин многоугольника, arrayY — это y-координаты вершин многоугольника, 8 — число вершин многоугольника.

Как создать объект точки?

Для этого используем класс Point:

аргументы — это x, y координаты.

Как определить, что точка принадлежит многоугольнику?

Используем метод класса Polygon contains для определения лежит ли точка в многоугольнике.

Как вывести строку?

Методом drawString класса Graphics:

строка «Yes» будет выведена от точки с координатами 50, 190.

Как задать шрифт?

Для этого используем класс Font:

где «Tahoma» — название шрифта,
Font.BOLD|Font.ITALIC — жирный шрифт с наклоном,
40 — высота шрифта.

После задания шрифта мы делаем его текущим и выводим строку этим шрифтом:

Как задать цвет текста?

Чтоб задать цвет текста создадим и установим в графический контекст новый цвет:

Здесь мы создали чисто синий цвет. А теперь выводим строку синим цветом:

Как начертить график?

Как график функции начертить? Сначала начертим координатные оси:

А теперь построить график функции можно просто. Для этого используем метод drawPolyline класса Graphics:

График строим по точкам, xArray – это x-координаты точек, yArray – y-координаты точек графика, nPoint — это число точек.

Наш график являет собой кривую намагничивания. Но почему график такой угловатый (см. картинку выше)? Если взять больше точек, то график будет более плавным.

Не могу понять, как работать с графикой

Есть примитивная программа. Создаётся Frame, в нём создаётся Panel, далее в методе paintComponent рисуется линия. Как теперь человеческими способами переписать программу так, чтобы то, что требуется нарисовать, рисовалось, к примеру, в функции main, потому что принятие решений о том, что рисовать, должно делаться НЕ внутри paintComponent. Как идеальный пример хотелось бы увидеть программу, которая нарисует одну линию, а через 5 секунд нарисует вторую линию

22.01.2012, 14:24

Не могу понять как работать с событиями
Здравствуйте. Подскажите пожалуйста такую вещь: У меня при нажатии на кнопку выбора файла .

TStyleManager, не могу понять как работать с ним
Ребята! Помогите! Хочу сделать программу покрасивее, но я не могу понять как работать с ним. Класс.

Не могу понять, как должна работать модель
Не могу понять алгоритм работы модели, кто может, подскажите как данная модель должна.

Не могу понять как работать с данным массивом
Добрый день форумчане! Имеется массив .

22.01.2012, 15:12222.01.2012, 15:28 [ТС]3

1. Зачем в методе MyFrame.paint оставлено рисование линии? И почему если это место закомментировать, то при запуске программы окно не прорисовывается?
2. В моём примере (взято из книги), рисование происходит на панели. В твоём, если я правильно понимаю, прямо на фрейме. Какая между этими вещами разница?

Добавлено через 5 минут
Если перефразировать мой изначальный вопрос, то звучать он будет примерно так. В моём тестовом примере по сути дела рисуется СТАТИЧЕСКАЯ КАРТИНКА. А мне хотелось бы уметь это делать динамически. Например, как реализовать передвигающийся кружок (квадрат, треугольник, не суть) мне непонятно. А точнее, непонятно, как это безе черезжо..ностей сделать

Читать еще:  Java 8 update 45 что это
22.01.2012, 16:22422.01.2012, 17:16 [ТС]523.01.2012, 07:026

А как можно нарисовать что-то, не зная что именно?

В самом простом варианте, можно поступить следующим образом:
1. Создаешь свой интерфейс

23.01.2012, 11:32 [ТС]7

Элементарно. Во всяком случая, я себе представлял, что реализовано что-то типа следующего. «Наверху» срашивают у «низа» что-то типа «дай мне графический контекст для рисования». На нём «наверху» отображают всё, что надо, а потом отдают «вниз» приказ типа «мы закончили рисовать, отображай на экран». Схематически что-то типа того:

При таком раскладе мы «наверху» рисуем то, что нам надо, не занимаясь извращениями в виде дополнительных классов и надстроек «внизу». «Внизу» вообще ничего не должны знать о том, какие данные имеются в нашей программе. «Внизу» должны только делать то, что требуют «сверху», не занимаясь хранением дополнительных данных и знаний о том, что же надо рисовать. Наподобие того, что есть в Borland’е: см. Краткое руководство по работе с классом TCanvas для начинающих раздел 1.1. Метод ButtonClick — это обработчик событий, хотя на его месте можно вполне себе поставить main-поток исполнения задачи, НЕ ЗАВОДЯ НИКАКИХ ДОПОЛНИТЕЛЬНЫХ КЛАССОВ. Неужто в java нельзя сделать вот так по простому?

Создание движка для 3D-рендеринга на Java

    Переводы, 10 марта 2016 в 23:38

Современные движки для 3D-рендеринга, использующиеся в играх и мультимедиа, поражают своей сложностью в плане математики и программирования. Соответственно, результат их работы превосходен.

Многие разработчики ошибочно полагают, что создание даже простейшего 3D-приложения с нуля требует нечеловеческих знаний и усилий. К счастью, это не совсем так. Более того, при наличии компьютера и свободного времени, можно создать нечто подобное самостоятельно. Давайте взглянем на процесс разработки нашего собственного движка для 3D-рендеринга.

Итак, для чего же это всё нужно? Во-первых, создание движка для 3D-рендеринга поможет понять, как же работают современные движки изнутри. Во-вторых, сам движок при желании можно использовать и в своём собственном приложении, не прибегая к вызову внешних зависимостей. В случае с Java это значит, что вы можете создать своё собственное приложение для просмотра 3D-изображений без зависимостей (далёких от API Java), которое будет работать практически везде и уместится в 50 КБ!

Само собой, если вы хотите создать какое-нибудь большое 3D-приложение с плавной анимацией, вам лучше использовать OpenGL/WebGL. Однако, имея базовое представление о том, как устроены подобные движки, работа с более сложными движками будет казаться в разы проще.

Sportmaster Lab, Москва

В этой статье я постараюсь объяснить базовый 3D-рендеринг с ортографической проекцией, простую треугольную растеризацию (процесс, обратный векторизации), Z-буферизацию и плоское затенение. Я не буду заострять своё внимание на таких вещах, как оптимизация, текстуры и разные настройки освещения — если вам это нужно, попробуйте использовать более подходящие для этого инструменты, вроде OpenGL (существует множество библиотек, позволяющих вам работать с OpenGL, даже используя Java).

Примеры кода будут на Java, но сами идеи могут, разумеется, быть применены для любого другого языка по вашему выбору.

Довольно болтать — давайте приступим к делу!

Для начала, давайте поместим хоть что-нибудь на экран. Для этого, я буду использовать простое приложение, в котором будет отображаться наше отрендеренное изображение и два скроллера для вращения.

Результат должен выглядеть вот так:

Теперь давайте добавим некоторые модели — вершины и треугольники. Вершина — это просто структура для хранения наших трёх координат (X, Y и Z), а треугольник соединяет вместе три вершины и содержит их цвет.

Здесь я буду считать, что X означает перемещение влево-вправо, Y — вверх-вниз, а Z будет глубиной (так, что ось Z перпендикулярна вашему экрану). Положительная Z будет означать «ближе к пользователю».

В качестве примера я выбрал тетраэдр как простейшую фигуру, о которой вспомнил — нужно всего 4 треугольника, чтобы описать её.

Код также будет достаточно простым — мы просто создаём 4 треугольника и добавляем их в ArrayList:

В результате мы получим фигуру, центр которой находится в начале координат (0, 0, 0), что довольно удобно, так как мы будем вращать фигуру относительно этой точки.

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

Заметьте, что сейчас я совершил все преобразования до отрисовки треугольников. Это сделано, чтобы для того, что бы поместить наш центр (0, 0, 0) в центр экрана — по умолчанию начало координат находится в левом верхнем углу экрана. После компиляции вы должны получить:

Вы можете не поверить, но это наш тетраэдр в ортогональной проекции, честно!

Теперь нам нужно добавить вращение. Для этого мне нужно будет немного отойти от темы и поговорить об использовании матриц и о том, как с их помощью достичь трёхмерной трансформации 3D-точек.

Существует много путей манипулировать 3D-точками, но самый гибкий из них — это использование матричного умножения. Идея заключается в том, чтобы показать точки в виде вектора размера 3×1, а переход — это, собственно, домножение на матрицу размера 3×3.

Возьмём наш входной вектор A:

И умножим его на так называемую матрицу трансформации T, чтобы получить в итоге выходной вектор B:

Например, вот как будет выглядеть трансформация, если мы умножим на 2:

Вы не можете описать любую возможную трансформацию, используя матрицы размера 3×3 — например, если переход происходит за пределы пространства. Вы можете использовать матрицы размера 4×4, делая перекос в 4D-пространство, но об этом не в этой статье.

Трансформации, которые нам пригодятся здесь — масштабирование и вращение.

Любое вращение в 3D-пространстве может быть выражено в 3 примитивных вращениях: вращение в плоскости XY, вращение в плоскости YZ и вращение в плоскости XZ. Мы можем записать матрицы трансформации для каждого из данных вращений следующим путём:

И вот здесь начинается магия: если вам нужно сначала совершить вращение точки в плоскости XY, используя матрицу трансформации T1, и затем совершить вращение этой точки в плоскости YZ, используя матрицу трансформации T2, то вы можете просто умножить T1 на T2 и получить одну матрицу, которая опишет всё вращение:

Читать еще:  Обновить плагин java

Это очень полезная оптимизация — вместо того, чтобы постоянно считать вращения на каждой точке, мы заранее считаем одну матрицу и затем используем её.

Что ж, довольно страшной математики, давайте вернёмся к коду. Создадим служебный класс Matrix3, который будет обрабатывать перемножения типа “матрица-матрица” и “вектор-матрица”:

Теперь можно и оживить наши скроллеры вращения. Горизонтальный скроллер будет контролировать вращение влево-вправо (XZ), а вертикальный скроллер будет контролировать вращение вверх-вниз (YZ).

Давайте создадим нашу матрицу вращения:

Вам также будет нужно добавить слушателей на скроллеры, чтобы обеспечить обновление изображения, когда вы будете тянуть их вверх-вниз или вправо-влево.

Как вы, наверное, уже заметили, вращение вверх-вниз ещё не работает. Добавим эти строки в код:

До сих пор мы отрисовывали только каркасное представление нашей фигуры. Теперь давайте заполним его чем-нибудь. Для этого нам нужно сначала растеризовать треугольник — представить его в виде пикселей на экране.

Я буду использовать очень простой, но крайне неэффективный метод — растеризация через барицентрические координаты. Настоящие 3D-движки используют растеризацию, задействуя железо компьютера, что очень быстро и эффективно, но мы не можем использовать нашу видеокарту, так что будем делать всё вручную, через код.

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

Довольно много кода, но теперь у нас есть цветной тетраэдр на экране.

Если вы поиграетесь с демкой, то вы заметите, что не всё сделано идеально — например, синий треугольник всегда выше других. Так происходит потому, что мы отрисовываем наши треугольники один за другим. Синий здесь — последний, поэтому он отрисовывается поверх других.

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

Теперь видно, что у нашего тетраэдра есть одна белая сторона:

Вот мы и получили работающий движок для 3D-рендеринга!

Но и это ещё не конец. В реальном мире восприятие какого-либо цвета меняется в зависимости от положения источников света — если на поверхность падает лишь небольшое количество света, то она видится более темной.

В компьютерной графике мы можем достичь подобного эффекта с помощью так называемого «затенения» — изменения цвета поверхности в зависимости от угла наклона и расстояния относительно источника света.

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

Для начала нам нужно посчитать вектор нормали для нашего треугольника. Если у нас есть треугольник ABC, мы можем посчитать его вектор нормали, рассчитав векторное произведение векторов AB и AC и поделив получившийся вектор на его длину.

Векторное произведение — это бинарная операция на двух векторах, которые определены в 3D пространстве вот так:

Вот так выглядит визуальное представление того, что делает наше векторное произведение:

Теперь нам нужно посчитать косинус между нормалью треугольника и направлением света. Для упрощения будем считать, что наш источник света расположен прямо за камерой на каком-либо расстоянии (такая конфигурация называется «направленный свет») — таким образом, наш источник света будет находиться в точке (0, 0, 1).

Косинус угла между векторами можно посчитать по формуле:

Где ||A|| — длина вектора, а числитель — скалярное произведение векторов A и B:

Обратите внимание на то, что длина вектора направления света равна 1, так же, как и длина нормали треугольника (мы уже нормализовали это). Таким образом, формула просто превращается в это:

Заметьте, что только Z компонент направления света не равен нулю, так что мы можем просто всё упростить:

В коде это всё выглядит тривиально:

Мы опускаем знак результата, потому что для наших целей нам не важно, какая сторона треугольника смотрит на камеру. В реальном приложении вам нужно будет отслеживать это и применять затенение соответственно.

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

Код будет давать нам некоторые эффекты затенения, но спадать они будут куда быстрее, чем нам нужно. Так происходит, потому что в Java используется спектр цветов sRGB.

Так что нам нужно конвертировать каждый цвет в линейный формат, применить затенение и затем конвертировать обратно. Реальный переход из sRGB к линейному RGB — довольно трудоёмкий процесс, так что я не буду выполнять полный перечень задач здесь. Вместо этого, я сделаю нечто приближенное к этому.

И теперь мы видим, как наш тетраэдр оживляется. У нас есть работающий движок для 3D рендеринга с цветами, освещением, затенением, и заняло это около 200 строк кода — неплохо!

Вот небольшой бонус для вас — вы можете быстро создать фигуру, приближенную к сфере из своего тетраэдра. Этого можно достичь путём разбивания каждого треугольника на 4 маленьких и «надувая».

Вот что должно у вас получиться:

Я бы закончил эту статью, порекомендовав одну занимательную книгу: “Основы 3D-математики для графики и разработки игр”. В ней вы можете найти детальное объяснение процесса рендеринга и математики в этом процессе. Её стоит прочитать, если вам интересны движки для рендеринга.

Ссылка на основную публикацию
ВсеИнструменты 220 Вольт
Adblock
detector