7
июля
1

Mатематические кривые в 3D

Мне стало интересно посмотреть на математические кривые в 3-х мерном пространстве. Для этого я начал разбираться с Matrix3D и прочей трехмерной оснасткой в action script. Получилась вот такая штуковина:

Все последующие изображения генерятся автоматически на основе рандомных параметров. Для того чтобы сбросить и начать сначала кликните на изображении. При движении мышкой меняется ракурс (если кто не понял… :)).

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

Идеологически понятно, как решать этот вопрос, но вот как конкретно в деталях это делается я не знал. Поиски привели меня на мой любимый wonderfl.net, и вот этот, невероятный, офигенный, трехмерный мегафеерверк дал мне ответы на все мои вопросы.

Итак, несколько слов об алгоритме. Во-первых, флеш «умеет» рисовать только в двумерном пространстве. Трехмерное api позволяет потом повернуть нарисованный примитив в трехмерном пространстве. Увы, все примеры в справочном руководстве по as3 посвящены только разбору этого варианта. Соответственно в лоб задача не решается.

А решается она традиционным путем. Сначала нужно построить кривую в трехмерном пространстве, т.е. получить массив точек, описывающих кривую, затем спроецировать ее на плоскость, и уже используя массив двумерных координат нарисовать кривую с помощью drawPath.

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

Само преобразование трехмерных координат в двумерные производится с помощью Utils3D.projectVectors:

Utils3D.projectVectors (projectionMatrix, curveVertices, ProjectedCurveVertices, uvts);

В качестве аргументов скармливаем ей матрицу трансформации projectionMatrix, массив трехмерных координат curveVertices и массив ProjectedCurveVertices, который функция заполнит двумерными координатами, четвертый параметр uvts - массив координат для маппинга текстур, в данном случае я никак не использовал.

Матрица трансформации, в свою очередь создается с использованием PerspectiveProjections.

1
2
3
4
5
6
7
8
private function setupProjectionMatrix():void
{
perspective.fieldOfView = 75;
projectionMatrix.identity();
projectionMatrix.appendRotation(viewRotationY, Vector3D.Y_AXIS);
projectionMatrix.appendRotation(viewRotationX, Vector3D.X_AXIS);
projectionMatrix.appendTranslation(0, 0, perspective.focalLength);
projectionMatrix.append(perspective.toMatrix3D());

correctMatrix3DMultiplyBug(projectionMatrix);

Utils3D.projectVectors(projectionMatrix, curveVertices, ProjectedCurveVertices, uvts);
}

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

1
2
3
4
5
6
7
8
9
10
11
12
private function correctMatrix3DMultiplyBug(matrix:Matrix3D):void
{
// see http://bugs.adobe.com/jira/browse/FP-670
var m1:Matrix3D = new Matrix3D(Vector.([ 0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 1, 0 ]));
var m2:Matrix3D = new Matrix3D(Vector.([ 0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 1,  0, 0, 0, 0 ]));
m1.append(m2);
if (m1.rawData[15] == 20) {
var rawData:Vector. = matrix.rawData;
rawData[15] /= 20;
matrix.rawData = rawData;
}
}

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

1
2
3
var mult:uint = 0x6f;
displayBuffer.merge(backBmd, displayBuffer.rect, new Point(0,0), mult, mult, mult, mult);
displayBuffer.applyFilter(displayBuffer, displayBuffer.rect, new Point(0,0), blur);

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

Вот такие чудеса. Для любителей экспериментов:
Исходники Математических кривых в 3D. (Flash CS4)

UPDATE

Усовершенствованная версия мат. кривых в 3D с эффектом DOF.

Enjoyed reading this post?
Subscribe to the RSS feed and have all new posts delivered straight to you.
1 Comment:
  1. admin 3 Янв, 2010

    Деян, привет. Я поправил ссылку. Скачивайте на здоровье!

Post your comment



Celadon theme by the Themes Boutique