Добавил:
nyan
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:
//вращение одной системы координат относительно другой
//выполнятеся с помощь мышки и стрелок клавиатуры
#define STRICT
#include <windows.h>
#include <math.h>
#include <stdio.h>
#include <gl\gl.h>
#include <gl\glu.h>
// Имя класса окна
const char Cname[] = "SurfClass";
// Заголовок окна
const char Title[] =
"OpenGL Windows Application Rotation by mouse and arrows, Stop - SPACE ";
//углы поворота видовой системы координат
struct ANGLS {
double fi, teta;
};
static ANGLS angl,anglOld;
//координаты точек в мировой системе координат
struct POINT3 {
double x, y, z;
};
static POINT3 Point[8];
//флаги для работы с мышкой
struct TDATA {
BOOL ButtonDown;
BOOL Drawing;
};
static TDATA Dat;
//координаты мышки
struct CORD {
int x, y;
};
static CORD corOld;
//флаг для указания направления вращения
int FlagRotation;
//флаг для удаления шахматной доски
bool FlagDesk = true;
//прототипы функций
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void SurfCreate();
void SurfDestroy();
void SurfPaint(HWND);
void DrawBox(HDC, ANGLS);
void PointCorns();
void SurfDC(HWND);
void SurfLButtonDown(int,int);
void SurfMouseMove(int,int);
void SurfLButtonUp();
void PointCorns();
void Picture(HWND,HDC);
void Axes(HDC);
inline double Xe(double,double);
inline double Ye(double,double,double);
inline int xn(double);
inline int ym(double);
void DrawOpenGL(HDC);
int WINAPI WinMain(HINSTANCE hInstance, //идентификатор приложения
HINSTANCE hPrevInstance,
LPSTR lpCmdParam,
int nCmdShow)
{
MSG msg; // структура для работы с сообщениями
//регистрация класса окна приложения
//------------------------------------------------------------------------
WNDCLASS wc; // структура для регистрации класса окна приложения
wc.style = 0;
wc.lpfnWndProc = (WNDPROC)WndProc; //адрес функции окна
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance; //идентификатор приложения
wc.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
wc.lpszMenuName = 0;
wc.lpszClassName = Cname;
if(!RegisterClass(&wc)) //регистрация класса окна приложения
return 0;
//создание окна приложения
//------------------------------------------------------------------------
HWND hWnd; // идентификатор окна приложения
hWnd = CreateWindow(Cname,
Title,
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN
| WS_CLIPSIBLINGS, //стиль окна
// WS_OVERLAPPEDWINDOW,
100, //x - координата л.в. угла
50, //y - координата л.в. угла
650, //ширина окна
500, //высота окна
// CW_USEDEFAULT,
// CW_USEDEFAULT,
// CW_USEDEFAULT,
// CW_USEDEFAULT,
NULL, //идентификатор окна-родителя
NULL, //идентификатор меню
hInstance, //идентификатор приложения
NULL);
if(!hWnd)
return 0;
// Рисуем окно. Для этого после функции ShowWindow,
// рисующей окно, вызываем функцию UpdateWindows,
// посылающую сообщение WM_PAINT в функцию окна
//--------------------------------------------------------------------------
ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);
// Запускаем цикл обработки сообщений
//-------------------------------------------------------------------------
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
//оконная процедура обрабатывающая сообщения
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam)
{
int x,y;
switch(msg)
{
case WM_CREATE:
SetTimer(hwnd, 1, 2, NULL);
SurfCreate();
break;
case WM_PAINT:
SurfPaint(hwnd);
break;
case WM_TIMER:
switch(FlagRotation)
{
case 1:
angl.fi += 0.5;
break;
case 2:
angl.fi -= 0.5;
break;
case 3:
angl.teta += 0.5;
break;
case 4:
angl.teta -= 0.5;
break;
}
SurfDC(hwnd);
break;
case WM_LBUTTONDOWN:
x = LOWORD(lParam);
y = HIWORD(lParam);
SurfLButtonDown(x,y);
break;
case WM_LBUTTONUP:
SurfLButtonUp();
break;
case WM_MOUSEMOVE:
if(Dat.ButtonDown)
{
x = LOWORD(lParam);
y = HIWORD(lParam);
SurfMouseMove(x,y);
SurfDC(hwnd);
}
break;
case WM_DESTROY:
KillTimer(hwnd, 1);
SurfDestroy();
break;
case WM_KEYDOWN:
switch(wParam)
{
case VK_SPACE:
FlagRotation = 0;
// angl.fi += 10;
// SurfDC(hwnd);
break;
case VK_LEFT:
FlagRotation = 1;
// angl.fi += 10;
// SurfDC(hwnd);
break;
case VK_RIGHT:
FlagRotation = 2;
// angl.fi -= 10;
// SurfDC(hwnd);
break;
case VK_UP:
FlagRotation = 3;
// angl.teta += 10;
// SurfDC(hwnd);
break;
case VK_DOWN:
FlagRotation = 4;
// angl.teta -= 10;
// SurfDC(hwnd);
break;
case VK_DELETE:
if (FlagDesk)
FlagDesk = false;
else
FlagDesk = true;
break;
}
break;
default:
return DefWindowProc(hwnd,msg,wParam,lParam);
}
return 0L;
}
//размеры поля вывода в мировых координатах и в пикселях
double xe1, xe2, ye1, ye2;
int ne1, ne2, me1, me2;
//максимальные длины координатных осей - мировые координтаы
double xmax, ymax, zmax;
//угловые коэффициенты
double sf,cf,st,ct;
//Выполняется при создании окна
void SurfCreate()
{
//размеры поля вывода в мировых координатах и в пикселях
xe1 = -4.5; xe2 = 4.5; ye1 = -4.5; ye2 = 4.5;
ne1 = 100; ne2 = 550; me1 = 440; me2 = 40;
//максимальные длины координатных осей - мировые координтаы
xmax=3., ymax=3., zmax=3.;
//углы поворота системы координат - начальные значения
angl.fi = 30; angl.teta = 60;
//координаты коробки в мировой системе координат
PointCorns();
FlagRotation = 1;
}
//Выполняется при закрытии окна
void SurfDestroy()
{
PostQuitMessage(0); //закрываем окно
}
//Рисует картину в ответ на сообщение WM_PAINT
void SurfPaint(HWND hwnd)
{
PAINTSTRUCT ps;
//получаем контест окна
HDC hdcWin = BeginPaint(hwnd, &ps);
//рисуем графические объекты
DrawOpenGL(hdcWin);
//освобождаем контекст окна
EndPaint(hwnd, &ps);
}
//Рисует картину в ответ на сообщение WM_MOUSEMOVE
void SurfDC(HWND hwnd)
{
//получаем контест окна
HDC hdcWin = GetDC(hwnd);
//рисуем графические объекты
DrawOpenGL(hdcWin);
//освобождаем контекст окна
ReleaseDC(hwnd, hdcWin);
}
//рисуем графические объекты
void Picture(HWND hwnd, HDC hdcWin)
{
//вычисляем синусы и косисинусы новых значений углов поворота
sf=sin(3.14159*angl.fi/180);
cf=cos(3.14159*angl.fi/180);
st=sin(3.14159*angl.teta/180);
ct=cos(3.14159*angl.teta/180);
//создаем контекст памяти связаный с контекстом окна
HDC hdcMem = CreateCompatibleDC(hdcWin);
//создаем битовую карту совместмую с контекстом окна
HBITMAP hBitmap = CreateCompatibleBitmap(hdcWin, ne2, me1);
//помещаем битовую карту в контекст памяти
HBITMAP hBitmapOld = (HBITMAP)SelectObject(hdcMem, hBitmap);
//рисуем OpenGL
// DrawOpenGL(hdcWin, hdcMem);
//устанавливем новые размеры поля вывода для рисования API-функций
ne1 = 395; ne2 = 545; me1 = 190; me2 = 40;
//создание прямоугольной области для вывода углов поворота
HRGN hrgn1 = CreateRectRgn(ne1,me2-30,ne2,me2-2);
//заливаем выделенную область светлоголубым цветом
HBRUSH hBrush0 = CreateSolidBrush(RGB(0xA6,0xCA,0xF0));
FillRgn(hdcMem,hrgn1,hBrush0);
//обведение границы области заданной кистью
HBRUSH hBrush1 = CreateSolidBrush(RGB(0xFF,0xFF,0xC0));
FrameRgn(hdcMem,hrgn1,hBrush1,2,2);
//выводим значения углов поворота в область hrgn1
char ss[10];
SetBkColor(hdcMem,RGB(0xA6,0xCA,0xF0));
SetTextColor(hdcMem,RGB(0,0,0x80));
sprintf(ss,"fi = %4.0lf",angl.fi);
TextOut(hdcMem,(ne1+ne2)/2-70,me2-25,ss,9);
sprintf(ss,"teta = %4.0lf",angl.teta);
TextOut(hdcMem,(ne1+ne2)/2+2,me2-25,ss,11);
//удаляем область hrgn1
DeleteObject(hrgn1);
//создание прямоугольной области в которой рисуем графический объект
HRGN hrgn2 = CreateRectRgn(ne1,me2,ne2,me1);
//заливаем выделенную область светлосерым цветом
HBRUSH hBrush2 = CreateSolidBrush(RGB(0xC0,0xC0,0xC0));
FillRgn(hdcMem,hrgn2,hBrush2);
//ограничиваем область вывода изображения
SelectClipRgn(hdcMem,hrgn2);
//рисуем координатные оси
Axes(hdcMem);
//возвращеме первоначальные размеры окна вывода
ne1 = 100; ne2 = 550; me1 = 440; me2 = 40;
//копируем контекст памяти в контекст окна
BitBlt(hdcWin,ne1,me2-30,ne2,me1,hdcMem,ne1,me2-30,SRCCOPY);
//убираем созданные графические объекты
DeleteObject(hBrush0);
DeleteObject(hBrush1);
DeleteObject(hBrush2);
DeleteObject(hrgn2);
SelectObject(hdcMem, hBitmapOld); //востанавливаем контекст памяти
DeleteObject(hBitmap); //убираем битовую карту
DeleteDC(hdcMem); // освобождаем контекст памяти
}
//рисуем графические объекты OpenGL
void DrawOpenGL(HDC hdcWin)
{
//структура описания формата пикселя
PIXELFORMATDESCRIPTOR pfd;
//зануляем все поля структуры pfd
memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
//заполняем некоторые поля структуры
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 32;
//выбираем наиболее подходящий формат пикселей в контексте окна
int iPixelFormat = ChoosePixelFormat(hdcWin, &pfd);
//устанавливаем найденный формат пикселей в контектсте памяти
SetPixelFormat(hdcWin, iPixelFormat, &pfd);
//получаем контекст отображения OpenGL
HGLRC hglrc = wglCreateContext(hdcWin);
//устанавливаем текущий контекст отображения OpenGL
wglMakeCurrent(hdcWin, hglrc);
//включаем механизм z-буфура
glClearColor(0,0.5,0, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearDepth(1.0);
glEnable(GL_DEPTH_TEST);
// glViewport(100, 0, 450, 400);
//установка матрицы перспективной проекции
// gluPerspective(f,a,zN,zF) f-угол просмотра, a- коэффициент
//пропорциональности, zN- расстояние до ближней плоскости отсечения
// zF- расстояние до дальней плоскости отсечения
gluPerspective(65, (double)1, 3, 40);
//умножение текущей матрицы на матрицу переноса
glTranslatef(0, 0, -10);
//умножение текущей матрицы на матрицу пповорота
glRotatef(90-(GLfloat)angl.teta, 1, 0, 0);
glRotatef(-(GLfloat)angl.fi, 0, 1, 0);
glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
glEnable(GL_LIGHTING);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_NORMALIZE);
//устанавливаем источники света
GLfloat lightpos[4] = {3,3,6,1};
GLfloat lightdirection[3] = {-0.9f,-0.1f,-7.6f};
glLightfv(GL_LIGHT0,GL_POSITION,lightpos);
glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,lightdirection);
glLightf(GL_LIGHT0,GL_SPOT_EXPONENT,4);
glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,50);
glEnable(GL_LIGHT0);
GLfloat lightpos1[4] = { 3, 3, -6, 1 };
GLfloat lightdirection1[3] = { -0.9f, -0.1f, 7.6f };
glLightfv(GL_LIGHT0, GL_POSITION, lightpos1);
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, lightdirection1);
glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 4);
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 50);
glEnable(GL_LIGHT0);
if (FlagDesk)
{
//Шахматное поле
for (int j = -5; j < 5; j++)
for (int i = -5; i < 5; i++)
{
if ((abs(i + j) % 2) == 0)
glColor3f(1, 0, 0);
else
glColor3f(0.8f, 0.8f, 0.8f);
glBegin(GL_QUADS);
glVertex3f((GLfloat)i, 0, (GLfloat)j);
glVertex3f((GLfloat)i + 1, 0, (GLfloat)j);
glVertex3f((GLfloat)i + 1, 0, (GLfloat)j + 1);
glVertex3f((GLfloat)i, 0, (GLfloat)j + 1);
glEnd();
}
}
//axes
glColor3f( 1.0f,1.0f,0.0f);
//толщина линий - 3 пикселей
glLineWidth(3.0);
//OX
glBegin(GL_LINES);
glVertex3f(0.0f,0.25f,0.f);
glVertex3f(5.5f,0.25f,0.f);
glEnd();
//OY
glBegin(GL_LINES);
glVertex3f(0.0f,0.25f,0.0f);
glVertex3f(0.0f,4.25f,0.0f);
glEnd();
//OZ
glBegin(GL_LINES);
glVertex3f(0.0f,0.25f,0.0f);
glVertex3f(0.0f,0.25f,5.5f);
glEnd();
//рисуем усеченную пирамиду
glColor3f(0.0f, 0.0f, 1.0f);
glTranslatef(0, 0, 2);
glBegin(GL_POLYGON);
glVertex3f(1.2f, 1.8f, 0.6f);
glVertex3f(0.8f, 0.1f, 0.0f);
glVertex3f(2.4f, 0.1f, 0.0f);
glVertex3f(2.0f, 1.8f, 0.6f);
glEnd();
glColor3f(0.0f, 0.5f, 1.0f);
glBegin(GL_POLYGON);
glVertex3f(2.0f, 1.8f, 0.6f);
glVertex3f(2.4f, 0.1f, 0.0f);
glVertex3f(3.2f, 0.1f, 1.2f);
glVertex3f(2.4f, 1.8f, 1.2f);
glEnd();
glColor3f(0.2f, 0.5f, 0.0f);
glBegin(GL_POLYGON);
glVertex3f(2.4f, 1.8f, 1.2f);
glVertex3f(3.2f, 0.1f, 1.2f);
glVertex3f(2.4f, 0.1f, 2.4f);
glVertex3f(2.0f, 1.8f, 1.8f);
glEnd();
glColor3f(0.5f, 0.1f, 0.2f);
glBegin(GL_POLYGON);
glVertex3f(2.0f, 1.8f, 1.8f);
glVertex3f(2.4f, 0.1f, 2.4f);
glVertex3f(0.8f, 0.1f, 2.4f);
glVertex3f(1.2f, 1.8f, 1.8f);
glEnd();
glColor3f(1.0f, 0.3f, 0.1f);
glBegin(GL_POLYGON);
glVertex3f(1.2f, 1.8f, 1.8f);
glVertex3f(0.8f, 0.1f, 2.4f);
glVertex3f(0.0f, 0.1f, 1.2f);
glVertex3f(0.8f, 1.8f, 1.2f);
glEnd();
glColor3f(0.3f, 0.3f, 0.3f);
glBegin(GL_POLYGON);
glVertex3f(0.8f, 1.8f, 1.2f);
glVertex3f(0.0f, 0.1f, 1.2f);
glVertex3f(0.8f, 0.1f, 0.0f);
glVertex3f(1.2f, 1.8f, 0.6f);
glEnd();
glColor3f(0.5f, 0.6f, 0.5f);
glBegin(GL_POLYGON);
glVertex3f(1.2f, 1.8f, 0.6f);
glVertex3f(2.0f, 1.8f, 0.6f);
glVertex3f(2.4f, 1.8f, 1.2f);
glVertex3f(2.0f, 1.8f, 1.8f);
glVertex3f(1.2f, 1.8f, 1.8f);
glVertex3f(0.8f, 1.8f, 1.2f);
glEnd();
glBegin(GL_POLYGON);
glVertex3f(0.8f, 0.1f, 0.0f);
glVertex3f(2.4f, 0.1f, 0.0f);
glVertex3f(3.2f, 0.1f, 1.2f);
glVertex3f(2.4f, 0.1f, 2.4f);
glVertex3f(0.8f, 0.1f, 2.4f);
glVertex3f(0.0f, 0.1f, 1.2f);
glEnd();
//////////////////////////////////////////////////
/////////////Отсекающая плоскость/////////////////
//////////////////////////////////////////////////
//GLdouble eqn[4] = {0.0, 1.0, 0.0, 0.0};
//glClipPlane(GL_CLIP_PLANE0, eqn); // идентифицируем плоскость отсечения
//glEnable(GL_CLIP_PLANE0); // включаем первую плоскость отсечения
//////////////////////////////////////////////////
//рисуем сферу
GLUquadricObj *quadricObj;
quadricObj = gluNewQuadric();
glColor3f(0.0f, 0.0f, 1.0f);
glTranslatef(1.4, 3.5, 1.5);
gluSphere(quadricObj, 1.8, 100, 100);
//ожидает завершения всех предыдущих команд OpenGL
SwapBuffers(hdcWin);
//завершаем работу с текущим контекстом отображения
wglMakeCurrent(NULL, NULL);
//освобождаем контекст отображения OpenGL
wglDeleteContext(hglrc);
}
//рисуем координатные оси
void Axes(HDC hdc)
{
//выбираем цвет для координатных осей
HPEN hPen = CreatePen(PS_SOLID,1,RGB(0,255,255));
HPEN hPenOld = (HPEN)SelectObject(hdc,hPen);
//координаты проектируемой точки в видовой системе координат
double xe, ye;
//координаты пикселов
int x1,y1,x2,y2;
//рисуем ось Ox
xe=Xe(-xmax/3,0);
ye=Ye(-xmax/3,0,0);
x1=xn(xe);
y1=ym(ye);
xe=Xe(1.5*xmax,0);
ye=Ye(1.5*xmax,0,0);
x2=xn(xe);
y2=ym(ye);
MoveToEx(hdc,x1,y1,0);
LineTo(hdc,x2,y2);
//делаем надпись на оси заданным цветом
SetBkColor(hdc,RGB(0xC0,0xC0,0xC0));
SetTextColor(hdc,RGB(120,120,120));
TextOut(hdc,x2, y2, "X",1);
//рисуем ось Oy
xe=Xe(0,-ymax/3);
ye=Ye(0,-ymax/3,0);
x1=xn(xe);
y1=ym(ye);
xe=Xe(0,1.5*ymax);
ye=Ye(0,1.5*ymax,0);
x2=xn(xe);
y2=ym(ye);
MoveToEx(hdc,x1,y1,0);
LineTo(hdc,x2,y2);
TextOut(hdc,x2, y2, "Y",1);
//рисуем ось Oz
xe=Xe(0,0);
ye=Ye(0,0,-zmax/3);
x1=xn(xe);
y1=ym(ye);
xe=Xe(0,0);
ye=Ye(0,0,1.5*zmax);
x2=xn(xe);
y2=ym(ye);
MoveToEx(hdc,x1,y1,0);
LineTo(hdc,x2,y2);
TextOut(hdc,x2, y2, "Z",1);
//востанавливаем в контексте старое перо
SelectObject(hdc,hPenOld);
//убираем созданные графические объекты
DeleteObject(hPen);
}
//координаты коробки - в мировой системе координат
void PointCorns()
{
Point[0].x = xmax; Point[0].y = ymax; Point[0].z = -zmax;
Point[1].x = -xmax; Point[1].y = ymax; Point[1].z = -zmax;
Point[2].x = -xmax; Point[2].y = -ymax; Point[2].z = -zmax;
Point[3].x = xmax; Point[3].y = -ymax; Point[3].z = -zmax;
Point[4].x = xmax; Point[4].y = ymax; Point[4].z = zmax;
Point[5].x = -xmax; Point[5].y = ymax; Point[5].z = zmax;
Point[6].x = -xmax; Point[6].y = -ymax; Point[6].z = zmax;
Point[7].x = xmax; Point[7].y = -ymax; Point[7].z = zmax;
}
//рисует коробку
void DrawBox(HDC hdc, ANGLS an)
{
HPEN hPen = CreatePen(PS_SOLID,1,RGB(160,160,160));
HPEN hPenOld = (HPEN)SelectObject(hdc,hPen);
double xe, ye;
int x1,y1,x2,y2;
double xt1,yt1,zt1,xt2,yt2,zt2;
int j;
for(int i=0; i<4; i++)
{
j = i + 1;
if(j==4)
j = 0;
xt1 = Point[i].x; yt1 = Point[i].y; zt1 = Point[i].z;
xt2 = Point[j].x; yt2 = Point[j].y; zt2 = Point[j].z;
xe=Xe(xt1,yt1);
ye=Ye(xt1,yt1,zt1);
x1=xn(xe);
y1=ym(ye);
xe=Xe(xt2,yt2);
ye=Ye(xt2,yt2,zt2);
x2=xn(xe);
y2=ym(ye);
MoveToEx(hdc,x1,y1,0);
LineTo(hdc,x2,y2);
}
for(int i=4; i<8; i++)
{
j = i + 1;
if(j==8)
j = 4;
xt1 = Point[i].x; yt1 = Point[i].y; zt1 = Point[i].z;
xt2 = Point[j].x; yt2 = Point[j].y; zt2 = Point[j].z;
xe=Xe(xt1,yt1);
ye=Ye(xt1,yt1,zt1);
x1=xn(xe);
y1=ym(ye);
xe=Xe(xt2,yt2);
ye=Ye(xt2,yt2,zt2);
x2=xn(xe);
y2=ym(ye);
MoveToEx(hdc,x1,y1,0);
LineTo(hdc,x2,y2);
}
for(int i=0; i<4; i++)
{
xt1 = Point[i].x; yt1 = Point[i].y; zt1 = Point[i].z;
xt2 = Point[i+4].x; yt2 = Point[i+4].y; zt2 = Point[i+4].z;
xe=Xe(xt1,yt1);
ye=Ye(xt1,yt1,zt1);
x1=xn(xe);
y1=ym(ye);
xe=Xe(xt2,yt2);
ye=Ye(xt2,yt2,zt2);
x2=xn(xe);
y2=ym(ye);
MoveToEx(hdc,x1,y1,0);
LineTo(hdc,x2,y2);
}
for(int i=0; i<2; i++)
{
xt1 = Point[i].x; yt1 = Point[i].y; zt1 = Point[i].z;
xt2 = Point[i+2].x; yt2 = Point[i+2].y; zt2 = Point[i+2].z;
xe=Xe(xt1,yt1);
ye=Ye(xt1,yt1,zt1);
x1=xn(xe);
y1=ym(ye);
xe=Xe(xt2,yt2);
ye=Ye(xt2,yt2,zt2);
x2=xn(xe);
y2=ym(ye);
MoveToEx(hdc,x1,y1,0);
LineTo(hdc,x2,y2);
}
//востанавливаем в контексте старое перо
SelectObject(hdc,hPenOld);
DeleteObject(hPen);
}
//переход в видовую систему координат и отрографическое проектирование
inline double Xe(double x,double y)
{
return -sf*x+cf*y;
}
//переход в видовую систему координат и отрографическое проектирование
inline double Ye(double x,double y,double z)
{
return -ct*cf*x-ct*sf*y+st*z;
}
//перевод видовых координат в координты пикселей
//переход от координаты x к пикселю n
inline int xn(double x)
{
return (int)((x - xe1)/(xe2 - xe1)*(ne2 - ne1)) + ne1;
}
//переход от координаты y к пикселю m
inline int ym(double y)
{
return (int)((y - ye1)/(ye2 - ye1)*(me2 - me1)) + me1;
}
//при нажатии левой кнопки мыши
void SurfLButtonDown( int x, int y)
{
Dat.ButtonDown = TRUE;
Dat.Drawing = FALSE;
anglOld.fi = angl.fi;
anglOld.teta = angl.teta;
corOld.x = x;
corOld.y = y;
}
//при движении мыши и нажатой левой кнопки мыши
void SurfMouseMove(int x, int y)
{
if(Dat.ButtonDown)
{
Dat.Drawing = TRUE;
angl.fi += corOld.x-x;
angl.teta += corOld.y-y;
corOld.x = x; corOld.y = y;
anglOld.fi = angl.fi;
anglOld.teta = angl.teta;
}
}
//устанавливает нужные флаги при отпускании правой кнопки мыши
void SurfLButtonUp()
{
if(Dat.ButtonDown && Dat.Drawing)
{
Dat.Drawing = FALSE;
}
Dat.ButtonDown = FALSE;
}