Докуметация Cтарт Статьи Форум Лента Вход
Не официальное русскоязычное сообщество
Главная
    Документация jMonkeyEngine
        jMonkeyEngine Уроки и Документация
            Введение в математический функционал

Введение в математический функционал

Опубликованно: 19.04.2017, 15:43
Последняя редакция, Andry: 06.07.2017 0:11

Это факт жизни, математика трудна! К сожалению, трехмерная графика требует достаточных хороших знаний о предмете. К счастью, jME способен скрывать большинство деталей от пользователя. Векторы — это фундаментальный тип в 3D-среде, и он широко используется. Матрицы также являются основной необходимостью в 3D для представления линейных систем. Кватернионы, возможно, являются самыми мощными и сложными из основных типов, и используются для вращения в jME.

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

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

Система координат

Описание

Система координат состоит из начала координат (одна точка в пространстве) и трех координатных осей, каждая из которых имеет единичную длину и взаимно перпендикулярна. Оси можно записать как столбец матрицы, R = [U1 | U2 | U3]. Фактически, именно так работает CameraNode. Система координат, определенная камерой, сохраняется в матрице.

JME использует правую систему координат (как это делает OpenGL).

Определение системы координат задается в jME свойствами Camera. Нет никаких проверок ошибок, чтобы убедиться, что: 1) система координат является правой и 2) оси взаимно перпендикулярны. Поэтому, если пользователь неправильно задает оси, он будет получать очень чудные результаты визуализации(rendering) (случайный отбраковку и т. Д.).

beginner-picking

 

Однородные координаты

Однородные координаты имеют дополнительное значение W, прикрепленное к концу. Значения XYZ делятся на W, чтобы дать истинные координаты.

Это имеет несколько преимуществ, одно из которых техническое, важное для некоторых прикладных программистов:

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

Для прикладных программистов это означает, что вы можете выразить бесконечно длинные векторы, которые все еще имеют направление — они, как правило, используются в освещении. Просто используйте значение W, равное 0.0.

Преобразования

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

Описание Видимости

Определение видимости связано с минимизацией объема данных, отправляемых на видеокарту для визуализации. В частности, мы не хотим отправлять данные, которые не будут видны. Данные, которые не отправляются на видеокарту, считаются отбракованными. Основное внимание в этом разделе уделяется Frustum Culling(Усеченная Выбраковка), основанная на усечении зрения камеры. По сути, этот усеченный конус создает шесть стандартных плоскостей обзора. BoundingVolume объекта проверяется относительно плоскостей усеченного конуса, чтобы определить, содержится ли он в усеченной области. Если в какой-либо момент граница объекта находится вне плоскости, она выкидывается и больше не обрабатывается для рендеринга. Это также относится ко всем потомкам, которыми он управлял, что позволяет быстро отсеивать большие участки сцены.

Основные типы

ColorRGBA

Описание

ColorRGBA определяет значение цвета в библиотеке jME. Значение цвета состоит из трех компонентов: красного, зеленого и синего. Четвертый компонент определяет альфа-значение (прозрачность) цвета. Каждое значение устанавливается между [0, 1]. Все, что ближе к 0, будет привязано к 0, и все, что ближе 1, будет привязано к 1.

Если вы хотите «преобразовать обычное значение RGB (0-255) в формат, используемый здесь (0-1), просто умножьте его на: 1/255.

jME класс

Для удобства использования ColorRGBA определяет несколько статических значений цвета. То есть, нежели:

ColorRGBA red = new ColorRGBA(1,0,0,1);
object.setSomeColor(red);

Вы можете просто сказать:

object.setSomeColor(ColorRGBA.red)

ColorRGBA также будет обрабатывать интерполяцию между двумя цветами. Если заданы второй цвет и значение от 0 до 1, то у объекта, обладающего свойством ColorRGBA, будут изменены значения цвета этого нового интерполированного цвета.

Матрицы

Смотрите Matrix3f Javadoc и Matrix4f Javadoc

Описание

Матрица обычно используется как линейное преобразование для преобразования векторов в векторы. То есть: Y = MX, где X — вектор, а M — матрица, выполняющая какое либо преобразование(масштабирование, поворот, трансляция).

Существует несколько специальных матриц:

Нулевая матрица — это матрица со всеми нулевыми элементами.

 0 0 0
 0 0 0
 0 0 0

Единичная Матрица — это матрица с 1 на диагонали и 0 для всех остальных элементов.

 1 0 0
 0 1 0
 0 0 1

Матрица является обратимой, если существует матрица M-1, где MM-1 = M-1M = I.

Транспонирование матрицы M = [mij] равна MT = [mji]. Оно приводит к тому, что строки M становятся столбцами в MT.

 1 1 1 1 2 3
 2 2 2 1 2 3
 3 3 3 1 2 3

Матрица симметрична, если M = MT. То есть элементы симметричны относительно главной диагонали.

 X A B
 A X C
 B C X

JME включает в себя два типа матричных классов: Matrix3f и Matrix4f. Matrix3f является матрицей 3×3 и является наиболее часто используемым (способным обрабатывать масштабирование и вращение), в то время как Matrix4f является матрицей 4×4, которая также может обрабатывать перемещение.

Преобразования

Умножение на матрицу вектора позволяет осуществить преобразование вектора. Также вращение, масштабирование или перемещение этого вектора.

Масштабирование(Scaling)

Если диагональная Матрица, определенная D = [dij] и dij = 0 для i! = j, имеет все положительные элементы, то она является масштабируемой матрицей. Если di больше 1, тогда результирующий вектор будет расти, а если di меньше 1, он уменьшится.

Вращение(Rotation)

Для матрицы поворота требуется, чтобы транспонированная и инверсия матрицы были одной и той же матрицей (R-1 = RT). Затем матрицу вращения R можно вычислить как: R = I + (sin(angle))S + (1 — cos(angle))S2, где S:

 0 u2 -u1
 -u2 0 u0
 u1 -u0 0

Перемещение(Translation)

Для перемещения требуется матрица 4×4, где вектор (x, y, z) сопоставляется с (x, y, z, 1) для умножения. Матрица перемещения затем определяется как:

 M T
 ST 1

Где M — матрица 3×3 (содержащая любую информацию о ротации/масштабе), T — вектор перемещения, а ST — транспонированный вектор T. 1 — это просто константа.

jME класс

Оба Matrix3f и Matrix4f сохраняют свои значения в виде чисел типа float и являются общедоступными как (m00, m01, m02, …, mNN), где N равно 2 или 3.

Большинство методов являются прямыми, и я оставлю документацию в Javadoc.

Вектор

Смотрите Vector3f Javadoc и Vector2f Javadoc

Описание

Векторы используются для реализации множества вещей в jME, точек в пространстве, вершин в треугольной сетке, нормалей и.т.д. Эти классы (в частности Vector3f) являются, вероятно, наиболее используемым классом в jME.

Вектор определяется множеством из вещественных чисел. V = <V1, V2, …, Vn>.

У нас есть два вектора (2f и 3f), что означает, что у нас есть множество из 2 значений типа float или 3 значений типа float.

Операции

Умножение на Скаляр

Вектор может быть умножен на скалярное значение, чтобы создать второй вектор с теми же пропорциями, что и первый. aV = Va = <aV1, aV2, …, aVn>

Сложение и вычитание

Добавление или вычитание двух векторов происходит покомпонентно. То есть первый компонент первого вектора прибавляется(вычитается) к первому компоненту второго вектора и.т.д.

P + Q = <P1+Q1, P2+Q2, …, Pn+Qn>

Величина

Величина определяет длину вектора. Вектор величиной в 1 является единичным.

Например, если V = (x, y, z), величина представляет собой квадратный корень из (x2 + y2 + z2).

Вектор можно нормализовать или сделать единичным, умножив вектор на (1/величину).

Скалярное произведение

Точечное произведение двух векторов определяется как: P точка Q = PxQx + PyQy + PzQz

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

Если скалярное произведение равно 0, то два вектора ортогональны или отклонены на 90 градусов.

Векторное произведение

Векторное произведение двух векторов возвращает третий вектор, перпендикулярный двум векторам. Это очень полезно для вычисления нормалей поверхности.

P X Q = <PyQz — PzQy, PzQx — PxQz, PxQy — PyQx>

jME класс

Vector3f и Vector2f сохраняют свои значения (x, y, z) и (x, y) как значения типа float. Большинство методов являются прямыми, и я оставлю документацию в Javadoc.

Кватернион

Смотрите Кватернионы Javadoc

Описание

Кватернионы определяют систему гиперкомплексные чисел. Кватернионы определяются (i2 = j2 = k2 = ijk = -1). JME использует кватернионы, поскольку они позволяют компактное представления вращения, и ориентацию в 3D пространстве. Всего с четырьмя float значениями, мы можем представить ориентацию объекта, там где матрице поворота потребовалось бы девять. Они также требуют меньше арифметических операций для конкатенации.

Дополнительные преимущества Кватернионов это снижение вероятности шарнирного замка(Gimbal Lock) и то что они позволяют легко интерполяцию между двумя вращениями(сферическую линейную интерполяцию или slerp).

В то время как Кватернионы довольно сложно полностью понять, существует множество удобных методов позволяющих вам использовать их не понимая математику лежащую в основе этого. В принципе, эти методы включают в себя не более чем установку значений кватерниона x, y, z, w с использованием других методов представления поворотов. Кватернион затем содержится в Spatial в качестве локальной компоненты вращения.

Кватернион q имеет вид:

q = <_w,x,y,z_> = w + xi + yj + zk

Или, альтернативно, он может быть записан как:

q = s + v, где s представляет собой скалярную часть, соответствующую w-компоненте q, а v представляет векторную часть (x, y, z) компоненты q.

Умножение Кватернионов использует дистрибутивный закон и придерживается следующих правил умножения мнимых компонентов (i, j, k):

i2 = j2 = k2 = -1+ ij = -ji = k+ jk = -kj = i+ ki = -ik = j

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

q1q2 = s1s2 — v1 dot v2 + s1v2 + s2v1 + v1 X v2

Кватернионы также имеют сопряжённость, где сопряженное с q есть (s — v)

Эти базовые операции позволяют нам преобразовывать различные представления вращения в кватернионах.

Угол Оси

Вы можете задать своё вращение через угол и ось. То есть вы определяете ось вращения и угол поворота вокруг этой оси. Кватернион определяет метод из AngleAxis (и fromAngleNormalAxis) для создания Кватерниона из этой пары. Это довольно активно используется в демонстрациях jME для постоянного вращения объектов. Вы также можете получить поворот по углу и оси из существующего кватерниона с помощью toAngleAxis.

Пример — Поворот Spatial c использованием fromAngleAxis

//вращение вокруг оси Y примерно на 1 пи
Vector3f axis = Vector3f.UNIT_Y;
// UNIT_Y равен (0,1,0) и не требует создания нового объекта
float angle = 3.14f;
s.getLocalRotation().fromAngleAxis(angle, axis);

Три Угла

Вы также можете задать поворот путем определения трех углов. Углы представляют вращение вокруг отдельных осей. Передача в трехэлементном массиве чисел типа float определяет углы, где первый элемент — X, второй — Y, а третий — Z. Метод, предоставляемый Кватернионом, из Angle может также заполнять массив, используя toAngles

Пример — поворота Spatial используя fromAngles

//поворот 1 радиан по x, 3 по y и 0 по z
float[] angles = {1, 3, 0};
s.getLocalRotation().fromAngles(angles);

Три Оси

Если у вас есть три оси, которые определяют ваше вращение, где оси определяют левую ось, ось вверх и ось направления соответственно), вы можете использовать fromAxes для генерации кватерниона. Следует отметить, что это создаст новый объект Matrix, который затем будет собран мусором, поэтому этот метод не следует использовать, если он будет вызываться много раз. Опять же, toAxes заполнит массив Vector3f.

Пример — поворота Spatial используя fromAxes

//поворота spatial лицевой стороной вверх на ~45 градусов
Vector3f[] axes = new Vector3f[3];
axes[0] = new Vector3f(-1, 0, 0); //лево
axes[1] = new Vector3f(0, 0.5f, 0.5f); //вверх
axes[2] = new Vector3f(0, 0.5f, 0.5f); //dir

s.getLocalRotation().fromAxes(axes);

Матрица поворота

Обычно вы можете получить Matrix, определяющую вращение. На самом деле, зачастую, чтобы сохранить вращение в Matrix, вам нужно создать Кватернион, повернуть Кватернион, а затем вы можете вернуть Matrix. Quaternion содержит метод fromRotationMatrix, который создаст соответствующий кватернион на основе Matrix. ToRotationMatrix будет заполнять заданную Matrix.

Пример — поворота Spatial с использованием Матрицы поворота

Matrix3f mat = new Matrix3f();
mat.setColumn(0, new Vector3f(1,0,0));
mat.setColumn(1, new Vector3f(0,-1,0));
mat.setColumn(2, new Vector3f(0,0,1));

s.getLocalRotation().fromRotationMatrix(mat);

Как видите, есть много способов использовать Кватернион. Этот позволяет вам работать с поворотами так, чтобы концептуально легче было их представить, но все равно создавался кватернион для внутреннего представления.

Slerp

Одно из самых больших преимуществ использования кватернионов — интерполяция между двумя поворотами. То есть, если у вас есть исходный кватернион, представляющий первоначальную ориентацию объекта, и у вас есть конечный кватернион, представляющий ориентацию, которую вы хотите получить, вы можете реализовать поворот очень плавно с помощью slerp. Просто введите время, где время равно [0, 1], 0 — начальное вращение, а 1 — конечное вращение.

Пример — использования Slerp для поворота между двумя кватернионами.

/*
Вы можете интерполировать повороты между двумя кватернионами, используя spherical linear
interpolation (slerp).
*/
Quaternion Xroll45 = new Quaternion();
Xroll45.fromAngleAxis(45 * FastMath.DEG_TO_RAD, Vector3f.UNIT_X);
//
Quaternion Yroll45 = new Quaternion();
Yroll45.fromAngleAxis(45 * FastMath.DEG_TO_RAD, Vector3f.UNIT_Y);

//поворот на половину между этими двумя

Quaternion halfBetweenXroll45Yroll45 = new Quaternion();
halfBetweenXroll45Yroll45.slerp(Xroll45, Yroll45, 0.5f);
geom2.setLocalRotation(halfBetweenXroll45Yroll45);

Умножение

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

Quaternion myRotation = pitch90.mult(roll45); /* тангаж и крен */

Чтобы повернуть Vector3f вокруг его начала по количеству Quaternion, используйте метод multLocal в Quaternion:

Quaternion myRotation = pitch90;
Vector3f myVector = new Vector3f(0,0,-1);
myRotation.multLocal(myVector);

Служебные Классы

Наряду с базовыми математическими классами jME предоставляет несколько классов Math, чтобы упростить разработку (и надеюсь существенно). Большинство этих классов находят применение во всей внутренней системе jME. Они также могут оказаться полезными для пользователей.

Быстрая математика

Смотрите FastMath Javadoc

Описание

Fast Math предоставляет ряд удобных методов по мере возможностей, более быстрые версии(хотя это может быть в ущерб точности).

Применение

FastMath предоставляет ряд констант, которые могут помочь в общих математических уравнениях. Одним из важных атрибутов является USE_FAST_TRIG, если вы установите это значение true, то будет использоваться таблица для тригонометрические функции, а не стандартная математическая библиотека Java. Это обеспечивает значительное увеличение скорости, но может снижать точность, поэтому следует соблюдать осторожность.

Существует пять основных категорий функций, которые предоставляет FastMath.

Тригонометрические функции

  • cos и acos — Возвращает значения косинуса и арккосинуса(используются данные из таблица если USE_FAST_TRIG true)
  • sin и asin — Возвращает значения синуса и арксинус (используются данные из таблица если USE_FAST_TRIG true)
  • tan и atan — Возвращает значения тангенс и арктангенс

Численные методы

  • ceil — Возвращает ceil (наименьшее значение, которое больше или равно заданному значению целому числу) значения.
  • floor — Возвращает floor (наибольшее значение, которое меньше или равно заданному значению целому числу) значения.
  • exp — Возвращает эйлеровый номер(а), увеличенный до указанного значения.
  • sqr — Возвращает квадрат значения (т.е. value*value).
  • pow — Возвращает первое заданное число, возведенное в степень второго.
  • isPowerOfTwo — Возвращает boolean значение, если значение является степенью двойки или нет (например, 32, 64, 4).
  • abs — Возвращает абсолютное значение заданного числа.
  • sign — Возвращает знак значение (1 если число положительное, -1, если отрицательное, и 0, Если 0).
  • log — Возвращает значение натурального логарифма.
  • sqrt — Возвращает квадратный корень из значения.
  • invSqrt — Возвращает обратный квадратный корень то есть значение(1/sqrt(value).

Линейная алгебра

  • LERP — Вычислить линейную интерполяцию двух точек, учитывая время между 0 и 1.
  • determinant — Вычисляет определитель матрицы 4×4.

Геометрические функции

  • counterClockwise — С учетом трех точек (определяющих треугольник) определяется кривая линия. 1 если против часовой стрелки, -1 если по часовой стрелке и 0, если точки определяют линию.
  • pointInsideTriangle — Вычисляет, находится ли точка внутри треугольника.
  • sphericalToCartesian — Преобразует точку из сферических координат в декартовы координаты.
  • cartesianToSpherical — Преобразует точку из декартовых координат в сферические.

Разное.

  • newRandomFloat — получить случайное float значение.
  • Line(Линия)

    Смотрите Line Javadoc

    Описание

    Линия — это прямая одномерная фигура, не имеющая толщины и бесконечно расширяющаяся в обоих направлениях. Линия определяется двумя точками A и B, и проходит через обе точки.

    Применение

    JME определяет класс Line, который определяется началом и направлением. На самом деле класс Line обычно используется в качестве сегмента линии. Где линия конечна и содержится между этими двумя точками.

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

    Пример 1 — найдём случайную точку на линии

    Line l = new Line(new Vector3f(0,1,0), new Vector3f(3,2,1));
    Vector3f randomPoint = l.random();
    

    Plane(плоскость)

    Смотрите Plane Javadoc

    Описание

    Плоскость определяется уравнением N. (X — X0) = 0, где N = (a, b, c) и проходит через точку X0 = (x0, y0, z0). X определяет другую точку на этой плоскости (x, y, z).

    N. (X — X0) = 0 можно описать как (N. X) + (N. -X0) = 0

    или

    (ax + by + cz) + (-ax0-by0-cz0) = 0

    где (-ax0-by0-cz0) = d

    Где d — отрицательное значение точки на плоскости, умноженной на единичный вектор, описывающий ориентацию плоскости.

    Это дает общее уравнение: (ax + by + cz + d = 0)

    Применение в jME

    JME определяет плоскость как ax + by + cz = -d. Поэтому при создании плоскости задается нормаль плоскости (a, b, c) и константа d.

    Самым распространенным использованием плоскости является плоскость усечения камеры. Поэтому основная цель Plane(плоскости) — определить, находится ли точка на положительной стороне, отрицательной или пересекающей плоскость.

    Плоскость определяет константы:

    • NEGATIVE_SIDE — Представляет собой точку на противоположной стороне, относительно точек нормали.
    • NO_SIDE — Представляет собой точку, которая лежит на самой плоскости.
    • POSITIVE_SIDE — Представляет собой точку на той стороне, относительно точек нормали.

    Эти значения возвращаются при вызове whichSide.

    Пример 1 — Определим, находится ли точка на положительной стороне плоскости

    Vector3f normal = new Vector3f(0,1,0);
    float constant = new Vector3f(1,1,1).dot(normal);
    Plane testPlane = new Plane(normal, constant);
    
    int side = testPlane.whichSide(new Vector3f(2,1,0);
    
    if(side == Plane.NO_SIDE) {
       System.out.println("This point lies on the plane");
    }
    

    Пример 2 — Для Непрофессионала

    Используя стандартный конструктор Plane(Vector3f normal, float constant), это то что вам нужно сделать, чтобы создать плоскость, а затем использовать его, чтобы проверить, на какой стороне плоскости находится точка.

    package test;
    
    import java.util.logging.Logger;
    
    import com.jme.math.*;
    
    /**
     *@author Nick Wiggill
     */
    
    public class TestPlanes
    {
      public static final Logger logger = Logger.getLogger(LevelGraphBuilder.class.getName());
    
      public static void main(String[] args) throws Exception
      {
        //***Контур.
        //Этот пример показывает, как построить изображение плоскости, используя
        //com.jme.math.Plane.
        //We will create a very simple, easily-imagined 3D plane. It will
        //be perpendicular to the x axis (it's facing). It's "centre" (if
        //such a thing exists in an infinite plane) will be positioned 1
        //unit along the positive x axis.
    
        //***Шаг 1.
        //The vector that represents the normal to the plane, in 3D space.
        //Imagine a vector coming out of the origin in this direction.
        //There is no displacement yet (see Step 2, below).
        Vector3f normal = new Vector3f(5f,0,0);
    
        //***Шаг 2.
        //This is our displacement vector. The plane remains facing in the
        //direction we've specified using the normal above, but now we are
        //are actually giving it a position other than the origin.
        //We will use this displacement to define the variable "constant"
        //needed to construct the plane. (see step 3)
        Vector3f displacement = Vector3f.UNIT_X;
        //or
        //Vector3f displacement = new Vector3f(1f, 0, 0);
    
        //***Шаг 3.
        //Here we generate the constant needed to define any plane. This
        //is semi-arcane, don't let it worry you. All you need to
        //do is use this same formula every time.
        float constant = displacement.dot(normal);
    
        //***Шаг 4.
        //Наконец, постройте плоскость, используя данные, которые вы собрали.
        Plane plane = new Plane(normal, constant);
    
        //***Некоторые тесты.
        logger.info("Plane info: "+plane.toString()); //Отслеживать информацию о нашей плоскости
    
        Vector3f p1  = new Vector3f(1.1f,0,0); //За плоскостью (дальше от начала, чем от плоскости)
        Vector3f p2  = new Vector3f(0.9f,0,0); //Перед плоскостью (ближе к началу, чем к плоскости)
        Vector3f p3  = new Vector3f(1f,0,0); //на плоскости
    
        logger.info("p1 position relative to plane is "+plane.whichSide(p1)); //outputs NEGATIVE
        logger.info("p2 position relative to plane is "+plane.whichSide(p2)); //outputs POSITIVE
        logger.info("p3 position relative to plane is "+plane.whichSide(p3)); //outputs NONE
      }
    }
    

    Ray(Луч)

    Смотрите Ray Javadoc

    Описание

    Ray(Луч) определяет линию, которая начинается в точке A и продолжается в направлении через B в бесконечность.

    Луч широко используется в jME для Picking. Луч льется из точки в экранном пространстве на сцену. Пересечения будут найдены и возвращены. Для создания луча задайте объекту две точки, где первая точка точка источник.

    Пример 1 — Создадим луч, отражающий положение камеры

    Ray ray = new Ray(cam.getLocation(), cam.getDirection());
    

    Rectangle(Прямоугольник)

    Смотрите Rectangle Javadoc

    Описание

    Прямоугольник определяется конечными плоскостями в трехмерном пространстве, которые задаются тремя точками (A, B, C). Эти три точки определяют треугольник с четвертой точкой, определяющей прямоугольник ((B + C) — A).

    Применение в jME

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

    Пример 1 — Создадим прямоугольник и получим точку в нём

    Vector3f v1 = new Vector3f(1,0,0);
    Vector3f v2 = new Vector3f(1,1,0);
    Vector3f v3 = new Vector3f(0,1,0);
    Rectangle r = new Rectangle(v1, v2, v3);
    Vector3f point = r.random();
    

    Triangle(Треугольник)

    Смотрите Triangle Javadoc

    Описание

    Треугольник — это трехсторонний многоугольник. Каждый треугольник имеет три стороны и три угла, некоторые из которых могут быть одинаковыми. Если один из углов треугольника прямой (равен 90°), то треугольник называется прямоугольным. Две стороны, образующие прямой угол, называются катетами, а сторона, противолежащая прямому углу, называется гипотенузой. Все треугольники являются выпуклыми и двуцентричными.

    Применение

    Класс jME Triangle — это простой класс данных. Он содержит три объекта Vector3f, которые представляют три точки треугольника. Их можно получить с помощью метода get. Метод get, получает точку на основе предоставленного индекса. Аналогично, значения могут быть установлены с помощью метода set.

    Пример 1 — Создадим треугольник

    //три точки, составляющие треугольник
    Vector3f p1 = new Vector3f(0,1,0);
    Vector3f p2 = new Vector3f(1,1,0);
    Vector3f p3 = new Vector3f(0,1,1);
    Triangle t = new Triangle(p1, p2, p3);
    

    Советы и приемы

    Как получить высоту/ширину пространства(spatial)?

    Используйте для spatial объекта com.jme3.bounding.BoundingBox, чтобы иметь возможность использовать getExtent ().

    Vector3f extent = ((BoundingBox) spatial.getWorldBound()).getExtent(new Vector3f());
    float x = ( (BoundingBox)spatial.getWorldBound()).getXExtent();
    float y = ( (BoundingBox)spatial.getWorldBound()).getYExtent();
    float z = ( (BoundingBox)spatial.getWorldBound()).getZExtent();
    

    Как расположить центр геометрии?

    geo.center().move(pos);
    

    Смотрите так же

    Переведено для jmonkeyengine.ru, оригинал.
    Автор перевода: Andry

    Добавить комментарий

    Содержание

    jMonkeyEngine.ru © 2017. Все права сохранены.