КАТЕГОРИИ: Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748) |
Проекции. Геометрическая операция проектирования (проецирования) выполняет отображение объектов на картинной плоскости
Геометрическая операция проектирования (проецирования) выполняет отображение объектов на картинной плоскости. При этом через каждую точку объекта проводятся прямые, начинающиеся в некотором центре. Точки пересечения этих прямых с плоскостью изображения образуют проекцию. Различают проектирование параллельное и центральное. При центральном проектировании все прямые исходят из одной точки - центра пучка. К центральным относятся перспективные проекции (прямая - обычная и обратная - иконы). При параллельном проектировании центр пуч- ка находится в бесконечности. Каждый из двух основных классов разбивается на несколько под- классов в зависимости от взаимного расположе- ния картинной плоскости и координатных осей.
КЛАССИФИКАЦИЯ ПРОЕКЦИЙ
z z При ортографической проекции картинная плос- кость совпадает с одной из координатных плос- y костей или параллельна ей. Матрица проектиро- x x y вания вдоль оси х на плоскость yz имеет вид: . Если плоскость проектирования параллельна координатной плоскости, матрица умножается на матрицу сдвига: . Матрицы для других осей координат: ; . При аксонометрической проекции проектирующие прямые перпендикулярны плоскости отображения. Аксонометрия - от греческого axon - ось + метрия - изображение. Предмет вместе со связанной с ним системой координат проектируется на некоторую плоскость. В соответствии с взаимным расположением плоскости проектирования и координатных осей различают проекции: · триметрию (плоскость находится относительно осей координат под различными углами для каждой оси) - используется редко; · диметрию (два из трех углов между осями и плоскостью равны, т.е. две оси одинаково сокращены); · изометрию (все углы равны, т.е. масштаб по всем осям одинаков).
Каждая из этих проекций получается комбинацией поворотов, после чего следует параллельное (ортографическое) проекти- рование. Можно вывести соответствующие матрицы, некото- рые подходы обозначены в [ 1 ].
Изометрия Диметрия
Косоугольные проекции используют пучок прямых, не перпендикулярных плоскости отображения. Выделяют два вида косоугольных проекций: · свободную (угол наклона проектирующих прямых к плоскости отображения равен ); · кабинетную (частный случай свободной, масштаб по третьей оси в 2 раза меньше). Все это также представимо в матричном виде. Так, при проектировании на плоскость xy точки с координатами x=0, y=0, z=1 имеем . Вид матрицы:. Для свободной проекции . Для кабинетной проекции . Перспективные (центральные) проекции более сложны. Они получаются путем перспективного преобразования и проектирования на некоторую плоскость наблюдения. Вводятся параметры, описывающие центр проектирования, т.е. точку, откуда "смотрят" на объект. Пусть эта точка имеет координаты . Тогда матрица перспективного преобразования в пространстве имеет вид: . Выкладки получения приведены в [ 1,8 ]. Член матрицы, характеризующий местоположение центра проектирования, выводится из уравнения прямой, проведенной из центра проектирования в некоторую точку объекта. Если мы хотим, например, плоскость наблюдения совместить с плоскостью xy, матрица примет вид: . Нулевое значение в третьем столбце третьей строки отражает факт . В общем случае при нахождении центра проектирования на осях z или y или x матрицы преобразования будут иметь соответственно вид: , , . Это матрицы одноточечных преобразований. Пример - преобразование единичного куба, центр проектирования лежит на оси z.
Если 2 элемента в четвертом столбце матрицы ненулевые (последнюю строку 0 0 0 1 не считаем), получается двухточечная или угловая перспектива, 3 элемента ненулевые - трехточечная или косая перспектива. Углы наклона определяются координатами центра проектирования. Для 2- и 3-точечных проекций оси координат системы не параллельны плоскости отображения.
C` G` I` 2-x точечная перспектива D` G` 3-x точечная перспектива I`
Для произвольного центра проектирования с координатами матрица преобразования: . Из школьного курса черчения и курса начертательной геометрии известно, что по нескольким проекциям можно восстановить изображение. Для компьютерной графики это соответствует обратным матричным преобразованиям. Т.к. для восстановления изображения используются несколько проекций, преобразования весьма сложны и длительны. Этим объясняется высокая ресурсоемкость подобных задач. Как все это реализовать (запрограммировать)? Здесь удобно использовать объектно-ориентированный подход. Фактически, мы работаем с векторами, т.к. координаты точки - 3 числа. Для класса ВЕКТОР (vector) можно определить систему операций (например, поэлементное сложение и вычитание векторов и т.д.). Определяются также основные функции. Аналогично вводится класс МАТРИЦА (matrix). Примеры программ [ 1 ]: #include <math.h> #include "Matrix.h"
Matrix:: Matrix (double v) { for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) x [i][j] = (i == j)? v: 0.0; x [3][3] = 1; }
void Matrix:: Invert () { Matrix Out (1); for (int i = 0; i < 4; i++) { double d = x [i][i]; if (d!= 1.0) { for (int j = 0; j < 4; j++) { Out.x [i][j] /= d; x [i][j] /= d; } } for (int j = 0; j < 4; j++) { if (j!= i) { if (x [j][i]!= 0.0) { double mulby = x[j][i]; for (int k = 0; k < 4; k++) { x [j][k] -= mulby * x [i][k]; Out.x [j][k] -= mulby * Out.x [i][k]; } } } } } *this = Out; }
void Matrix:: Transpose () { double t; for (int i = 0; i < 4; i++) for (int j = i; j < 4; j++) if (i!= j) { t = x [i][j]; x [i][j] = x [j][i]; x [j][i] = t; } }
Matrix& Matrix:: operator += (const Matrix& A) { for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) x [i][j] += A.x [i][j]; return *this; }
Matrix& Matrix:: operator -= (const Matrix& A) { for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) x [i][j] -= A.x [i][j]; return *this; }
Matrix& Matrix:: operator *= (double v) { for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) x [i][j] *= v; return *this; }
Matrix& Matrix:: operator *= (const Matrix& A) { Matrix res = *this; for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) { double sum = 0; for (int k = 0; k < 4; k++) sum += res.x [i][k] * A.x [k][j]; x [i][j] = sum; } return *this; }
Matrix operator + (const Matrix& A, const Matrix& B) { Matrix res; for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) res.x [i][j] = A.x [i][j] + B.x [i][j]; return res; }
Matrix operator - (const Matrix& A, const Matrix& B) { Matrix res; for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) res.x [i][j] = A.x [i][j] - B.x [i][j]; return res; }
Matrix operator * (const Matrix& A, const Matrix& B) { Matrix res; for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) { double sum = 0; for (int k = 0; k < 4; k++) sum += A.x [i][k] * B.x [k][j]; res.x [i][j] = sum; } return res; }
Matrix operator * (const Matrix& A, double v) { Matrix res; for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) res.x [i][j] = A.x [i][j] * v; return res; }
Vector operator * (const Matrix& M, const Vector& v) { Vector res; res.x = v.x * M.x[0][0] + v.y * M.x[1][0] + v.z * M.x[2][0] + M.x[3][0]; res.y = v.x * M.x[0][1] + v.y * M.x[1][1] + v.z * M.x[2][1] + M.x[3][1]; res.z = v.x * M.x[0][2] + v.y * M.x[1][2] + v.z * M.x[2][2] + M.x[3][2]; double denom = v.x * M.x[0][3] + v.y * M.x[1][3] + v.z * M.x[2][3] + M.x[3][3]; if (denom!= 1.0) res /= denom; return res; }
//////////////////////// Derived classes /////////////////////////////
Matrix Translate (const Vector& Loc) { Matrix res (1); res.x [3][0] = Loc.x; res.x [3][1] = Loc.y; res.x [3][2] = Loc.z; return res; }
Matrix Scale (const Vector& v) { Matrix res (1); res.x [0][0] = v.x; res.x [1][1] = v.y; res.x [2][2] = v.z; return res; }
Matrix RotateX (double Angle) { Matrix res (1); double Cosine = cos (Angle); double Sine = sin (Angle); res.x [1][1] = Cosine; res.x [2][1] = -Sine; res.x [1][2] = Sine; res.x [2][2] = Cosine; return res; }
Matrix RotateY (double Angle) { Matrix res (1); double Cosine = cos (Angle); double Sine = sin (Angle); res.x [0][0] = Cosine; res.x [2][0] = -Sine; res.x [0][2] = Sine; res.x [2][2] = Cosine; return res; }
Matrix RotateZ (double Angle) { Matrix res (1); double Cosine = cos (Angle); double Sine = sin (Angle); res.x [0][0] = Cosine; res.x [1][0] = -Sine; res.x [0][1] = Sine; res.x [1][1] = Cosine; return res; }
Matrix Rotation (const Vector& axis, double angle) { Matrix res (1); double Cosine = cos (angle); double Sine = sin (angle); res.x [0][0] = axis.x * axis.x + (1 - axis.x * axis.x) * Cosine; res.x [0][1] = axis.x * axis.y * (1 - Cosine) + axis.z * Sine; res.x [0][2] = axis.x * axis.z * (1 - Cosine) - axis.y * Sine; res.x [0][3] = 0; res.x [1][0] = axis.x * axis.y * (1 - Cosine) - axis.z * Sine; res.x [1][1] = axis.y * axis.y + (1 - axis.y * axis.y) * Cosine; res.x [1][2] = axis.y * axis.z * (1 - Cosine) + axis.x * Sine; res.x [1][3] = 0; res.x [2][0] = axis.x * axis.z * (1 - Cosine) + axis.y * Sine; res.x [2][1] = axis.y * axis.z * (1 - Cosine) - axis.x * Sine; res.x [2][2] = axis.z * axis.z + (1 - axis.z * axis.z) * Cosine; res.x [2][3] = 0; res.x [3][0] = 0; res.x [3][1] = 0; res.x [3][2] = 0; res.x [3][3] = 1; return res; }
Matrix MirrorX () { Matrix res (1); res.x [0][0] = -1; return res; }
Matrix MirrorY () { Matrix res (1); res.x [1][1] = -1; return res; }
Matrix MirrorZ () { Matrix res (1); res.x [2][2] = -1; return res; } /********************************************************************************/ #ifndef __MATRIX__ #define __MATRIX__
#include "Vector.h"
class Matrix { public: double x [4][4]; Matrix () {}; Matrix (double); Matrix& operator += (const Matrix&); Matrix& operator -= (const Matrix&); Matrix& operator *= (const Matrix&); Matrix& operator *= (double); Matrix& operator /= (double); void Invert (); void Transpose (); friend Matrix operator + (const Matrix&, const Matrix&); friend Matrix operator - (const Matrix&, const Matrix&); friend Matrix operator * (const Matrix&, double); friend Matrix operator * (const Matrix&, const Matrix&); friend Vector operator * (const Matrix&, const Vector&); };
Matrix Translate (const Vector&); Matrix Scale (const Vector&); Matrix RotateX (double); Matrix RotateY (double); Matrix RotateZ (double); Matrix Rotate (const Vector& v, double); Matrix MirrorX (); Matrix MirrorY (); Matrix MirrorZ ();
#endif /****************************************************************************/ #include <math.h> #include <stdlib.h> #include "Vector.h"
Vector operator ^ (const Vector& u, const Vector& v) { return Vector (u.y * v.z - u.z * v.y, u.z * v.x - u.x * v.z, u.x * v.y - u.y * v.x); }
Vector RndVector () { Vector v (rand () - 0.5*RAND_MAX, rand () - 0.5*RAND_MAX, rand () – 0.5*RAND_MAX); return Normalize (v); }
Vector& Clip (Vector& v) { if (v.x < 0.0) v.x = 0.0; else if (v.x > 1.0) v.x = 1.0; if (v.y < 0.0) v.y = 0.0; else if (v.y > 1.0) v.y = 1.0;
if (v.z < 0.0) v.z = 0.0; else if (v.z > 1.0) v.z = 1.0; return v; } ////////////////////////////////////////////////////////// // basic vector library // // all major operators overloaded to support vectors // ////////////////////////////////////////////////////////// #ifndef __VECTOR__ #define __VECTOR__
#include <math.h>
class Vector { public: double x, y, z; Vector () {}; Vector (double v) { x = y = z = v; }; Vector (const Vector& v) { x = v.x; y = v.y; z = v.z; }; Vector (double vx, double vy, double vz) { x = vx; y = vy; z = vz; }; Vector& operator = (const Vector& v) { x = v.x; y = v.y; z = v.z; return *this; }; Vector& operator = (double f) { x = y = z = f; return *this; }; Vector operator - () const; Vector& operator += (const Vector&); Vector& operator -= (const Vector&); Vector& operator *= (const Vector&); Vector& operator *= (double); Vector& operator /= (double); friend Vector operator + (const Vector&, const Vector&); friend Vector operator - (const Vector&, const Vector&); friend Vector operator * (const Vector&, const Vector&); friend Vector operator * (double, const Vector&); friend Vector operator * (const Vector&, double); friend Vector operator / (const Vector&, double); friend Vector operator / (const Vector&, const Vector&); friend double operator & (const Vector& u, const Vector& v) { return u.x*v.x + u.y*v.y + u.z*v.z; }; friend Vector operator ^ (const Vector&, const Vector&); double operator! () { return (double) sqrt (x*x + y*y + z*z); }; double& operator [] (int n) { return * (&x + n); }; int operator < (double v) { return x < v && y < v && z < v; }; int operator > (double v) { return x > v && y > v && z > v; }; };
class Ray { public: Vector Org; Vector Dir; // direction must be normalyzed Ray () {}; Ray (Vector& o, Vector& d) { Org = o; Dir = d; }; Vector Point (double t) { return Org + Dir*t; }; }; //////////////////// implementation ///////////////////////// inline Vector Vector:: operator - () const { return Vector (-x, -y, -z); } inline Vector operator + (const Vector& u, const Vector& v) { return Vector (u.x + v.x, u.y + v.y, u.z + v.z); } inline Vector operator - (const Vector& u, const Vector& v) { return Vector (u.x - v.x, u.y - v.y, u.z - v.z); } inline Vector operator * (const Vector& u, const Vector& v) { return Vector (u.x * v.x, u.y * v.y, u.z * v.z); } inline Vector operator * (const Vector& u, double f) { return Vector (u.x * f, u.y * f, u.z * f); } inline Vector operator * (double f, const Vector& v) { return Vector (f * v.x, f * v.y, f * v.z); } inline Vector operator / (const Vector& v, double f) { return Vector (v.x / f, v.y / f, v.z / f); } inline Vector operator / (const Vector& u, const Vector& v) { return Vector (u.x / v.x, u.y / v.y, u.z / v.z); } inline Vector& Vector:: operator += (const Vector& v) { x += v.x; y += v.y; z += v.z; return *this; } inline Vector& Vector:: operator -= (const Vector& v) { x -= v.x; y -= v.y; z -= v.z; return *this; } inline Vector& Vector:: operator *= (double v) { x *= v; y *= v; z *= v; return *this; } inline Vector& Vector:: operator *= (const Vector& v) { x *= v.x; y *= v.y; z *= v.z; return *this; } inline Vector& Vector:: operator /= (double v) { x /= v; y /= v; z /= v; return *this; } /////////////////////////// Functions ///////////////////////////////// inline Vector Normalize (Vector& v) { return v /!v; }; Vector RndVector (); Vector& Clip (Vector&); #endif
Дата добавления: 2014-01-11; Просмотров: 955; Нарушение авторских прав?; Мы поможем в написании вашей работы! Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет |