- •Московский институт электронной техники
- •Аффинные преобразования на плоскости.
- •Два взгляда на аффинные преобразования.
- •Элементарные аффинные преобразования.
- •Однородные координаты.
- •Композиция элементарных аффинных преобразований.
- •Класс Matrix2d для реализации аффинных преобразований в 2d графике.
- •Пример использования аффинных преобразований для моделирования движения в 2d-графике.
- •Пример программы моделирования движения в Windows.
- •Уничтожение следа за движущимся объектом повторным рисованием объекта в Windows программах.
- •Использование режима xor для моделирования движения в Windows программах.
- •Использование видеостраниц для моделирования движения в однопользовательских операционных системах, например в dos.
- •Использование оперативной памяти для моделирования движения в Windows программах.
- •Примеры анимации в Windows программах.
- •Задание к выполнению лабораторной работы.
- •Задание к выполнению второго пункта работы.
Композиция элементарных аффинных преобразований.
Как было сказано выше, любое сложное аффинное преобразование, можно представить в виде композиции нескольких элементарных аффинных преобразований. Покажем это на примере. У нас имеются матрицы отражения относительно координатных осей, нам же надо найти матрицу отражения относительно произвольной оси l, как это показано на рисунке 11.
Рис. 11.
Аффинное преобразование – отражение относительно оси l.
Нужное преобразование легко получить, если перейти в другую систему координат (x//,y//), где осьlбудет совпадать с координатной осьюx//, как это показано на рисунке 12.
Рис. 12.
Аффинное преобразование – отражение относительно оси x.
Находясь теперь в системе координат (x//,y//) можно применить операцию отражения относительно координатной осиx//. Матрица такого преобразования известна, она имеет вид.
(27)
Перейти из системы координат (x,y) в систему координат (x//,y//) можно, если использовать два элементарных аффинных преобразования, как показано на рисунке 13.
Рис. 13.
Аффинное преобразование – цепочка преобразования координат (x,y)(x,y)(x,y).
Вначале мы переходим из системы координат (x,y) в систему координат (x/,y/) совершая перенос на вектор. Матрица этого перехода имеет вид.
(28)
Здесь надо вспомнить о двух точках зрения на аффинное преобразование. Если бы речь шла о движении объекта, мы использовали бы преобразование . Если же речь идет о переходе в другую систему координат, то мы применяем аффинное преобразование для движения в противоположную сторону.
Далее мы переходим из системы координат (x/,y/) в систему координат (x//,y//) совершая поворот на угол. Матрица этого перехода имеет вид.
(29)
Теперь можно указать все этапы получения матрицы отражения относительно оси l.
Переход из системы координат (x,y) в систему координат (x/,y/) с помощью преобразования.
Переход из системы координат (x/,y/) в систему координат (x//,y//) с помощью преобразования.
Отражение относительно оси x//с помощью преобразования.
Возвращение из системы координат (x//,y//) в систему координат (x/,y/) с помощью преобразования.
Возвращение из системы координат (x/,y/) в систему координат (x,y) с помощью преобразования.
Эти этапы удобно изобразить в виде цепочки преобразований.
Данная цепочка позволяет легко получить матрицу искомого преобразования как произведение матриц элементарных аффинных преобразований.
(30)
Класс Matrix2d для реализации аффинных преобразований в 2d графике.
Для программирования аффинных преобразований при моделировании движения объектов удобно использовать аппарат классов. В этом случае, например, операции умножения матриц будут выглядеть как обычное алгебраическое умножение. Ниже приводится описание класса для работы с рассмотренными элементарными аффинными преобразованиями.
//класс для работы с матрицами аффинных преобразований
//используются однородные координаты
class Matrix2D
{
public:
double x[3][3];
Matrix2D(); //конструктор класса, матрица единичная
void rotate(double fi); //матрица поворота
void displa(double kx, double ky); //матрица растяжения
void transl(double tx, double ty ); //матрица трансляции
//оператор перемножение матриц
friend Matrix2D operator * (const Matrix2D&, const Matrix2D&);
};
//конструктор класса, матрица единичная
Matrix2D::Matrix2D()
{
x[0][0] = 1; x[0][1] = 0; x[0][2] = 0;
x[1][0] = 0; x[1][1] = 1; x[1][2] = 0;
x[2][0] = 0; x[2][1] = 0; x[2][2] = 1;
}
//матрица поворота
void Matrix2D::rotate(double fi)
{
double cosfi = cos(fi), sinfi = sin(fi);
x[0][0] = cosfi; x[0][1] = -sinfi; x[0][2] = 0;
x[1][0] = sinfi; x[1][1] = cosfi; x[1][2] = 0;
x[2][0] = 0; x[2][1] = 0; x[2][2] = 1;
}
//матрица растяжения
void Matrix2D::displa(double kx, double ky)
{
x[0][0] = kx; x[0][1] = 0; x[0][2] = 0;
x[1][0] = 0; x[1][1] = ky; x[1][2] = 0;
x[2][0] = 0; x[2][1] = 0; x[2][2] = 1;
}
//матрица трансляции
void Matrix2D::transl(double tx, double ty )
{
x[0][0] = 1; x[0][1] = 0; x[0][2] = tx;
x[1][0] = 0; x[1][1] = 1; x[1][2] = ty;
x[2][0] = 0; x[2][1] = 0; x[2][2] = 1;
}
//оператор перемножение матриц
Matrix2D operator * (const Matrix2D& a, const Matrix2D& b)
{
Matrix2D c;
double s;
for(int i=0; i<3; i++)
for(int j=0; j<3; j++)
{
s = 0;
for(int n=0; n<3; n++)
s += a.x[i][n]*b.x[n][j];
c.x[i][j] = s;
}
return c;
}