Вращающийся куб
Изобразить на экране прямоугольник, вращающийся в плоскости экрана вокруг своего центра
Здравствуйте. Помогите решить задачу. Изобразить на экране прямоугольник, вращающийся в.
Изобразить на экране прямоугольник, вращающийся в плоскости экрана вокруг своего центра
Здравствуйте. Помогите решить задачу. Изобразить на экране прямоугольник, вращающийся в.
Изобразить на экране прямоугольник, вращающийся в плоскости экрана вокруг своего центра
Здравствуйте. Помогите решить задачу. Изобразить на экране прямоугольник, вращающийся в.
Изобразить на экране правильный треугольник, вращающийся в плоскости экрана вокруг своего центра
Изобразить на экране правильный треугольник, вращающийся в плоскости экрана вокруг своего центра.
Вообще то, я ее сам писал, и пытался по формулам (закоментированы) написать код. Ничего доказывать, я Вам не собераюсь, особенно в области авторства программы.
Добавлено через 2 минуты
Так, можно узнать причину того, что рисуется не то, что надо? Что надо исправить?
Решение
Я же указал, что для начала нужно исправить!
Непонятные (для меня ;–) преобразования в строках 52…68.
Плюс непонятные (для меня ;–) действия при инициализации объекта.
Вот полностью переписанная программа:
Volobuev Ilya, ваше здесь только преобразование мировых координат в экранные… Да и то, переделанные под реалии данной моей программы ;–)
P.S. Ресайзинг формы специально не отключен! Куб всегда остаётся в центре формы.
В конце мая или начале июня появилась возможность использования var для всего кортежа, если что 8–)
Илья, пишите уже так:

Нарисуйте пожалуйста куб как на картинке.

Изобразить на экране отрезок, вращающийся в плоскости экрана вокруг точки, делящей отрезок в.
Прямоугольник, вращающийся на плоскости экрана вокруг своей оси
Изобразить на экране прямоугольник, вращающийся в плоскости экрана вокруг своего центра

Изобразить равнобедренный треугольник, вращающийся с постоянной угловой скоростью вокруг своей.
Pascal: Занятие № 4 часть II. Графика в Паскале
Графика в Паскале
Для работы с графикой в pascal abc используется модуль GraphABC. Для его подключения используется следующий код:
Система координат в Паскале соответствует экранной системе координат и выглядит следующим образом:
Управление цветом
Для того, чтобы использовать цвет, необходимо применить этот цвет к инструменту перо:
или использовать для заливки:
После чего можно использовать процедуры для рисования геометрических фигур.
clBlack – черный
clPurple – фиолетовый
clWhite – белый
clMaroon – темно-красный
clRed – красный
clNavy – темно-синий
clGreen – зеленый
clBrown – коричневый
clBlue – синий
clSkyBlue – голубой
clYellow – желтый
clCream – кремовый
clAqua – бирюзовый
clOlive – оливковый
clFuchsia – сиреневый
clTeal – сине-зеленый
clGray – темно-серый
clLime – ярко-зеленый
clMoneyGreen – цвет зеленых денег
clLtGray – светло-серый
clDkGray – темно-серый
clMedGray – серый
clSilver – серебряный
Точки, отрезки и ломаные
Для отображения точки в паскале используется процедура:
uses GraphABC; begin SetPixel(300,200,clred); end.
Для рисования линии используется:
uses GraphABC; begin SetPenColor(clgreen); line(100,50,500,250); end.
[Название файла: L4_2task0.pas ]
Для установки размеров графического окна используется процедура
Рисование фигур
uses GraphABC; begin Rectangle(50,50,200,200); end.
uses GraphABC; begin Rectangle(50,50,200,200); FloodFill(100,100,clBlue); end.
Line(x1,y1,x2,y2);
LineTo(x,y);
uses GraphABC; begin setpenwidth(20); setpencolor(clred); moveTo(300,100); lineTo(500,300); lineto(100,300); lineto(300,100); floodfill(300,200,clgreen); end.
uses GraphABC; begin Circle(500,200,100); FloodFill(500,200,clred); end.
uses GraphABC; Begin SetPenWidth(10); Arc(300,250,150,45,135); end.
[Название файла: L4_2task1.pas ]
[Название файла: L4_2task2.pas ]
Функция random для использования окраски
* раскрасить круги случайным цветом
[Название файла: L4_2task3.pas ]
[Название файла: L4_2task4.pas ]
[Название файла: L4_2task5.pas ]
Нарисовать штриховку на Паскале можно, используя процедуры рисования прямоугольника и линии:
Программа будет выглядеть следующим образом:
[Название файла: L4_2task6.pas ]
Анимация в Паскале
Анимация в программировании заключается в том, что сначала рисуется фигура цветным инструментом, затем с тем же координатами рисуется та же фигура белым цветом. После чего происходит сдвиг фигуры и действия повторяются.
uses GraphABC; var x:integer; begin x:=40; repeat SetPenColor(clWhite); Circle(x,100,10); <Рисуем белую окружность>SetPenColor(clBlack); Circle(x,100,10); <Рисуем черную окружность>x:=x+1 <Перемещаемся немного направо>until x>600; end.
Программа, выводящая на экран куб на языке программирования PascalABC
Курс повышения квалификации
Дистанционное обучение как современный формат преподавания
Курс повышения квалификации
Педагогическая деятельность в контексте профессионального стандарта педагога и ФГОС
Курс повышения квалификации
Современные педтехнологии в деятельности учителя
Ищем педагогов в команду «Инфоурок»
Номер материала: ДВ-227868
Не нашли то что искали?
Вам будут интересны эти курсы:
Оставьте свой комментарий
Авторизуйтесь, чтобы задавать вопросы.
Учителя о ЕГЭ: секреты успешной подготовки
Время чтения: 11 минут
Учителям предлагают 1,5 миллиона рублей за переезд в Златоуст
Время чтения: 1 минута
Учителя о ЕГЭ: секреты успешной подготовки
Время чтения: 11 минут
Путин призвал повышать уровень общей подготовки в колледжах
Время чтения: 1 минута
В МГУ заработала университетская квантовая сеть
Время чтения: 1 минута
Путин поручил не считать выплаты за классное руководство в средней зарплате
Время чтения: 1 минута
В российских школах могут появиться «службы примирения»
Время чтения: 1 минута
Подарочные сертификаты
Ответственность за разрешение любых спорных моментов, касающихся самих материалов и их содержания, берут на себя пользователи, разместившие материал на сайте. Однако администрация сайта готова оказать всяческую поддержку в решении любых вопросов, связанных с работой и содержанием сайта. Если Вы заметили, что на данном сайте незаконно используются материалы, сообщите об этом администрации сайта через форму обратной связи.
Все материалы, размещенные на сайте, созданы авторами сайта либо размещены пользователями сайта и представлены на сайте исключительно для ознакомления. Авторские права на материалы принадлежат их законным авторам. Частичное или полное копирование материалов сайта без письменного разрешения администрации сайта запрещено! Мнение администрации может не совпадать с точкой зрения авторов.
Как рисовать в Паскале
Графика в Паскале.Анимация. Динамические рисунки Turbo Pascal
3Д вращение каркаса куба по различным осям
Program Kub;
Uses Graph,Crt;
Type
mas=array[1..8] of real;
Var
ro,teta,phi,d,rebro:real;
xk,yk,zk:mas;
xv,yv,zv:mas;
V:array [1..4,1..4] of real;
i,GrDrive,GrMode:integer;
minx,miny,maxx,maxy,fx,fy,f,c1,c2:real;
t,f1,wx1,wy1,wx2,wy2:integer;
q:char;
Function mult(x,y,z:real; n:integer):real;
Begin
xv[n]:=x*v[1,1]+y*v[2,1]+z*v[3,1]+v[4,1];
yv[n]:=x*v[1,2]+y*v[2,2]+z*v[3,2]+v[4,2];
zv[n]:=x*v[1,3]+y*v[2,3]+z*v[3,3]+v[4,3];
End;
Begin
GrDrive:=Detect;
InitGraph(GrDrive,GrMode,»);
t:=0;
f1:=0;
d:=1400;
Repeat
SetColor(0);
line(round(xv[1]),round(yv[1]),round(xv[2]),round(yv[2]));
line(round(xv[2]),round(yv[2]),round(xv[3]),round(yv[3]));
line(round(xv[3]),round(yv[3]),round(xv[4]),round(yv[4]));
line(round(xv[4]),round(yv[4]),round(xv[1]),round(yv[1]));
line(round(xv[5]),round(yv[5]),round(xv[6]),round(yv[6]));
line(round(xv[6]),round(yv[6]),round(xv[7]),round(yv[7]));
line(round(xv[7]),round(yv[7]),round(xv[8]),round(yv[8]));
line(round(xv[8]),round(yv[8]),round(xv[5]),round(yv[5]));
line(round(xv[1]),round(yv[1]),round(xv[5]),round(yv[5]));
line(round(xv[2]),round(yv[2]),round(xv[6]),round(yv[6]));
line(round(xv[3]),round(yv[3]),round(xv[7]),round(yv[7]));
line(round(xv[4]),round(yv[4]),round(xv[8]),round(yv[8]));
rebro:=100;
ro:=1360;
t:=t+1;
f1:=f1+1;
if t=90 then t:=0;
if f1=90 then f1:=0;
teta:=t*pi/180;
phi:=f1*pi/180;
xk[1]:=rebro; yk[1]:=-rebro; zk[1]:=-rebro;
xk[2]:=rebro; yk[2]:=rebro; zk[2]:=-rebro;
xk[3]:=-rebro; yk[3]:=rebro; zk[3]:=-rebro;
xk[4]:=-rebro; yk[4]:=-rebro; zk[4]:=-rebro;
xk[5]:=rebro; yk[5]:=-rebro; zk[5]:=rebro;
xk[6]:=rebro; yk[6]:=rebro; zk[6]:=rebro;
xk[7]:=-rebro; yk[7]:=rebro; zk[7]:=rebro;
xk[8]:=-rebro; yk[8]:=-rebro; zk[8]:=rebro;
v[1,1]:=-sin(teta); v[1,2]:=-cos(phi)*cos(teta); v[1,3]:=-sin(phi)*cos(teta);
v[2,1]:=cos(teta); v[2,2]:=-cos(phi)*sin(teta); v[2,3]:=-sin(phi)*sin(teta);
v[3,1]:=0; v[3,2]:=sin(phi); v[3,3]:=-cos(phi);
v[4,1]:=0; v[4,2]:=0; v[4,3]:=ro;
for i:=1 to 8 do
begin
mult(xk[i],yk[i],zk[i],i);
xv[i]:=d*xv[i]/zv[i];
yv[i]:=d*yv[i]/zv[i];
end;
SetViewPort(250,200,350,300,false);
SetColor(10);
line(round(xv[1]),round(yv[1]),round(xv[2]),round(yv[2]));
line(round(xv[2]),round(yv[2]),round(xv[3]),round(yv[3]));
line(round(xv[3]),round(yv[3]),round(xv[4]),round(yv[4]));
line(round(xv[4]),round(yv[4]),round(xv[1]),round(yv[1]));
line(round(xv[5]),round(yv[5]),round(xv[6]),round(yv[6]));
line(round(xv[6]),round(yv[6]),round(xv[7]),round(yv[7]));
line(round(xv[7]),round(yv[7]),round(xv[8]),round(yv[8]));
line(round(xv[8]),round(yv[8]),round(xv[5]),round(yv[5]));
line(round(xv[1]),round(yv[1]),round(xv[5]),round(yv[5]));
line(round(xv[2]),round(yv[2]),round(xv[6]),round(yv[6]));
line(round(xv[3]),round(yv[3]),round(xv[7]),round(yv[7]));
line(round(xv[4]),round(yv[4]),round(xv[8]),round(yv[8]));
delay(1000);
Until KeyPressed;
CloseGraph;
End.
Как построить куб в паскале
В этой статье мы научимся рисовать простой 3D объект — куб. Также мы запрограммируем анимацию куба и виртуальную камеру, позволяющую взглянуть на куб глазами зрителя.
Содержание
Вершины куба
В чём OpenGL измеряет расстояния в трёхмерном мире? В 2D графике всё понятно: у нас есть пиксели. На трёхмерной проекции объекты одинакового размера могут дать разные проекции из-за перспективного искажения: чем дальше поверхность или линия, тем она меньше. Поэтому OpenGL измеряет расстояния в единицах измерения, не уточняя, в каких именно. Вы можете измерять в метрах, попугаях или в футах — на картинке это не имеет разницы, потому что исходные размеры не совпадают с проекциями.
Триангуляция куба
После того, как выписали список вершин куба, следует разпределить вершины по треугольникам. У куба 6 квадратных граней, их можно описать 12-ю треугольниками. При этом вершины каждого треугольника следует перечислять по часовой стрелке для наблюдателя, смотрящего снаружи куба на этот треугольник. В противном случае треугольник станет поверхностью, видимой изнутри куба, что нарушает физические законы.
Процесс разделения поверхности на треугольники называют триангуляцией (англ. triangulation). Для упрощения этого процесса сделаем визуализацию куба с вершинами, нумерованными в том же порядке, в котором они были перечислены ранее:
Теперь, глядя на иллюстрацию, можно перечислить все 12 треугольников, составляющих 6 граней.
Рисование в Immediate Mode
Для непосредственного рисования граней куба мы применим не самый производительный метод, который к тому же устарел в современных версиях OpenGL: рисование в блоке glBegin/glEnd, также известное как OpenGL Immediate Mode.
Настройка фиксированной камеры
В OpenGL при использовании фиксированного конвейера есть ровно две матрицы, относящихся к трансформациям точек и объектов:
За рамками фиксированного конвейера можно использовать столько матриц, сколько захочется — но сейчас мы ограничены. Кроме того, нам приходится смешивать матрицы:
Обычно при программировании действуют так:
Решение проблем невидимых поверхностей
При программном рисовании трёхмерного мира, состоящего из объемных тел с непрерывной поверхностью (англ. solid bodies), возникает вопрос: как не нарисовать невидимые поверхности? Например, на рисунке горы, покрытой лесом, мы не должны увидеть ни деревьев на противоположном к нам склоне, ни поверхности самого склона.
У художников для решения задачи есть свой алгоритм: сначала они рисуют композицию заднего фона, затем сверху покрывают средний фон, и, наконец, выводят передний фон:
Этот алгоритм так и называется — “алгоритм художника” (англ. painter’s algorithm). В компьютерной графике он иногда применим, но с модификацией: вместо деления объектов на три группы (задний фон, средний фон и передний фон) придётся отсортировать все объекты и вывести их в порядке приближения. К сожалению, не всегда объекты воможно отсортировать: это известно как “проблема художника” (англ. painter’s problem).
Для решения проблемы художника в OpenGL сделано следующее:
Тест буфера глубины
Буфер глубины OpenGL — это двумерная матрица дополнительных данных, где каждому пикселю соответствует одно значение float: глубина фрагмента примитива, оказавшегося ближе к пикселю, чем остальные фрагменты примитивов, проецируемые на тот же пиксель. Это позволяет реализовать попиксельный алгоритм художника: после приведения в нормализованное пространство каждая примитивная фигура будет разбита на фрагменты, для которых будет проведён тест глубины.
Фрагмент — это атомарная, то есть неделимая, часть фигуры. Если видеокарта не совершает сглаживание, то один фрагмент станет одним пикселем фигуры.
Тест глубины устроен следующим образом: если фрагмент в нормализованном пространтсве стал ближе, чем последнее значение буфера глубины, то мы выбираем его и обновляем значение в буфере глубины, иначе мы отбрасываем фрагмент. В псевдокоде способ выглядит так:
Как и любой другой буфер OpenGL, буфер глубины следует очищать. Для этого вызов glClear должен получать ещё один флаг GL_DEPTH_BUFFER_BIT :
Также нужно после создания контекста включить режим теста глубины командой glEnable:
Отсечение задних граней
Вызов glFrontFace(GL_CW) изменит классификацию на обратную: перечисление по часовой даст переднюю грань, перечисление против часовой даст заднюю.
Независимо от того, в каком порядке были заданы исходные вершины, если после всех преобразований грань объёмного тела повёрнута к нам лицевой стороной — порядок обхода сохранится, а если её перекроют другие грани — порядок обхода сменится на противоположный.
Соберём всю инициализацию состояния OpenGL в метод OnWindowInit, который будет вызываться один раз поле инициализации окна
Чтобы метод OnWindowInit был вызван своевременно, его можно объявить виртуальным в классе CAbstractWindow и вызывать в методе Show:
Диагностика проблем
При выводе трёхмерных тел встречается ряд типовых ошибок. Если что-то не работает, пройдитесь по следующему чеклисту:
Если всё нормально, то вы получите статичное изображение куба без возможности поменять положение камеры:
Чтобы придать сцене динамику, нам потребуется глубже изучить математические принципы трансформаций точек и векторов в трёхмерном пространстве. Приступим…
Трёхмерная система координат
В OpenGL используется правосторонняя система координат, в которых пользователь может задавать вершины примитивов, из которых состоят трехмерные объекты. Правосторонней система координат называется потому, что ее можно образовать при помощи большого, указательного и среднего пальцев правой руки, задающих направления координатных осей X, Y и Z соответственно.
Система координат задаётся точкой отсчёта и координатными осями, которые, в свою очередь, задают направления и длины трёх единичных векторов (1, 0, 0), (0, 1, 0) и (0, 0, 1). Как точка отсчёта, так и координатные оси могут меняться при переходе из одной системы координат в другую.
В любой трёхмерной сцене есть система координат, которую можно считать мировой системой коодинат. Это очень удобно: любая точка или вектор в мировой системе координат представляется однозначно. Благодаря этому, если у нас есть несколько локальных систем координат (например: комната, салон автомобиля, камера), и мы знаем способ преобразования из любой системы в мировые координаты, то мы можем спокойно перейти, например, от системы координат комнаты к системе координат камеры:
О локальных системах координат можно сказать следующее:
Самый удивительный факт: любое элементарное трёхмерное преобразование, а также их комбинацию можно представить в виде матрицы 4×4! Чтобы понять, как это происходит, разберёмся с однородным представлением точек и векторов.
Единый тип данных для точек и векторов
Давайте представим, что нам поставили задачу: создать единый тип данных, способный хранить как трёхмерную точку, так и трёхмерный вектор. Этот тип данных должен поддерживать операции вращения, перемещения и масштабирования, причём по-разному для векторов и точек: например, перемещение вектора никак не меняет его, а перемещение точки изменяет эту точку.
Если использовать процедурную парадигму программирования, получится нечто такое:
Объектно-ориентированный подход предлагает такой вариант:
Оба подхода одинаково плохи: во-первых, мы в любом случае дублируем код. Во-вторых, на видеокартах с современной архитектурой любое ветвление или условное выполнение оборачивается огромным падением производительности, и желательно его избегать; в данных двух реализациях мы не сможем избежать ветвлений при выполнении трансформаций точек и векторов прямо на видеокарте.
Проблема решается с помощью математического приёма — однородного представления точек и векторов.
Однородное представление точек и векторов.
Как известно, можно умножить матрицу на матрицу при условии, что ширина одной матрицы равна высоте другой (иначе операция просто недопустима). Для получения элемента с позицией i,j в новой матрице достаточно взять i-ю строку левой матрицы и j-й столбец правой матрицы. Вот пример:
Как ни странно, умножение 4-х компонентного вектора на матрицу 4×4 тоже возможно! Для этого достаточно считать 4-х компонентный вектор матрицей 4×1. После умножения получится новый 4-х компонентный вектор.
Ещё более удивительно, что любую комбинацию трёхмерных перемещений, поворотов, вращений (и не только их!) можно представить как всего лишь одну матрицу 4×4, называемую матрицей трёхмерной трансформации. При этом умножение матрицы на трёхмерную точки или вектор, записанный в однородном представлении, даёт новую точку или вектор именно так, как этого требуют правила преобразования точек и векторов. Никаких ветвлений, и никакой магии!
Класс CAnimatedCube
Давайте запомним несколько простых правил. Некоторые из них даже будут доказаны чуть ниже.
Для демонстрации этих правил расширим класс CIdentityCube из предыдущего урока. Новый класс будет называться CAnimatedCube, и он будет демонстрировать работу трёх базовых аффинных трансформаций. Смена и продвижение анимации будет выполняться в методе Update, вызываемом периодически снаружи.
С учётом перечисленных выше правил, мы можем написать метод Draw для анимированного куба. При этом вместо glLoadMatixf следует применить glMultMatrixf, чтобы вместо замены уже существующей трансформации всего лишь модифицировать её. Если мы заменим матрицу GL_MODELVIEW, камера будет работать некорректно.
Функции для работы с аффинными трансформациями (и не только!) можно найти в GML:
Единичная матрица
Единичная матрица (матрица идентичности, англ. identity matrix) задает преобразование, при котором точки и векторы остаются без изменений, отображаясь сами в себя. Посмотрите сами на перемножение этой матрицы и точки/вектора:
Если мы не хотим возвращать из метода GetAnimationTransform() какую-либо преобразующую трансформацию, мы можем просто вернуть единичную матрицу. Именно такую матрицу создаёт конструктор по умолчанию класса glm::mat4. Теперь мы можем заложить каркас метода GetAnimationTransform:
Матрица перемещения
Матрица перемещения воздействует на точку, но вектор сохраняет неизменным. Действует она так:
В GLM есть функция glm::translate, умножающая переданную матрицу на матрицу перемещения. Чтобы анимировать куб, будем вычислять смещение по оси Ox в каждый момент времени. После этого получение матрицы перемещения будет очень простым:
Для гладкого движения куба будем использовать прямолинейное равномерно ускоренное движение, аналогичное обычному прыжку или движению мача, брошенного вверх. Вот его иллюстрация в неинерциальной и инерциальной системах отсчёта:
В процессе анимации от 0% до 100% куб должен один или несколько раз прыгнуть в сторону и затем вернуться обратно. Для этого воспользуемся делением с остатком, а также формулой расчёта расстояния на основе начальной скорости и противоположно направленного ускорения. Можно написать так:
Матрица масштабирования
Матрица масштабирования воздействует как на точку, так и на вектор, изменяя соответственно удалённость точки от начала координат и длину вектора. Действует так:
В GLM есть функция glm::scale, умножающая переданную матрицу на матрицу масштабирования, имеющую потенциально разные коэффициенты масштабирования для трёх разных компонентов вектора.
Давайте используем эту функцию, чтобы реализовать пульсирование куба — сжатие от нормальных размеров к нулевым и обратно:
Матрица поворота
Матрица поворота воздействует и на точку, и на вектор, при этом удалённость точки от начала координат и длина вектора не меняются. Существует Теорема Эйлера, согласно которой любой поворот в трёхмерном пространстве вокруг произвольной оси можно представить как последовательность трёх поворотов вокруг трёх базовых осей системы координат в определённом порядке и на определённые углы:
Перечислим три матрицы поворота на угол “a” вокруг трёх осей системы координат (посмотреть, что получается при перемножении, вы можете самостоятельно):
В GLM есть функция glm::rotate, умножающая переданную матрицу на матрицу поворота вокруг переданного произвольного вектора оси на переданный угол. Как уже было сказано ранее, следует настроить GLM так, чтобы углы выдавались в радианах — иначе вы будете получать предупреждения об использовании устаревшего API. Проверьте, что в stdafx.h перед включением GLM объявлен макрос GLM_FORCE_RADIANS:
Матрицы поворота сложнее масштабирования или перемещения, но применить их для анимации проще: нужно всего лишь задать скорость поворота такой, чтобы за время анимации куб повернулся целое число раз:
Вот так это будет выглядеть к концу урока:
Как создать камеру
В OpenGL в режиме версии 1.x есть две трансформирующих вершины матрицы: GL_MODELVIEW и GL_PROJECTION. Матрица GL_MODELVIEW объединяет к себе как переход от локальной системы координат к мировой (Model), так и переход от мировых координат к системе коодинат камеры (View). Класс CCamera будет возвращать только одну компоненту GL_MODELVIEW: матрицу вида, созданную функцией glm::lookAt.
Правила движения камеры будут следующими:
С учётом сказанного, спроектируем следующий интерфейс класса:
Методы Update, OnKeyDown, OnKeyUp должны вызываться извне — например, из класса окна. При этом методы обработки событий возвращают true, если событие было обработано, чтобы класс окна мог не рассылать это событие далее другим объектам.
Внутри класс хранит угол поворота камеры, отдаление от центра мира и подмножество клавиш, которые сейчас нажаты. Хранение подмножества нажатых клавиш позволяет легко устранить ряд непростых случаев:
Чтобы отслеживать нажатие только нужных клавиш, создадим функцию-предикат ShouldTrackKeyPressed:
Также подключим заголовок с функциями вращения вектора, введём вспомогательные константы и функции, позволяющие получить скорость поворота и скорость приближения (возможно, нулевые или отрицательные) на основе информации о нажатых клавишах:
После этого с небольшим применением линейной алгебры мы можем реализовать методы класса CCamera:
Изменения в CWindow
Теперь класс CWindow должен хранить три объекта:
Конструктор CCamera требует два аргумента, их можно задать следующим образом:
CWindow::CWindow() : m_camera(CAMERA_INITIAL_ROTATION, CAMERA_INITIAL_DISTANCE)
В методе OnUpdateWindow мы должны вызывать метод Update у всех трёх объектов системы:
В методе Draw немного схитрим: применим вызов glTranslate (вместо нормальной работы с функциями GLM), чтобы развести два куба в стороны:
Метод SetupView станет проще, потому что мы можем не вычислять матрицу GL_MODELVIEW, а получить её начальное (для кадра) значение у камеры.
Наконец, следует перегрузить методы OnKeyDown/OnKeyUp класса CAbstractInputControlWindow в классе CWindow:
Конец!
Теперь вы можете взять полный пример (github.com) или посмотреть, каким будет результат запуска (в виде статичного скриншота):
Чтобы сделать результат более наглядным, была сделана серия скриншотов, которые затем были объединены в gif с помощью GIMP:























