Страницы

Saturday, 28 May 2011

Руководство по Image_3D: Пользовательские формы и поверхности (часть 7 из 13)

Перевод седьмой части руководства по PEAR пакету Image_3D, оригинал http://www.ibm.com/developerworks/opensource/tutorials/os-php-3d/section7.html

Пользовательские формы и поверхности

Существуют два объекта, которые позволяют создавать больше пользовательских объектов в Image_3D: полигоны и карты.

Создание полигонов

Предположим, что вы можете наметить 3D форму с помощью многомерных координат, вы можете поместить эти координаты вместе, чтобы построить стороны 3D объекта. Проделав некоторые тщательные расчеты, используя точки и полигоны, можно построить кубы, конусы или сферы с нуля. Но существуют простые методы для создания этих объектов.

Вместо этого, давайте построим трехконечную звезду, которая имеет третье измерение: глубина. Звезда должна иметь переднюю и заднюю поверхности, которые будут иметь одинаковые координаты точек, определяющие внешние края. Необходимо шесть точек - три точки для передней часть и три для задней. Чтобы это было проще сделать, передняя часть будет иметь точки, которые лежат в координате Z=0. Обратная сторона будет постоянным расстоянием, 60, от лицевой стороны. Таким образом, все внешние точки будут иметь одинаковые координаты X и Y, а Z координата будет изменена на 60.

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

Большинство работы в листинге 9 это наложение точек, которые должны быть подключены к созданию этого объекта. Циклы foreach, которые следуют после этого используются для создания объектов Image_3D_Point, которые в свою очередь используется для создания окончательного объекта.

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

Листинг 9. Создание трехконечной звезды
$polygons = array();

// Передняя поверхность
$polygons[] = array(
                array(0, -120, 0), array(-18, -12, 0), 
                array(-86, 48, 0), array(0, 18, 0), 
                array(86, 48, 0),  array(18, -12, 0)
              );

// Задняя поверхность
$polygons[] = array(
                array(0, -120, 60), array(-18, -12, 60), 
                array(-86, 48, 60), array(0, 18, 60), 
                array(86, 48, 60),  array(18, -12, 60)
              );

// Три боковые стороны
$polygons[] = array(
                array(0, -120, 0),  array(-18, -12, 0), 
                array(-86, 48, 0),  array(-86, 48, 60), 
                array(-18, -12, 60),array(0, -120, 60)
              );
$polygons[] = array(
                array(-86, 48, 0), array(0, 18, 0), 
                array(86, 48, 0),  array(86, 48, 60), 
                array(0, 18, 60),  array(-86, 48, 60)
              );
$polygons[] = array(
                array(86, 48, 0),  array(18, -12, 0), 
                array(0, -120, 0), array(0, -120, 60), 
                array(18, -12, 60),array(86, 48, 60)
              );

foreach ($polygons as $poly) {
    $points = array();
    foreach ($poly as $set) {
        $points[] = new Image_3D_Point($set[0], $set[1], $set[2]);
    }
    $p = $world->createObject('polygon', $points);
    $p->setColor(new Image_3D_Color(255, 255, 255));
}

$world->transform($world->createMatrix('Rotation', array(0, -25, -15)));
Рисунок 12. Пользовательская полиграмма созданная с помощью пакета Image_3D


Наложение 3D поверхностей

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

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

Геликоид

Первый из этих двух листингов будет создавать то, что, как представляется, спиралный пандус. Каждая точка на поверхности имеет координаты X, Y и Z, которые складываются из следующей параметрической функции:

f[s,t] = {s * cos(2 ? t), s* sin(2 ? t), t}

Для создания этой поверхности, вы будете создавать новую "карту" объекта в пространстве.
$map = $world->createObject('map');
Для создания 3D поверхности карта принимает массив объектов Image_3D_Point, как вы видели в пользовательских полигонах выше. Каждая из этих точек может быть определена в соответствии с выше упомянутой функцией:
new Image_3D_Point( ($s * cos(2 * pi() * $t)), 
  ($s * sin(2 * pi() * $t)), 
  ($t) );
Вы будете изменять параметры s и t в интервалах 0-1 и 0-6, соответственно. Чтобы придать поверхности подходящий размер, вы умножите каждую координату на произвольное значение присвоенное $scale.

Листинг 10 демонстрирует создание объекта карты, и, как и другие примеры, вы будете устанавливать цвет, угол поворота и положение окончательного объекта.

Листинг 10. Геликоидальная параметризованная поверхность
$map = $world->createObject('map');

$scale  = 120;
$detail = 30;
$levels = 6;
$increment  = 1 / $detail;

for ($s = 0; $s <= 1; $s += $increment) {
        $row = array();
        for ($t = 0; $t <= $levels; $t += $increment) {
             $row[] = new Image_3D_Point( 
                          $scale * ($s * cos(2 * pi() * $t)),   // x
                          $scale * ($s * sin(2 * pi() * $t)),   // y
                          $scale * ($t)                         // z
                        );
        }
        $map->addRow($row);
}

$map->setColor(new Image_3D_Color(255, 255, 255));
$map->transform($world->createMatrix('Rotation', array(-50, 0, 15)));
$map->transform($world->createMatrix('Move', array(50, -220, 0)));

На рисунке 13 показано результирующее изображение. Уровнем детализации, масштабом и высотой геликоида можно манипулировать с помощью переменных $scale, $detail и $levels, соответственно.

Рисунок 13. Созданный геликоид с помощью объекта карты пакета Image_3D


Форма для выпечки кексов

Ваша вторая поверхность это интеграл с применением теоремы Стокса, получается довольно таки интересный результат. Вы могли бы описать поверхность как произведение синусоидальной волны, различной высоты, Z, расходящаяся радиусами во всех направлениях от начала координат плоскости X и Y.
Говоря, в непрофессиональной манере, что тор может быть описан как бублик, вы можете думать, что это выглядит как форма для выпечки кексов.

Эта поверхность будет описана в соответствии со следующей параметрической функцией:

f[r,t] = {r * cos(t), r * sin(t), sin(4 ? r)}

Опять же, чтобы добавить в карту объекта, вы будете наносить точки для этой поверхности. Каждая точка определяется в листинге 11.

Листинг 11. Определение точек
new Image_3D_Point( ($r * cos($t)), 
                    ($r * sin($t)), 
                    (sin(4 * pi() * $r)) 
                  );
Для получения гладкой поверхности, вы обернете каждую точку внутри двух циклов, которые изменяют параметры r и t. Каждая координата X, Y и Z будет умножена на значение $scale, как показано в листинге 12.

Листинг 12. 3D форма для выпечки кексов
$map = $world->createObject('map');

$scale  = 130;
$detail = 35;
$increment  = 1 / $detail;

for ($r = 0; $r <= 1; $r += $increment) {
    $row = array();
    for ($t = 0; $t <= (2 * pi()); $t += $increment) {
         $row[] = new Image_3D_Point( $scale * ($r * cos($t)), 
                                       $scale * ($r * sin($t)), 
                                       $scale * (sin(4 * pi() * $r)) 
                                      );
    }
    $map->addRow($row);
}

$map->setColor(new Image_3D_Color(255, 255, 255));
$map->transform($world->createMatrix('Rotation', array(-45, 0, -15)));
Рисунок 14. 3D поверхность, воссозданная от параметрической функции построенной с использованием объекта карты из пакета Image_3D


Другие части перевода

Перед началом работы (часть 1 из 13)
Расположение в пространстве (часть 2 из 13)
Создание вашего первого мира (часть 3 из 13)
Источники света и цвета (часть 4 из 13)
Изменение объектов и форм (часть 5 из 13)
Дополнительные объекты (часть 6 из 13)
Пользовательские формы и поверхности (часть 7 из 13)
Дополнительные драйверы вывода (часть 8 из 13)
Возвращение к практическим примерам (часть 9 из 13)
Суммарно (часть 10 из 13)
Скачать (часть 11 из 13)
Ресурсы (часть 12 из 13)
Об авторе (часть 13 из 13)

Автор перевода: reket.

No comments:

Post a comment