Я читаю литературу по началам графики и решил составить небольшой примерчик, демонстрирующий 3Д но без DirectX. Конечно мой пример можна проще всего сделать при помощи DirectX или OpenGL но меня заинтересовал сам механизм трехмерной графики поэтому я взялся за этот пример его делать. Пример заключаеться в слеадующем: я в трехмерном пространстве нарисовал куб в начале центра координатной системы трехмерной. Потом вращаю этот куб (при помощи таймера) по оси Y и по часовой стрелке справа на лево, и у меня получаються искажения, артефакты. Вот рисунок куба при повороте на 0 градусов:
, вот при повороте на 90 градусов (идут искажения, как буд то наблюдатель справа от меня, меняеться проекция вроде) 90 градусов -
. При повороте на 180 проекция сохраняеться
и при повороте на 270 опять проекция вроде наблюдатель слева от меня
Вот мой код:
Код:
void CCubeNotDXDlg::OnTimer(UINT nIDEvent)
{
angle+=(3.1415926/180);
if(angle>3.1415926*2) angle =0;
Invalidate();
}
void CCubeNotDXDlg::OnPaint()
{
CPaintDC dc(this); // device context for painting
float nPoint = 1.0;
Side[0].x1 = -nPoint;
Side[0].y1 = nPoint;
Side[0].z1 = -nPoint;
Side[0].x2 = nPoint;
Side[0].y2 = nPoint;
Side[0].z2 = -nPoint;
Side[0].x3 = nPoint;
Side[0].y3 = -nPoint;
Side[0].z3 = -nPoint;
Side[0].x4 = -nPoint;
Side[0].y4 = -nPoint;
Side[0].z4 = -nPoint;
Side[1].x1 = nPoint;
Side[1].y1 = nPoint;
Side[1].z1 = -nPoint;
Side[1].x2 = nPoint;
Side[1].y2 = nPoint;
Side[1].z2 = nPoint;
Side[1].x3 = nPoint;
Side[1].y3 = -nPoint;
Side[1].z3 = nPoint;
Side[1].x4 = nPoint;
Side[1].y4 = -nPoint;
Side[1].z4 = -nPoint;
Side[2].x1 = nPoint;
Side[2].y1 = nPoint;
Side[2].z1 = nPoint;
Side[2].x2 = -nPoint;
Side[2].y2 = nPoint;
Side[2].z2 = nPoint;
Side[2].x3 = -nPoint;
Side[2].y3 = -nPoint;
Side[2].z3 = nPoint;
Side[2].x4 = nPoint;
Side[2].y4 = -nPoint;
Side[2].z4 = nPoint;
Side[3].x1 = -nPoint;
Side[3].y1 = nPoint;
Side[3].z1 = nPoint;
Side[3].x2 = -nPoint;
Side[3].y2 = nPoint;
Side[3].z2 = -nPoint;
Side[3].x3 = -nPoint;
Side[3].y3 = -nPoint;
Side[3].z3 = -nPoint;
Side[3].x4 = -nPoint;
Side[3].y4 = -nPoint;
Side[3].z4 = nPoint;
Side[4].x1 = -nPoint;
Side[4].y1 = nPoint;
Side[4].z1 = nPoint;
Side[4].x2 = nPoint;
Side[4].y2 = nPoint;
Side[4].z2 = nPoint;
Side[4].x3 = nPoint;
Side[4].y3 = nPoint;
Side[4].z3 = -nPoint;
Side[4].x4 = -nPoint;
Side[4].y4 = nPoint;
Side[4].z4 = -nPoint;
Side[5].x1 = -nPoint;
Side[5].y1 = -nPoint;
Side[5].z1 = nPoint;
Side[5].x2 = nPoint;
Side[5].y2 = -nPoint;
Side[5].z2 = nPoint;
Side[5].x3 = nPoint;
Side[5].y3 = -nPoint;
Side[5].z3 = -nPoint;
Side[5].x4 = -nPoint;
Side[5].y4 = -nPoint;
Side[5].z4 = -nPoint;
for (int i = 0; i < 6; i++)
{
//поворачиваем вокруг Y
Side[i].x1 = Side[i].x1 * cos(angle) + Side[i].y1 * 0 - Side[i].z1 * sin(angle);
Side[i].z1 = Side[i].x1 * -sin(angle)+ Side[i].y1 * 0 - Side[i].z1 * cos(angle);
Side[i].x2 = Side[i].x2 * cos(angle) + Side[i].y2 * 0 - Side[i].z2 * sin(angle);
Side[i].z2 = Side[i].x2 * -sin(angle)+ Side[i].y2 * 0 - Side[i].z2 * cos(angle);
Side[i].x3 = Side[i].x3 * cos(angle) + Side[i].y3 * 0 - Side[i].z3 * sin(angle);
Side[i].z3 = Side[i].x3 * -sin(angle)+ Side[i].y3 * 0 - Side[i].z3 * cos(angle);
Side[i].x4 = Side[i].x4 * cos(angle) + Side[i].y4 * 0 - Side[i].z4 * sin(angle);
Side[i].z4 = Side[i].x4 * -sin(angle)+ Side[i].y4 * 0 - Side[i].z4 * cos(angle);
//мировая трансформация
Side[i].x1+=0;
Side[i].y1+=0;
Side[i].z1+=4;
Side[i].x2+=0;
Side[i].y2+=0;
Side[i].z2+=4;
Side[i].x3+=0;
Side[i].y3+=0;
Side[i].z3+=4;
Side[i].x4+=0;
Side[i].y4+=0;
Side[i].z4+=4;
//перспективная трансформация
Side[i].x1 /= Side[i].z1;
Side[i].y1 /= Side[i].z1;
Side[i].x2 /= Side[i].z2;
Side[i].y2 /= Side[i].z2;
Side[i].x3 /= Side[i].z3;
Side[i].y3 /= Side[i].z3;
Side[i].x4 /= Side[i].z4;
Side[i].y4 /= Side[i].z4;
//экранная трансформация
RECT rect;
GetClientRect(&rect);
Side[i].x1 = Side[i].x1 * rect.right/2 + rect.right/2;
Side[i].y1 = (-Side[i].y1) * rect.bottom/2 + rect.bottom/2;
Side[i].x2 = Side[i].x2 * rect.right/2 + rect.right/2;
Side[i].y2 = (-Side[i].y2) * rect.bottom/2 + rect.bottom/2;
Side[i].x3 = Side[i].x3 * rect.right/2 + rect.right/2;
Side[i].y3 = (-Side[i].y3) * rect.bottom/2 + rect.bottom/2;
Side[i].x4 = Side[i].x4 * rect.right/2 + rect.right/2;
Side[i].y4 = (-Side[i].y4) * rect.bottom/2 + rect.bottom/2;
CPen penBlue;
penBlue.CreatePen(PS_SOLID, 3, RGB(0, 0, 255));
CPen* ppenOld;
ppenOld=dc.SelectObject(&penBlue);
dc.MoveTo(Side[i].x1, Side[i].y1);
dc.LineTo(Side[i].x2, Side[i].y2);
dc.LineTo(Side[i].x3, Side[i].y3);
dc.LineTo(Side[i].x4, Side[i].y4);
dc.LineTo(Side[i].x1, Side[i].y1);
dc.SelectObject(ppenOld);
}
if (IsIconic())
{
...................
}
else
{
CDialog::OnPaint();
}
}