<
  • Главная
Статьи

Глава 7. Матричні перетворення

  1. зміст глави лінійні перетворення Афінний перетворення і вихід за їх межі Camera Transforms ...
  2. Матриці і перетворення
  3. Використання класу MatrixTransform3D (тривимірне матричне перетворення)
  4. двомірна аналогія
  5. Тривимірні однорідні координати

зміст глави
  • лінійні перетворення
  • Афінний перетворення і вихід за їх межі
  • Camera Transforms
  • У моєму описі перетворень в Главі 2 «Перетворення і анімація» і Главі 3 «Обертання, заданий віссю і кутом повороту» був опущений один з класів, похідний від Transform3D (тривимірне перетворення). Цим таємничим класом був MatrixTransform3D (тривимірне матричне перетворення). Цей клас має гнучкість, достатньою для здійснення стандартних перетворень переміщення, масштабування і повороту (і не тільки їх). Природно, у міру збільшення гнучкості, знижується простота використання. У цього класу є тільки одна властивість - Matrix (матриця) типу Matrix3D, що представляє собою структуру, що має 16 власних властивостей, доступних для читання і запису. У XAML можна задати значення цих властивостей або окремо, або описавши матрицю цілком одним рядком з 16 чисел.

    Якщо ви вважаєте, що для ваших потреб вам цілком достатньо стандартних перетворень переміщення, масштабування і повороту, то можна повністю уникнути застосування структури Matrix3D. Але розуміння її ролі в програмуванні тривимірної графіки відкриває шлях до ряду просунутих технік.

    Структура Matrix3D реалізує математичну сутність, якої приблизно в середині XIX століття англійським математиком Джеймсом Джозефом Сильвестром (1814-1897) було дано ім'я «матриця». Той факт, що графічні перетворення найчастіше виражаються у вигляді матриць, пояснюється тим, що матрична алгебра дозволяє легко оперувати такими перетвореннями. Наприклад, складові перетворення еквівалентні множення матриць, а зворотні перетворення - зверненням матриць. Припускаю, що, отримуючи освіту, ви вже зустрічалися з матрицями, але, на випадок якщо ви їх трохи забули, я приведу короткий огляд.

    Існують різні способи підрозділи перетворень на категорії. І в міру того, як ці категорії будуть нам зустрічатися, я дам їм визначення. У своїй розповіді про матрицях в цьому розділі я спершу сфокусується на лінійних перетвореннях, потім на афінних і, нарешті, на неаффінних. Якщо спочатку здасться, що я в своєму викладі щось опускаю, перебувайте в упевненості, що це буде розглянуто в свій час.

    В математиці функція називається лінійної, якщо для змінних і і константи справедливі наступні співвідношення:


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

    Отже, з математичної точки зору перетворення шляхом масштабування є лінійним. І перетворення шляхом повороту - лінійно. Інші види перетворень (наприклад, таке як зрушення або скіс) теж лінійні. Однак переміщення - в якомусь сенсі, найпростіше з усіх перетворень - не є лінійним. На щастя, ця невелика проблема тягне за собою рішення, що обіцяє і інші вигоди.

    Огляд матричної алгебри

    Матриця - це прямокутна таблиця чисел з фіксованою кількістю рядків і стовпців. Таблиця 3 × 4 має три рядки і чотири стовпці.

    Таблиця 3 × 4 має три рядки і чотири стовпці

    При записи матриці, таблиця чисел полягає в квадратні дужки (поряд з якими можуть використовуватися і круглі, а також подвійні вертикальні лінії). Нерідко для позначення матриць використовуються жирні великі літери латинського алфавіту (наприклад, A). Числа, що складають матрицю, називаються елементами матриці. Іноді кажуть, що матриця складається з ячейок. Окремо взятий елемент матриці записується з двома індексами, наприклад, де - номер рядка, а - номер стовпчика. Найчастіше ці індекси відраховуються від одиниці, а не від нуля. Наприклад, у вищенаведеній матриці, - це елемент, що знаходиться в лівому верхньому кутку, а - елемент в нижньому правому куті.

    Дві матриці можна складати або віднімати одну з іншої шляхом додавання або віднімання відповідних елементів (тобто поелементно). Можна помножити матрицю на скаляр (одне число) шляхом множення кожного елемента на цей скаляр.

    Більш цікавою операцією є множення двох матриць. Припустимо, що A і B - це дві матриці з елементами і, а матриця C з елементами - це їхній колективний витвір:

    A × B = C

    Твір визначено тільки в тому випадку, якщо число стовпців матриці А дорівнює числу рядків матриці В. При цьому матриця-твір C має стільки ж рядків, скільки у матриці A, і стільки ж стовпців, скільки у матриці B. А кожен елемент матриці C може бути розрахований за такою формулою (в якій - це число стовпців матриці A або рядків матриці B):

    А кожен елемент матриці C може бути розрахований за такою формулою (в якій - це число стовпців матриці A або рядків матриці B):

    Велика грецька буква «сигма» позначає підсумовування, де приймає значення від 1 до. Насправді, множити матриці на практиці набагато легше, ніж в теорії. Візьмемо такі три матриці:

    Візьмемо такі три матриці:

    Я вже заповнив елементи матриці-твори. Як бачите, кількість стовпців першої матриці (три) збігається з кількістю рядків другий матриці. Матриця-твір містить стільки ж рядків, скільки перша матриця (дві), і стільки ж стовпців, скільки друга (чотири).

    Почніть з першого рядка першої матриці, що містить числа 2, 3 і 4. Поверніть її в розумі так, щоб вона стала вертикальної. Поставте її поряд з першим стовпцем другуматриці (числа 1, 4 і 2). Перемножте відповідні числа і складіть результати: 2, помножене на 1, плюс 3, помножене на 4, плюс 4, помножене на 2, що дорівнює 22. Це число поміщається на перетині першого рядка та першого стовпчика матриці-результату. Продовжуйте виконувати описані операції, використовуючи перший рядок першої матриці і, послідовно, другий, третій і четвертий стовпчики другуматриці, щоб заповнити перший рядок матриці-результату. Тепер візьміть другий рядок першої матриці: числа 7, 5 і 3. Знову, поверніть її набік і перемножте з першим стовпцем другуматриці: 7, помножене на 1, плюс 5, помножене на 4, плюс 3, помножене на 2, що дорівнює 33 . Це - результат для першого стовпця другого рядка. Тепер продовжуйте поелементно множити другий рядок першої матриці на другий, третій і четвертий стовпчики другуматриці, щоб заповнити залишилися стовпці другого рядка матриці-результату.

    Взагалі, множення матриць некомутативними. Іншими словами, твір A × B не обов'язково одно B × A. Це очевидно з попереднього прикладу, тому що число стовпців першої матриці має дорівнювати числу рядків другої матриці, а це правило не буде виконуватися, якщо ми поміняємо матриці місцями. Але, навіть якщо б матриці були квадратними (тобто мали б однакову кількість рядків і стовпців), операція множення матриць, як правило, не буде комутативній. Проте, множення матриць асоціативно: в творі A × B × C байдуже, яке множення провести в першу чергу. Множення матриць також є дистрибутивним щодо складання:

    A × (B + C) = A × B + A × C

    Матриці і перетворення

    Точка в тривимірному просторі, що задається координатами, може бути представлена ​​у вигляді матриці 1 × 3:

    Точка в тривимірному просторі, що задається координатами, може бути представлена ​​у вигляді матриці 1 × 3:

    Лінійне перетворення може бути представлено у вигляді матриці 3 × 3:

    Лінійне перетворення може бути представлено у вигляді матриці 3 × 3:

    Я записав елементи цієї матриці, використовуючи імена властивостей, певних для структури Matrix3D, які зручно вказують на номер рядка і стовпця. Перетворення - це множення точки в просторі на матрицю 3 × 3.

    Перетворення - це множення точки в просторі на матрицю 3 × 3

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



    Можна сказати, що перетворення зіставляє точці точку.

    (Мушу зазначити, що в деяких книгах, присвячених комп'ютерній графіці, це множення матриць показано трохи по-іншому: рядки і стовпці матриці перетворення міняються місцями, що вимагає подання преобразуемой точки у вигляді матриці-стовпця 3 × 1, який поміщають праворуч від матриці перетворення при записі твору. І, хоча такий запис має деякі переваги, я буду дотримуватися правила, що випливає з імен властивостей структури Matrix3D).

    Перетворення, представлене цією матрицею 3 × 3, називається лінійним перетворенням, тому що в кожну формулу входять лише твори констант на координати точки,, і, і це задовольняє критеріям математичної лінійності. Я хочу, щоб у вас склалося хороше розуміння формул для обчислення нових координат (, і). Так, щоб, бачачи матрицю 3 × 3, ви розуміли, що її перший стовпець містить множники для обчислення координати, другий - для координати, а третій - для координати.

    Можна подивитися на це ще під одним кутом: припустимо, що - це не крапка, а вектор:. Три стовпці матриці перетворення теж можна уявити як вектори:, і. В цьому випадку, перетворені координати, і - це значення трьох скалярних творів вектора з трьома складовими матрицю векторами-стовпцями:



    Такий підхід до інтерпретації перетворень є вельми корисним.

    Використання класу MatrixTransform3D (тривимірне матричне перетворення)

    При створенні нового об'єкта типу MatrixTransform3D, його властивість Matrix містить створюваний за замовчуванням об'єкт типу Matrix3D, що виражає матрицю, значення, що лежать на головній діагоналі якої дорівнюють одиниці:

    При створенні нового об'єкта типу MatrixTransform3D, його властивість Matrix містить створюваний за замовчуванням об'єкт типу Matrix3D, що виражає матрицю, значення, що лежать на головній діагоналі якої дорівнюють одиниці:

    Ця матриця відома під назвою одиничної, і саме такий об'єкт створює конструктор без параметрів структури Matrix3D. Одинична матриця - це матриця, еквівалентна числу 1. Множення будь-якої матриці на одиничну не призводить ні до яких змін. Формули перетворення, пов'язані з одиничною матрицею, прості:



    Ви, напевно, знаєте, що у структури її конструктор за замовчуванням (конструктор без параметрів) завжди задає нульові значення для всіх полів цієї структури, тому може здатися трохи дивним, що результатом роботи конструктора без параметрів структури Matrix3D є одинична матриця, деякі властивості якої рівні 1. насправді, внутрішні значення всіх полів структури Matrix3D дорівнюють нулю, але властивості M11, M22 і M33, очевидно, додають одиницю до значень, що зберігаються в пов'язаних з цими властивостями полях.

    Елемент MatrixTransform3D можна використовувати там же, де ви використовуєте елементи TranslateTransform3D, ScaleTransform3D або RotateTransform3D. Нижче представлений приклад, в якому елемент Matrix3D поміщений в елемент, відповідний властивості MatrixTransform3D.Matrix:

<MatrixTransform3D> <MatrixTransform3D.Matrix> <Matrix3D M11 = "1" M12 = "0" M13 = "0" M21 = "0" M22 = "1" M23 = "0" M31 = "0" M32 = "0" M33 = "1" /> </MatrixTransform3D.Matrix> </ MatrixTransform3D>

У цій розмітці представлені властивості структури Matrix3D з їх заданими за замовчуванням значеннями, наочно розташованими у вигляді масиву. У наведеному далі вмісті файлу LinearTransformExperimenter.xaml можна знайти подібний елемент Matrix3D, з яким можна поекспериментувати.

<! - ============================================== ================ LinearTransformExperimenter.xaml (c) 2007 by Charles Petzold ======================== ====================================== -> <Page xmlns = "http: // schemas.microsoft.com/winfx/2006/xaml/presentation "xmlns: x =" http://schemas.microsoft.com/winfx/2006/xaml "WindowTitle =" Linear Transform Experimenter "Title =" Linear Transform Experimenter "> <DockPanel> <! - Scrollbars to view object from different sides. -> <ScrollBar Name = "horz" DockPanel.Dock = "Bottom" Orientation = "Horizontal" Minimum = "- 180" Maximum = "180" LargeChange = "10" SmallChange = "1" /> <ScrollBar Name = " vert "DockPanel.Dock =" Right "Orientation =" Vertical "Minimum =" - 180 "Maximum =" 180 "LargeChange =" 10 "SmallChange =" 1 "/> <Viewport3D> <ModelVisual3D> <ModelVisual3D.Content> <Model3DGroup > <GeometryModel3D> <GeometryModel3D.Geometry> <! - House: front, back, left roof, left, right roof, right, bottom. -> <MeshGeometry3D Positions = "0 1 1, -0.5 0.6 1, 0.5 0.6 1, -0.5 0 1, 0.5 0 1, 0 1 -1, 0.5 0.6 -1, -0.5 0.6 -1, 0.5 0 -1 , -0.5 0 -1, 0 1 -1, 0 1 1, -0.5 0.6 -1, -0.5 0.6 1, -0.5 0.6 -1, -0.5 0.6 1, -0.5 0 -1, -0.5 0 1, 0 1 1, 0 1 -1, 0.5 0.6 1, 0.5 0.6 -1, 0.5 0.6 1, 0.5 0.6 -1, 0.5 0 1 0.5 0 -1, 0.5 0 1, 0.5 0 -1, -0.5 0 1, -0.5 0 -1 "TriangleIndices =" 0 1 2, 1 3 2, 2 3 4, 5 6 7, 6 8 7, 7 8 9, 10 12 11, 11 12 13, 14 16 15, 15 16 17, 18 20 19 , 19 20 21, 22 24 23, 23 24 25, 26 28 27, 27 28 29 "/> </GeometryModel3D.Geometry> <GeometryModel3D.Material> <DiffuseMaterial Brush =" Cyan "/> </GeometryModel3D.Material> < GeometryModel3D.BackMaterial> <DiffuseMaterial Brush = "Red" /> </GeometryModel3D.BackMaterial> <! - Matrix transform. -> <GeometryModel3D.Transform> <MatrixTransform3D> <MatrixTransform3D.Matrix> <Matrix3D M11 = "1" M12 = "0" M13 = "0" M21 = "0" M22 = "1" M23 = "0" M31 = "0" M32 = "0" M33 = "1" /> </MatrixTransform3D.Matrix> </ MatrixTransform3D> </GeometryModel3D.Transform> </ GeometryModel3D> <! - Light sources. -> <AmbientLight Color = "# 404040" /> <DirectionalLight Color = "# C0C0C0" Direction = "2, -3 -1" /> </ Model3DGroup> </ModelVisual3D.Content> </ ModelVisual3D> <! - - Camera. -> <Viewport3D.Camera> <OrthographicCamera Position = "0 0 4" LookDirection = "0 0 -1" UpDirection = "0 1 0" Width = "4"> <OrthographicCamera.Transform> <Transform3DGroup> <RotateTransform3D> < RotateTransform3D.Rotation> <AxisAngleRotation3D Axis = "0 1 0" Angle = "{Binding ElementName = horz, Path = Value}" /> </RotateTransform3D.Rotation> </ RotateTransform3D> <RotateTransform3D> <RotateTransform3D.Rotation> <AxisAngleRotation3D Axis = "1 0 0" Angle = "{Binding ElementName = vert, Path = Value}" /> </RotateTransform3D.Rotation> </ RotateTransform3D> </ Transform3DGroup> </OrthographicCamera.Transform> </ OrthographicCamera> </ Viewport3D. Camera> </ Viewport3D> </ DockPanel> </ Page>

Що міститься в файлі код відображає простий тривимірний будиночок, розміщений на координатної площині XY. Ширина цього будиночка становить одну одиницю, висота - теж одну одиницю, глибина - дві одиниці, а осі X і Z обидві проходять під центром будиночка. Ортографічна камера (об'єкт OrthographicCamera) спрямована на фасад будинку так, що спершу видно тільки його торець, але, за допомогою двох смуг прокрутки, можна підібрати іншу, кращу, точку огляду.

Найбільш пізнавальним було б завантажити цей файл LinearTransformExperimenter.xaml в програму XamlCruncher або подібну їй і поекспериментувати з властивостями елемента Matrix3D. Три елемента, розташованих на діагоналі матриці, - M11, M22 і M33 - керують масштабуванням в напрямках X, Y і Z. Завдання значень для цих властивостей має такий же ефект, як і завдання значень для властивостей ScaleX, ScaleY і ScaleZ об'єкта ScaleTransform3D. Якщо встановити всі три ці властивості рівними 5, то будиночок збільшиться настільки, що камера виявиться всередині його, і ви побачите його внутрішню поверхню, забарвлену в червоний колір.

Також можна обертати фігуру навколо осей X, Y і Z. Поворот навколо осі Z потребує такої матриці перетворення:

Формули перетворення мають такий вигляд:



Ці формули подібні формулами для отримання окружності, з якими ми зустрічалися в попередньому розділі. Для повороту на 30 градусів навколо осі Z будуть потрібні наступні значення:

Для повороту на 30 градусів навколо осі Z будуть потрібні наступні значення:

І ось результат (якщо дивитися, трохи збоку):

І ось результат (якщо дивитися, трохи збоку):

Поворот навколо осі X виражається наступною матрицею:

Поворот навколо осі X виражається наступною матрицею:

Нарешті, обертання навколо осі Y задається так:

Нарешті, обертання навколо осі Y задається так:

Зверніть увагу, що в кожній з цих базових матриць повороту, координати, відповідні осі повороту, не зачіпаються. Наприклад, матриця, що задає поворот навколо осі Y, залишає незмінними всі значення.

Поворот навколо довільної осі - вектора - задається більш громіздко, але якщо таке питання у вас виник, то наведемо матрицю і для нього (для спрощення синтаксису дужки навколо операндів тригонометричних функцій опущені):

Майте на увазі, що значення, і в цій матриці є координатами вектора, що задає вісь обертання, а не обертається точки. Якщо задати для і нульові значення, а для - одиничне (що означає поворот навколо осі Z), то матриця спроститься і буде відповідати наведеній вище. Те ж саме відноситься і до інших базових одиничним векторам (ортам).

Поки ви ще не побачили нічого такого, чого б ви не змогли зробити за допомогою об'єктів ScaleTransform3D або RotateTransform3D, однак тільки об'єкт MatrixTransform3D може задавати перетворення зсуву (також званого скосом). В процесі цього перетворення, прямі кути стають гострими або тупими. Наприклад, спробуйте використовувати наступну матрицю:

Це - практично одинична матриця. Єдина відмінність - в ще одному рівному одиниці елементі. Так що формула для набуває вигляду:

Для точок, що знаходяться вище площини XZ, у міру зростання висоти над площиною, значення координати x зростають (точки зміщуються в бік позитивного напрямку осі X). У той же час точки, що знаходяться нижче цієї площини, зміщуються в бік негативного напрямку осі X внаслідок зменшення значення координати x в міру збільшення відстані до площини XZ. Будиночок нахиляється:

Можна зрушувати будиночок в самих різних напрямках, задаючи відмінні від нуля значення для нульових елементів матриці. Ось, наприклад, такий варіант:

Ось, наприклад, такий варіант:

Значення залишені незміненими, а значення і зміщуються в залежності від значення:


Наприклад, для безлічі точок, у яких координата дорівнює 1 (що відповідають площині, що проходить через фасад будиночка), формули перетворення візьмуть вигляд:


І ось як це виглядає:

І ось як це виглядає:

Постарайтеся на якийсь час зберегти в пам'яті це зображення. Незабаром воно може виявитися корисним.

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

Проблема полягає в тому, що матриця 3 × 3 висловлює лінійне перетворення в тривимірному просторі, а переміщення - це просто нелінійна функція. Наприклад, уявіть точки і, які можуть бути також виражені векторами і, що виходять з початку координат. (Я переходжу до векторів, щоб надати сенс арифметичних операцій). Складіть ці два вектори, отримавши в результаті вектор, і перемістіть його на одну одиницю по осі X: вийде. А тепер спершу зробіть переміщення, отримавши в результаті вектори і, а потім складіть їх. Сума буде дорівнює, що відрізняється від першого результату, наочно показуючи, що переміщення не є лінійною функцією або лінійним перетворенням.

Перетворення масштабування, повороту и Зсув всегда віробляються пропорційно по відношенню до віхідної фігурі. Неважливо, наскільки велика або мала фігура, - якщо вона масштабується з коефіцієнтом 2, вона завжди подвоюється в розмірах. Інакше кажучи, координати точок фігури в процесі перетворення множаться на деякий постійний коефіцієнт. Однак переміщення математично проводиться інакше. Воно засноване на складання, а не на збільшенні. І тому в його основі лежать реальні одиниці виміру, а не безрозмірні коефіцієнти.

Чи є спосіб включити переміщення в зручну матрицю, розроблену нами для інших типів перетворення?

Так, це завдання має рішення, але воно не є інтуїтивно зрозумілим. І, навіть якщо ви знаєте, як це робиться, логіка, що стоїть за цим способам, може виявитися незнайомій вам.

Той тип перетворень, до якого відносяться переміщення, масштабування, поворот і зрушення, відомий під ім'ям афінних перетворень. Слово «афінний» походить від латинського «affinis», що означає «споріднений», але в математиці воно зазвичай відноситься до чого-небудь, що залишається кінцевим, тобто конкретно визначеним. Це означає, що Афінний перетворення ніколи не перетворює точку, мають кінцеві координати в тривимірному просторі, в точку, у якій хоча б одна координата стала б дорівнює нескінченності. Звичайно, це дуже широке визначення, тому якщо говорити конкретно про перетвореннях, то аффіннимі серед них, в основному, є всі лінійні перетворення, а також, на додаток до них, перетворення переміщення.

Пошук способу вираження афінних перетворень в тривимірному просторі матричному вигляді буде істотно полегшений, якщо ми повернемося в відносний комфорт двомірного простору.

двомірна аналогія

У двох вимірах (тобто на площині) лінійні перетворення можуть бути представлені матрицею 2 × 2:

У двох вимірах (тобто на площині) лінійні перетворення можуть бути представлені матрицею 2 × 2:

Формули перетворення мають такий вигляд:


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

TwoDimensionalHouse.xaml

На другому зображенні масштаб будиночка збільшений на 50% в напрямку осі Y, а третє зображення представляє цей будиночок поверненим на 45 градусів за годинниковою стрілкою навколо початку координат. Але переміщення неможливо здійснити за допомогою матриці 2 × 2.

Цей двомірний будиночок фактично ідентичний передній грані (фасаду) тривимірного будиночка, відображається кодом з файлу LinearTransformExperimenter.xaml. Єдина відмінність полягає в тому, що всі координати збільшені в 100 разів, оскільки такі величини краще підходять для двомірної системи координат WPF, що базується на вирішенні 96 одиниць на 1 дюйм.

Досить цікаво, але ви вже бачили приклад переміщення двомірного будиночка. Фасад того тривимірного будиночка, який ми розглядали раніше в цьому розділі, і є цим двомірним будиночком. В останньому показаному мною прикладі зсуву, перетворення переміщує фасад будиночка в сторону від початку координат, але, при цьому, не вносить жодних спотворень в містить цей фасад площину:

В останньому показаному мною прикладі зсуву, перетворення переміщує фасад будиночка в сторону від початку координат, але, при цьому, не вносить жодних спотворень в містить цей фасад площину:

Площина фасаду цього тривимірного будиночка, що має координату Z рівну одиниці, таким чином фактично переміщується в бік від початку координат на відстань, що визначається коефіцієнтами зсуву, заданими в якості елементів M31 і M32 матриці перетворення:

Площина фасаду цього тривимірного будиночка, що має координату Z рівну одиниці, таким чином фактично переміщується в бік від початку координат на відстань, що визначається коефіцієнтами зсуву, заданими в якості елементів M31 і M32 матриці перетворення:

З цієї матриці слідують такі формули перетворення:



Але, якщо нас цікавить тільки площину, у якій координата дорівнює 1, то формули перетворення скоротяться до формул переміщення по і:


Це серйозне відкриття: тривимірний зрушення, що задається елементами M31 і M32 матриці перетворення, фактично переміщує двомірні об'єкти по площині, координата z якої дорівнює 1. Це - ключ до застосування перетворення переміщення в двомірної графіки. Завжди, коли ми малюємо на площині, ми можемо фактично уявити це як малювання в тривимірному просторі. Концептуально це виглядає як зображення двомірних фігур на площині, розташованої в тривимірному просторі, причому такій площині, що координати z всіх точок, що утворюють цю площину, були б рівні 1. На наступному малюнку ця площину показана у вигляді сірої напівпрозорої поверхні:

2Don3D.xaml

Оскільки тепер ми малюємо в тривимірному просторі, замість оперування точками з двомірними координатами, ми фактично повинні задавати точки з тривимірними координатами. Чи не заплутатися: ми як і раніше малюємо плоскі фігури на плоскій поверхні. Три координати точок в даному випадку несуть ту ж інформацію, що і дві координатами. Але зате тепер ми можемо застосовувати тривимірне перетворення зсуву для переміщення фігур по цій площині:

Але зате тепер ми можемо застосовувати тривимірне перетворення зсуву для переміщення фігур по цій площині:

Звичайно, на практиці мова не йде про те, щоб насправді використовувати тривимірний простір для малювання плоских фігур. Цей повністю уявний процес. Все, що потрібно на саме справі, - це розширені можливості перетворення. Думаю, ніхто не здивується, дізнавшись, що звичайна структура Matrix, певна в просторі імен System.Windows.Media, яка обслуговує двомірну графіку в WPF, фактично реалізує матрицю 3 × 3 і має наступні властивості:

Media, яка обслуговує двомірну графіку в WPF, фактично реалізує матрицю 3 × 3 і має наступні властивості:

Концептуально, для цілей множення матриць, всі крапки з координатами представляються у вигляді:

Концептуально, для цілей множення матриць, всі крапки з координатами представляються у вигляді:

Формули перетворення мають вигляд:


Підіб'ємо підсумки: щоб задіяти перетворення переміщення в двомірної графіку, необхідно використовувати матрицю лінійних перетворень для тривимірного простору. Цей прийом стане очевидним, як тільки ви усвідомлюєте, що тривимірний зрушення в напрямку X і Y еквівалентний двовимірним переміщенню на площині, паралельної (але не рівний) координатної площини XY. Щоб спростити обчислення, як такій площині зазвичай вибирають ту, для якої координата дорівнює 1, а все, що належать їй точки мають координати виду. Безліч двомірних перетворень, які стає можливим описати за допомогою цієї збільшеної матриці, відоме під назвою «афінних перетворень» і є розширенням безлічі лінійних перетворень.

Що можна сказати про третьому стовпці цієї матриці 3 × 3? При використанні подібної матриці лінійних перетворень третього порядку в світі тривимірних координат цей стовпець застосовується при масштабуванні в напрямку осі Z або ж при обертанні навколо чого-небудь за винятком осі Z. Але в двомірної графіку цей стовпець, здається, не несе ніякої корисної навантаження.

Насправді, двомірна графічна система WPF не дасть вам можливості працювати з елементами третього стовпця об'єкта Matrix. Але теоретично, ви можете думати про це стовпці як про додаткові, свого роду «бонусних», осередках. І, якби ви могли задавати цим елементам будь-які інші значення, відмінні від заданих за замовчуванням 0, 0 і 1, то таким чином ви б змогли описати перетворення, яке було б не тільки нелінійним, але також і неаффінним.

Давайте на мить уявімо, що у нас є можливість задавати значення елементів третього стовпчика матриці і що двомірне перетворення насправді виглядає так:

В цьому випадку формули перетворення візьмуть вигляд:



Якщо значення в третьому стовпці матриці не рівні 0, 0 і 1 відповідно, то в результаті перетворення точка піде за межі площини, в якій координата дорівнює 1. А оскільки в цьому прикладі ми все ще продовжуємо працювати з двомірної графікою, нам доведеться якось повернути перетворену точку назад на площину. Нам треба знайти спосіб змінить значення, і так, щоб координата Z знову стала дорівнює 1, і фігура розмістилася б на площині.

Найпростішим рішенням буде поділити все три координати на:

Тепер ми знову маємо точку на площині, у якій координата дорівнює 1. Однак ми привнесли можливість вельми небезпечного результату: поділ, застосоване в цій операції, цілком може виявитися розподілом на нуль. Це означає, що в результаті перетворення координата точки може стати рівною нескінченності. Саме можливість отримати в результаті нескінченність робить це перетворення неаффінним. Адже за визначенням, аффінниє перетворення - це ті, в результаті яких координати не звертаються в нескінченність.

Цей конкретний вид неаффінних перетворень, який я тут описую, іноді називають конусним перетворенням, оскільки воно не зберігає паралельність ліній і, замість цього, звужує фігуру з одного боку і розширює з іншого. Наприклад, розглянемо наступну двомірну матрицю неаффінного перетворення:

Значення елемента M13 рівне -0,01 представляється незначним, але воно має великий вплив на двомірну графіку в системі координат, заснованої на вирішенні 96 одиниць на дюйм. Формули перетворення виглядають так:



Точка переходить в наступну точку:

Точка переходить в наступну точку:

Коли дорівнює 100, знаменник дробу звертається в нуль, а координата стає рівною нескінченності. На щастя, значення абсцис точок маленького двовимірного будиночка обмежені інтервалом від -50 до 50, тобто знаменник приймає значення від 1,5 до 0,5. Ось як виглядає перетворена версія будиночка:

TaperTransformedHouse.xaml

Частина фігури, розташована правіше початку координат стала більше, так як збільшилися значення координат складових її точок, в той час як частина фігури, розташована зліва від початку координат, з тієї ж причини стала менше. Якщо це хоч якось нагадує ефект перспективи, то ви, звичайно, вже припускаєте, як можна використовувати цю схожість.

Коли ви створюєте уявлення для точки з двомірними координатами (x; y) за допомогою додаткової третьої координати, ви використовуєте концепцію однорідних координат, розроблену німецьким математиком Августом Фердинандом Мебіусом (1790-1868), найбільш відомим сьогодні в зв'язку з топологічним парадоксом, званому петля Мьобіуса . У тривимірному просторі однорідні координати корисні не тільки для вираження переміщень, але також відіграють важливу роль в описі перспективи.

Тривимірні однорідні координати

Далі буде...

переклад: Андрій Мурзін

Чи є спосіб включити переміщення в зручну матрицю, розроблену нами для інших типів перетворення?
Що можна сказати про третьому стовпці цієї матриці 3 × 3?


Новости
  • Виртуальный хостинг

    Виртуальный хостинг. Возможности сервера распределяются в равной мере между всеми... 
    Читать полностью

  • Редизайн сайта

    Редизайн сайта – это полное либо частичное обновление дизайна существующего сайта.... 
    Читать полностью

  • Консалтинг, услуги контент-менеджера

    Сопровождение любых интернет ресурсов;- Знание HTML и CSS- Поиск и обновление контента;-... 
    Читать полностью

  • Трафик из соцсетей

    Сравнительно дешевый способ по сравнению с поисковым и контекстным видами раскрутки... 
    Читать полностью

  • Поисковая оптимизация

    Поисковая оптимизация (англ. search engine optimization, SEO) — поднятие позиций сайта в результатах... 
    Читать полностью