//---------------------------------------------------------------------------
#include <windows.h>
#include <math.h>
#include "resource.h"
#include <stdio.h>
#include "matrix.h"
#include "bmp.h"
#define CM_SAVEBMP 10001
#define NC 6
#define NL 12
#define NS 8
int Width=150,
Height=300,
centr_x=0,
centr_y=0,
centr_z=0,
angle=45,
rotate_x=1,
rotate_y=1,
rotate_z=0,
R=100,
G=100,
B=100,
int_x=0,
int_y=0,
int_z=500;
double intens=5;
Vector *v=new Vector[NC];
Vector proect(17,22,1080);
BOOL visible[NS];
const int edge[NL][2]={{1,2},{1,3},{1,4},{1,5},{2,3},{3,4},
{4,5},{5,2},{2,6},{3,6},{4,6},{5,6}};
const int side[NS][3]= {{1,2,3},{1,3,4},{1,4,5},{1,5,2},
{2,6,3},{3,6,4},{4,6,5},{5,6,2}};
HMENU hmenu;
HINSTANCE hInst;
HWND hchild1,hchild2,hchild3;
LRESULT CALLBACK _export WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK _export ChildWndProc1(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK _export ChildWndProc2(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK _export ChildWndProc3(HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK DlgProc(HWND,UINT,WPARAM,LPARAM);
void DrawFig(HDC hdc, Vector []);
void DrawGuro(HDC hdc, Vector []);
void DrawFong(HDC hdc, Vector []);
void SetVector();
void Transform(Matrix,Vector);
void FaceSides();
Vector Normal(const int Side[]);
char *GetSaveFileName(HWND);
char const szClassName[]="WindowAppClass";
char const szChildClassName1[]="ChildClass1";
char const szChildClassName2[]="ChildClass2";
char const szChildClassName3[]="ChildClass3";
char const szWindowTitle[]="Бычков Василий ММ-494; Лабораторная работа №5";
BOOL InitApp(HINSTANCE);
int PASCAL WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
HWND hwnd;
hInst=hInstance;
hwnd = FindWindow(szClassName, NULL);
if(hwnd)
{
if(IsIconic(hwnd))
ShowWindow(hwnd, SW_RESTORE);
SetForegroundWindow(hwnd);
return FALSE;
}
InitApp(hInstance);
hwnd=CreateWindow(szClassName, szWindowTitle, WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX,
100,50,800,700,0,0, hInstance, NULL);
hchild1=CreateWindow(szChildClassName1,"",WS_CHILDWINDOW |WS_VISIBLE |WS_BORDER,
5,40,250,600,hwnd,0,hInstance,NULL);
hchild2=CreateWindow(szChildClassName2,"",WS_CHILDWINDOW |WS_VISIBLE |WS_BORDER,
270,40,250,600,hwnd,0,hInstance,NULL);
hchild3=CreateWindow(szChildClassName3,"",WS_CHILDWINDOW |WS_VISIBLE |WS_BORDER,
535,40,250,600,hwnd,0,hInstance,NULL);
CreateWindow("static", "Однотонная закраска",WS_CHILD | WS_VISIBLE,
50,10,150,20, hwnd, (HMENU)0, hInstance, NULL);
CreateWindow("static", "Закраска методом Гуро",WS_CHILD | WS_VISIBLE,
310,10,200,20, hwnd, (HMENU)0, hInstance, NULL);
CreateWindow("static", "Закраска методом Фонга",WS_CHILD | WS_VISIBLE,
565,10,200,20, hwnd, (HMENU)0, hInstance, NULL);
if(!hwnd)
return FALSE;
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&msg, 0, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
BOOL InitApp(HINSTANCE hInstance)
{
ATOM aWndClass;
WNDCLASS wc;
memset(&wc, 0, sizeof(wc));
wc.style = 0;
wc.lpfnWndProc = (WNDPROC) WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = (HICON)LoadBitmap(hInstance,MAKEINTRESOURCE(100));
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(225,225,225));
wc.lpszMenuName = (LPSTR)NULL;
wc.lpszClassName = (LPSTR)szClassName;
aWndClass = RegisterClass(&wc);
if(aWndClass == 0) return false;
wc.lpfnWndProc = (WNDPROC) ChildWndProc1;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszClassName = (LPSTR)szChildClassName1;
aWndClass = RegisterClass(&wc);
if(aWndClass == 0) return false;
wc.lpfnWndProc = (WNDPROC) ChildWndProc2;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszClassName = (LPSTR)szChildClassName2;
aWndClass = RegisterClass(&wc);
if(aWndClass == 0) return false;
wc.lpfnWndProc = (WNDPROC) ChildWndProc3;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszClassName = (LPSTR)szChildClassName3;
aWndClass = RegisterClass(&wc);
if(aWndClass == 0) return false;
return true;
}
LRESULT CALLBACK _export
WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
switch (msg)
{
case WM_CREATE:
{
hmenu = CreateMenu();
SetMenu(hwnd, hmenu);
AppendMenu(hmenu, MF_ENABLED|MF_STRING, CM_SAVEBMP, "&Сохранить");
DrawMenuBar(hwnd);
Vector trans(centr_x,centr_y,centr_z);
Vector scale(Width,Height,Width);
Transform(Scale(scale),trans);
FaceSides();
break;
}
case WM_RBUTTONDOWN:
{
if(DialogBox(hInst,MAKEINTRESOURCE(IDD_DIALOG), hwnd,(DLGPROC) DlgProc))
break;
Vector translate(centr_x,centr_y,centr_z);
Vector scaling(Width,Height,Width);
Transform(Scale(scaling),translate);
FaceSides();
InvalidateRect(hchild1, NULL, true);
UpdateWindow(hchild1);
InvalidateRect(hchild2, NULL, true);
UpdateWindow(hchild2);
InvalidateRect(hchild3, NULL, true);
UpdateWindow(hchild3);
break;
}
case WM_LBUTTONDOWN:
{
angle+=5;
Vector translate(centr_x,centr_y,centr_z);
Vector scaling(Width,Height,Width);
Transform(Scale(scaling),translate);
FaceSides();
InvalidateRect(hchild1, NULL, true);
UpdateWindow(hchild1);
InvalidateRect(hchild2, NULL, true);
UpdateWindow(hchild2);
InvalidateRect(hchild3, NULL, true);
UpdateWindow(hchild3);
break;
}
case WM_COMMAND:
{
if (LOWORD(wParam)==CM_SAVEBMP)
{
HBITMAP hBitmap;
RECT rc;
HDC hdcSave;
hdc=GetDC(hwnd);
SetMapMode(hdc,MM_ANISOTROPIC);
SetViewportOrgEx(hdc, 0, 0, NULL);
hdcSave=CreateCompatibleDC(hdc);
GetClientRect(hwnd, &rc);
hBitmap=CreateCompatibleBitmap(hdc, rc.right, rc.bottom);
SelectObject(hdcSave, hBitmap);
BitBlt(hdcSave, 0, 0, rc.right, rc.bottom, hdc, 0,0, SRCCOPY);
CreateBMPFile(hwnd, GetSaveFileName(hwnd), CreateBitmapInfoStruct(hwnd, hBitmap), hBitmap, hdc);
DeleteObject(hdcSave);
DeleteObject(hBitmap);
ReleaseDC(hwnd, hdc);
break;
}
}
case WM_DESTROY:
{
delete [] v;
PostQuitMessage(0);
break;
}
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
LRESULT CALLBACK _export
ChildWndProc1(HWND hwnd, UINT msg,WPARAM wParam, LPARAM lParam)
{
HDC hdc;
switch (msg)
{
case WM_RBUTTONDOWN:
{
if(DialogBox(hInst,MAKEINTRESOURCE(IDD_DIALOG), hwnd,(DLGPROC) DlgProc))
break;
Vector translate(centr_x,centr_y,centr_z);
Vector scaling(Width,Height,Width);
Transform(Scale(scaling),translate);
FaceSides();
InvalidateRect(hchild1, NULL, true);
UpdateWindow(hchild1);
InvalidateRect(hchild2, NULL, true);
UpdateWindow(hchild2);
InvalidateRect(hchild3, NULL, true);
UpdateWindow(hchild3);
break;
}
case WM_LBUTTONDOWN:
{
angle+=5;
Vector translate(centr_x,centr_y,centr_z);
Vector scaling(Width,Height,Width);
Transform(Scale(scaling),translate);
FaceSides();
InvalidateRect(hchild1, NULL, true);
UpdateWindow(hchild1);
InvalidateRect(hchild2, NULL, true);
UpdateWindow(hchild2);
InvalidateRect(hchild3, NULL, true);
UpdateWindow(hchild3);
break;
}
case WM_PAINT:
{
PAINTSTRUCT ps;
RECT rc;
HDC hdcBuf;
HBITMAP bitBuf;
hdc = BeginPaint(hwnd,&ps);
GetClientRect(hwnd,&rc);
bitBuf = CreateCompatibleBitmap(hdc,rc.right,rc.bottom);
hdcBuf = CreateCompatibleDC(hdc);
SelectObject(hdcBuf, bitBuf);
FillRect(hdcBuf,&rc, CreateSolidBrush(RGB(255,255,255)));
SetMapMode(hdc,MM_ANISOTROPIC);
SetWindowExtEx(hdc,1,-1,NULL);
SetViewportOrgEx(hdc,rc.right/2,rc.bottom/2,NULL);
SetMapMode(hdcBuf,MM_ANISOTROPIC);
SetWindowExtEx(hdcBuf,1,-1,NULL);
SetViewportOrgEx(hdcBuf,rc.right/2,rc.bottom/2,NULL);
DrawFig(hdcBuf,v);
BitBlt(hdc,-rc.right/2,-rc.bottom/2,rc.right,rc.bottom,hdcBuf,-rc.right/2,-rc.bottom/2,SRCCOPY);
DeleteObject(bitBuf);
DeleteDC(hdcBuf);
DeleteDC(hdc);
EndPaint(hwnd,&ps);
break;
}
case WM_DESTROY:
{
PostQuitMessage(0);
break;
}
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
LRESULT CALLBACK _export
ChildWndProc2(HWND hwnd, UINT msg,WPARAM wParam, LPARAM lParam)
{
HDC hdc;
switch (msg)
{
case WM_RBUTTONDOWN:
{
if(DialogBox(hInst,MAKEINTRESOURCE(IDD_DIALOG), hwnd,(DLGPROC) DlgProc))
break;
Vector translate(centr_x,centr_y,centr_z);
Vector scaling(Width,Height,Width);
Transform(Scale(scaling),translate);
FaceSides();
InvalidateRect(hchild1, NULL, true);
UpdateWindow(hchild1);
InvalidateRect(hchild2, NULL, true);
UpdateWindow(hchild2);
InvalidateRect(hchild3, NULL, true);
UpdateWindow(hchild3);
break;
}
case WM_LBUTTONDOWN:
{
angle+=5;
Vector translate(centr_x,centr_y,centr_z);
Vector scaling(Width,Height,Width);
Transform(Scale(scaling),translate);
FaceSides();
InvalidateRect(hchild1, NULL, true);
UpdateWindow(hchild1);
InvalidateRect(hchild2, NULL, true);
UpdateWindow(hchild2);
InvalidateRect(hchild3, NULL, true);
UpdateWindow(hchild3);
break;
}
case WM_PAINT:
{
PAINTSTRUCT ps;
RECT rc;
HDC hdcBuf;
HBITMAP bitBuf;
hdc = BeginPaint(hwnd,&ps);
GetClientRect(hwnd,&rc);
bitBuf = CreateCompatibleBitmap(hdc,rc.right,rc.bottom);
hdcBuf = CreateCompatibleDC(hdc);
SelectObject(hdcBuf, bitBuf);
FillRect(hdcBuf,&rc, CreateSolidBrush(RGB(255,255,255)));
SetMapMode(hdc,MM_ANISOTROPIC);
SetWindowExtEx(hdc,1,-1,NULL);
SetViewportOrgEx(hdc,rc.right/2,rc.bottom/2,NULL);
SetMapMode(hdcBuf,MM_ANISOTROPIC);
SetWindowExtEx(hdcBuf,1,-1,NULL);
SetViewportOrgEx(hdcBuf,rc.right/2,rc.bottom/2,NULL);
DrawGuro(hdcBuf,v);
BitBlt(hdc,-rc.right/2,-rc.bottom/2,rc.right,rc.bottom,hdcBuf,-rc.right/2,-rc.bottom/2,SRCCOPY);
DeleteObject(bitBuf);
DeleteDC(hdcBuf);
DeleteDC(hdc);
EndPaint(hwnd,&ps);
break;
}
case WM_DESTROY:
{
PostQuitMessage(0);
break;
}
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
LRESULT CALLBACK _export
ChildWndProc3(HWND hwnd, UINT msg,WPARAM wParam, LPARAM lParam)
{
HDC hdc;
switch (msg)
{
case WM_RBUTTONDOWN:
{
if(DialogBox(hInst,MAKEINTRESOURCE(IDD_DIALOG), hwnd,(DLGPROC) DlgProc))
break;
Vector translate(centr_x,centr_y,centr_z);
Vector scaling(Width,Height,Width);
Transform(Scale(scaling),translate);
FaceSides();
InvalidateRect(hchild1, NULL, true);
UpdateWindow(hchild1);
InvalidateRect(hchild2, NULL, true);
UpdateWindow(hchild2);
InvalidateRect(hchild3, NULL, true);
UpdateWindow(hchild3);
break;
}
case WM_LBUTTONDOWN:
{
angle+=5;
Vector translate(centr_x,centr_y,centr_z);
Vector scaling(Width,Height,Width);
Transform(Scale(scaling),translate);
FaceSides();
InvalidateRect(hchild1, NULL, true);
UpdateWindow(hchild1);
InvalidateRect(hchild2, NULL, true);
UpdateWindow(hchild2);
InvalidateRect(hchild3, NULL, true);
UpdateWindow(hchild3);
return 0;
}
case WM_PAINT:
{
PAINTSTRUCT ps;
RECT rc;
HDC hdcBuf;
HBITMAP bitBuf;
hdc = BeginPaint(hwnd,&ps);
GetClientRect(hwnd,&rc);
bitBuf = CreateCompatibleBitmap(hdc,rc.right,rc.bottom);
hdcBuf = CreateCompatibleDC(hdc);
SelectObject(hdcBuf, bitBuf);
FillRect(hdcBuf,&rc, CreateSolidBrush(RGB(255,255,255)));
SetMapMode(hdc,MM_ANISOTROPIC);
SetWindowExtEx(hdc,1,-1,NULL);
SetViewportOrgEx(hdc,rc.right/2,rc.bottom/2,NULL);
SetMapMode(hdcBuf,MM_ANISOTROPIC);
SetWindowExtEx(hdcBuf,1,-1,NULL);
SetViewportOrgEx(hdcBuf,rc.right/2,rc.bottom/2,NULL);
DrawFong(hdcBuf,v);
BitBlt(hdc,-rc.right/2,-rc.bottom/2,rc.right,rc.bottom,hdcBuf,-rc.right/2,-rc.bottom/2,SRCCOPY);
DeleteObject(bitBuf);
DeleteDC(hdcBuf);
DeleteDC(hdc);
EndPaint(hwnd,&ps);
break;
}
case WM_DESTROY:
{
PostQuitMessage(0);
break;
}
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
BOOL CALLBACK DlgProc(HWND hDlg,UINT msg,WPARAM wParam,LPARAM lPrarm)
{
char buf[15];
switch(msg)
{
case WM_INITDIALOG:
{
sprintf(buf,"%d\0", Width);
SetDlgItemText(hDlg,IDC_WIDTH,buf);
sprintf(buf,"%d\0", Height);
SetDlgItemText(hDlg,IDC_HEIGHT,buf);
sprintf(buf,"%d\0", centr_x);
SetDlgItemText(hDlg,IDC_CENTRX,buf);
sprintf(buf,"%d\0", centr_y);
SetDlgItemText(hDlg,IDC_CENTRY,buf);
sprintf(buf,"%d\0", centr_z);
SetDlgItemText(hDlg,IDC_CENTRZ,buf);
sprintf(buf,"%d\0", angle);
SetDlgItemText(hDlg,IDC_UGOL,buf);
sprintf(buf,"%d\0", rotate_x);
SetDlgItemText(hDlg,IDC_VECTORX,buf);
sprintf(buf,"%d\0", rotate_y);
SetDlgItemText(hDlg,IDC_VECTORY,buf);
sprintf(buf,"%d\0", rotate_z);
SetDlgItemText(hDlg,IDC_VECTORZ,buf);
sprintf(buf,"%d\0", R);
SetDlgItemText(hDlg,IDC_CLRR,buf);
sprintf(buf,"%d\0", G);
SetDlgItemText(hDlg,IDC_CLRG,buf);
sprintf(buf,"%d\0", B);
SetDlgItemText(hDlg,IDC_CLRB,buf);
sprintf(buf,"%d\0", int_x);
SetDlgItemText(hDlg,IDC_INTX,buf);
sprintf(buf,"%d\0", int_y);
SetDlgItemText(hDlg,IDC_INTY,buf);
sprintf(buf,"%d\0", int_z);
SetDlgItemText(hDlg,IDC_INTZ,buf);
sprintf(buf,"%.1f\0", intens);
SetDlgItemText(hDlg,IDC_INTENS,buf);
return true;
}
case WM_COMMAND:
{
if(LOWORD(wParam) == IDC_OK)
{
if(GetWindowText(GetDlgItem(hDlg, IDC_WIDTH), buf, 15) == 0) break;
if(sscanf(buf, "%d", &Width) == 0) break;
if(GetWindowText(GetDlgItem(hDlg, IDC_HEIGHT), buf, 15) == 0) break;
if(sscanf(buf, "%d", &Height) == 0) break;
if(GetWindowText(GetDlgItem(hDlg, IDC_CENTRX), buf, 15) == 0) break;
if(sscanf(buf, "%d", ¢r_x) == 0) break;
if(GetWindowText(GetDlgItem(hDlg, IDC_CENTRY), buf, 15) == 0) break;
if(sscanf(buf, "%d", ¢r_y) == 0) break;
if(GetWindowText(GetDlgItem(hDlg, IDC_CENTRZ), buf, 15) == 0) break;
if(sscanf(buf, "%d", ¢r_z) == 0) break;
if(GetWindowText(GetDlgItem(hDlg, IDC_VECTORX), buf, 15) == 0) break;
if(sscanf(buf, "%d", &rotate_x) == 0) break;
if(GetWindowText(GetDlgItem(hDlg, IDC_VECTORY), buf, 15) == 0) break;
if(sscanf(buf, "%d", &rotate_y) == 0) break;
if(GetWindowText(GetDlgItem(hDlg, IDC_VECTORZ), buf, 15) == 0) break;
if(sscanf(buf, "%d", &rotate_z) == 0) break;
if(GetWindowText(GetDlgItem(hDlg, IDC_UGOL), buf, 15) == 0) break;
if(sscanf(buf, "%d", &angle) == 0) break;
if(GetWindowText(GetDlgItem(hDlg, IDC_CLRR), buf, 15) == 0) break;
if(sscanf(buf, "%d", &R) == 0) break;
if(GetWindowText(GetDlgItem(hDlg, IDC_CLRG), buf, 15) == 0) break;
if(sscanf(buf, "%d", &G) == 0) break;
if(GetWindowText(GetDlgItem(hDlg, IDC_CLRB), buf, 15) == 0) break;
if(sscanf(buf, "%d", &B) == 0) break;
if(GetWindowText(GetDlgItem(hDlg, IDC_INTX), buf, 15) == 0) break;
if(sscanf(buf, "%d", &int_x) == 0) break;
if(GetWindowText(GetDlgItem(hDlg, IDC_INTY), buf, 15) == 0) break;
if(sscanf(buf, "%d", &int_y) == 0) break;
if(GetWindowText(GetDlgItem(hDlg, IDC_INTZ), buf, 15) == 0) break;
if(sscanf(buf, "%d", &int_z) == 0) break;
if(GetWindowText(GetDlgItem(hDlg, IDC_INTENS), buf, 15) == 0) break;
intens=atof(buf);
EndDialog(hDlg,0); break;
}
if(LOWORD(wParam) == IDC_CANCEL || LOWORD(wParam) == IDCANCEL)
EndDialog(hDlg,1);break;
}
}
return false;
}
void SetVector()
{
v[0].x = 0; v[0].y = 1; v[0].z = 0;
v[1].x = -0.5; v[1].y = 0; v[1].z = -0.5;
v[2].x = 0.5; v[2].y = 0; v[2].z = -0.5;
v[3].x = 0.5; v[3].y = 0; v[3].z = 0.5;
v[4].x = -0.5; v[4].y = 0; v[4].z = 0.5;
v[5].x = 0; v[5].y = -1; v[5].z = 0;
}
void DrawFig(HDC hdc, Vector vec[])
{
int red,grn,blu;
Vector intens_v(int_x,int_y,int_z),max,mid,min,max1,min1,v1,v2,n,T;
double Int,d;
for (int i = 0; i < NS; i++)
{
if(!visible[i]) continue;
n=Normal(side[i]);
T=((vec[side[i][0]-1]+vec[side[i][1]-1])/2+vec[side[i][2]-1])/2;
T=T-intens_v;
d=pow(T.x*T.x+T.y*T.y+T.z*T.z,0.5);
Vector r=2*((Normalize(n)&Normalize(intens_v)))*n-Normalize(intens_v);
Int=2.5*0.5 + intens*(0.8*(n&Normalize(intens_v))+0.3*(n&Normalize(r)));
if(Int<2.0) Int=2.0;
red=R*Int/3; grn=G*Int/3; blu=B*Int/3;
if(red>255) red=255; if(grn>255) grn=255; if(blu>255) blu=255;
HPEN hPen=CreatePen(PS_SOLID,3, RGB(red,grn,blu));
SelectObject(hdc, hPen);
if(vec[side[i][0]-1].y>vec[side[i][1]-1].y&&vec[side[i][0]-1].y>vec[side[i][2]-1].y)
{
max=vec[side[i][0]-1];
if(vec[side[i][1]-1].y>vec[side[i][2]-1].y)
{
mid=vec[side[i][1]-1];
min=vec[side[i][2]-1];
}
else
{
mid=vec[side[i][2]-1];
min=vec[side[i][1]-1];
}
}
else
{
if(vec[side[i][1]-1].y>vec[side[i][2]-1].y)
{
max=vec[side[i][1]-1];
if(vec[side[i][0]-1].y>vec[side[i][2]-1].y)
{
mid=vec[side[i][0]-1];
min=vec[side[i][2]-1];
}
else
{
mid=vec[side[i][2]-1];
min=vec[side[i][0]-1];
}
}
else
{
max=vec[side[i][2]-1];
if(vec[side[i][0]-1].y>vec[side[i][1]-1].y)
{
mid=vec[side[i][0]-1];
min=vec[side[i][1]-1];
}
else
{
mid=vec[side[i][1]-1];
min=vec[side[i][0]-1];
}
}
}
max1=max; min1=mid;
for(double j=max.y;j>=min.y;j-=0.5)
{
if(j<=mid.y)
{
max1=mid; min1=min;
}
if(max1.y!=min1.y)
{
v1=(1-(max1.y-j)/(max1.y-min1.y))*max1+(max1.y-j)/(max1.y-min1.y)*min1;
v2=(1-(max.y-j)/(max.y-min.y))*max+(max.y-j)/(max.y-min.y)*min;
}
else
{
v1=max1;
v2=min1;
}
MoveToEx(hdc,v1.x,v1.y,NULL);
LineTo(hdc,v2.x,v2.y);
}
DeleteObject(hPen);
}
}
void Transform(Matrix scale, Vector trans)
{
SetVector();
double a=rotate_z, b=rotate_x, c=rotate_y,
d1=pow(a*a+b*b,0.5), d2=pow(a*a+b*b+c*c,0.5);
Matrix rot_y, rot_x;
Matrix P(1);
if(a!=0||b!=0)
{
if((b>=0&&a>=0)||(b<0&&a<0))
rot_y=RotateY(asin(b/d1));
else
{
if(b>=0)
rot_y=RotateY(acos(a/d1));
else
rot_y=RotateY(-acos(a/d1));
}
rot_x=RotateX(acos(c/d2));
P=rot_y*rot_x*RotateY(angle*M_PI/180);
rot_x.Invert(); rot_y.Invert();
P=P*rot_x*rot_y;
}
else
{
rot_y=RotateY(0);
rot_x=RotateX(0);
if(c>0)
{
P=rot_y*rot_x*RotateY(angle*M_PI/180);
rot_x.Invert(); rot_y.Invert();
P=P*rot_x*rot_y;
}
if(c<0)
{
P=rot_y*rot_x*RotateY(-angle*M_PI/180);
rot_x.Invert(); rot_y.Invert();
P=P*rot_x*rot_y;
}
}
for(int i=0;i<NC;i++)
{
Vector v_cur(0,0,0);
v[i]=scale*P*v[i]+trans;
v_cur.x=(v[i].x-v[i].z*proect.x/proect.z)/(1-v[i].z/proect.z);
v_cur.y=(v[i].y-v[i].z*proect.y/proect.z)/(1-v[i].z/proect.z);
v_cur.z=v[i].z;
v[i]=v_cur;
}
}
void DrawGuro(HDC hdc, Vector vec[])
{
int red,grn,blu;
Vector intens_v(int_x,int_y,int_z),max,mid,min,max1,min1,v1,v2;
double Int[3],d,maxI,midI,minI,maxI1,minI1,I1,I2;
for(int i=0;i<NS;i++)
{
if(!visible[i]) continue;
for(int g=0;g<3;g++)
{
int ns=0;
d=pow(vec[side[i][g]-1].x*vec[side[i][g]-1].x+vec[side[i][g]-1].y*
vec[side[i][g]-1].y+vec[side[i][g]-1].z*vec[side[i][g]-1].z,0.5);
Vector n(0,0,0);
for(int j=0;j<NS;j++)
{
for(int l=0;l<3;l++)
{
if(side[i][g]==side[j][l])
n=n+Normal(side[j]);
}
}
n=Normalize(n);
Vector r=2*((Normalize(n)&Normalize(intens_v)))*n-Normalize(intens_v);
Int[g]=2.5*0.5 + intens*(0.8*(n&Normalize(intens_v))+0.3*(n&Normalize(r)));
}
if(vec[side[i][0]-1].y>vec[side[i][1]-1].y&&vec[side[i][0]-1].y>vec[side[i][2]-1].y)
{
max=vec[side[i][0]-1]; maxI=Int[0];
if(vec[side[i][1]-1].y>vec[side[i][2]-1].y)
{
mid=vec[side[i][1]-1]; midI=Int[1];
min=vec[side[i][2]-1]; minI=Int[2];
}
else
{
mid=vec[side[i][2]-1]; midI=Int[2];
min=vec[side[i][1]-1]; minI=Int[1];
}
}
else
{
if(vec[side[i][1]-1].y>vec[side[i][2]-1].y)
{
max=vec[side[i][1]-1]; maxI=Int[1];
if(vec[side[i][0]-1].y>vec[side[i][2]-1].y)
{
mid=vec[side[i][0]-1]; midI=Int[0];
min=vec[side[i][2]-1]; minI=Int[2];
}
else
{
mid=vec[side[i][2]-1]; midI=Int[2];
min=vec[side[i][0]-1]; minI=Int[0];
}
}
else
{
max=vec[side[i][2]-1]; maxI=Int[2];
if(vec[side[i][0]-1].y>vec[side[i][1]-1].y)
{
mid=vec[side[i][0]-1]; midI=Int[0];
min=vec[side[i][1]-1]; minI=Int[1];
}
else
{
mid=vec[side[i][1]-1]; midI=Int[1];
min=vec[side[i][0]-1]; minI=Int[0];
}
}
}
max1=max; min1=mid; maxI1=maxI; minI1=midI;
for(double j=max.y;j>=min.y;j-=0.5)
{
if(j<=mid.y)
{
max1=mid; min1=min; maxI1=midI; minI1=minI;
}
if(max1.y!=min1.y)
{
v1=(1-(max1.y-j)/(max1.y-min1.y))*max1+(max1.y-j)/(max1.y-min1.y)*min1;
v2=(1-(max.y-j)/(max.y-min.y))*max+(max.y-j)/(max.y-min.y)*min;
I1=(1-(max1.y-j)/(max1.y-min1.y))*maxI1+(max1.y-j)/(max1.y-min1.y)*minI1;
I2=(1-(max.y-j)/(max.y-min.y))*maxI+(max.y-j)/(max.y-min.y)*minI;
}
else
{
v1=max1;
v2=min1;
I1=maxI1;
I2=minI1;
}
Vector vt,maxX,minX;
double maxXI,minXI,It;
if(v1.x>v2.x)
{
maxX=v1; minX=v2; maxXI=I1; minXI=I2;
}
else
{
maxX=v2; minX=v1; maxXI=I2; minXI=I1;
}
for(double l=maxX.x;l>=minX.x;l-=0.5)
{
if(minX.x!=maxX.x)
{
vt=(1-(maxX.x-l)/(maxX.x-minX.x))*maxX+(maxX.x-l)/(maxX.x-minX.x)*minX;
It=(1-(maxX.x-l)/(maxX.x-minX.x))*maxXI+(maxX.x-l)/(maxX.x-minX.x)*minXI;
}
else
{
vt=maxX; It=maxXI;
}
if(It<2.0) It=2.0;
red=R*It/2; grn=G*It/2; blu=B*It/2;
if(red>255) red=255; if(grn>255) grn=255; if(blu>255) blu=255;
SetPixel(hdc,vt.x,vt.y,RGB(red,grn,blu));
}
}
}
}
void DrawFong(HDC hdc, Vector vec[])
{
int red,grn,blu;
Vector intens_v(int_x,int_y,int_z),max,mid,min,max1,min1,v1,v2,N[3],
maxN,midN,minN,maxN1,minN1,N1,N2;
double d;
for (int i = 0; i < NS; i++)
{
if(!visible[i]) continue;
for(int g=0;g<3;g++)
{
int ns=0;
Vector n(0,0,0);
for(int j=0;j<NS;j++)
{
for(int l=0;l<3;l++)
{
if(side[i][g]==side[j][l])
n=n+Normal(side[j]);
}
}
N[g]=Normalize(n);
}
if(vec[side[i][0]-1].y>vec[side[i][1]-1].y&&vec[side[i][0]-1].y>vec[side[i][2]-1].y)
{
max=vec[side[i][0]-1]; maxN=N[0];
if(vec[side[i][1]-1].y>vec[side[i][2]-1].y)
{
mid=vec[side[i][1]-1]; midN=N[1];
min=vec[side[i][2]-1]; minN=N[2];
}
else
{
mid=vec[side[i][2]-1]; midN=N[2];
min=vec[side[i][1]-1]; minN=N[1];
}
}
else
{
if(vec[side[i][1]-1].y>vec[side[i][2]-1].y)
{
max=vec[side[i][1]-1]; maxN=N[1];
if(vec[side[i][0]-1].y>vec[side[i][2]-1].y)
{
mid=vec[side[i][0]-1]; midN=N[0];
min=vec[side[i][2]-1]; minN=N[2];
}
else
{
mid=vec[side[i][2]-1]; midN=N[2];
min=vec[side[i][0]-1]; minN=N[0];
}
}
else
{
max=vec[side[i][2]-1]; maxN=N[2];
if(vec[side[i][0]-1].y>vec[side[i][1]-1].y)
{
mid=vec[side[i][0]-1]; midN=N[0];
min=vec[side[i][1]-1]; minN=N[1];
}
else
{
mid=vec[side[i][1]-1]; midN=N[1];
min=vec[side[i][0]-1]; minN=N[0];
}
}
}
max1=max; min1=mid; maxN1=maxN; minN1=midN;
for(double j=max.y;j>=min.y;j-=0.5)
{
if(j<=mid.y)
{
max1=mid; min1=min; maxN1=midN; minN1=minN;
}
if(max1.y!=min1.y)
{
v1=(1-(max1.y-j)/(max1.y-min1.y))*max1+(max1.y-j)/(max1.y-min1.y)*min1;
v2=(1-(max.y-j)/(max.y-min.y))*max+(max.y-j)/(max.y-min.y)*min;
N1=(1-(max1.y-j)/(max1.y-min1.y))*maxN1+(max1.y-j)/(max1.y-min1.y)*minN1;
N2=(1-(max.y-j)/(max.y-min.y))*maxN+(max.y-j)/(max.y-min.y)*minN;
}
else
{
v1=max1;
v2=min1;
N1=maxN1;
N2=minN1;
}
Vector vt,maxX,minX,maxXN,minXN,Nt;
if(v1.x>v2.x)
{
maxX=v1; minX=v2; maxXN=N1; minXN=N2;
}
else
{
maxX=v2; minX=v1; maxXN=N2; minXN=N1;
}
for(double l=maxX.x;l>=minX.x;l-=0.5)
{
if(minX.x!=maxX.x)
{
vt=(1-(maxX.x-l)/(maxX.x-minX.x))*maxX+(maxX.x-l)/(maxX.x-minX.x)*minX;
Nt=(1-(maxX.x-l)/(maxX.x-minX.x))*maxXN+(maxX.x-l)/(maxX.x-minX.x)*minXN;
}
else
{
vt=maxX; Nt=maxXN;
}
d=pow(vt.x*vt.x+vt.y*vt.y+vt.z*vt.z,0.5);
Vector r=2*((Normalize(Nt)&Normalize(intens_v)))*Nt-Normalize(intens_v);
double I=2.5*0.5 + intens*(0.8*(Normalize(Nt)&Normalize(intens_v))+0.3*(Normalize(Nt)&Normalize(r)));
if(I<2.0) I=2.0;
red=R*I/3; grn=G*I/3; blu=B*I/3;
if(red>255) red=255; if(grn>255) grn=255; if(blu>255) blu=255;
SetPixel(hdc,vt.x,vt.y,RGB(red,grn,blu));
}
}
}
}
void FaceSides()
{
Vector a,b,n;
for(int i=0;i<NS;i++)
visible[i] = 1;
for(int i=0;i<NS;i++)
{
a=(v[side[i][0]-1]-v[side[i][1]-1]),
b=(v[side[i][2]-1]-v[side[i][1]-1]);
n=a^b;
n=Normalize(n);
if((n&proect)<=0)
visible[i]=0;
}
}
Vector Normal(const int Side[])
{
Vector a,b;
a=(v[Side[0]-1]-v[Side[1]-1]);
b=(v[Side[2]-1]-v[Side[1]-1]);
return Normalize(a^b);
}
char *GetSaveFileName(HWND hwnd)
{
OPENFILENAME ofn;
char szFile[80];
char szFileTitle[80];
char szFilter[80] = "BMP\0*.bmp\0";
szFile[0] = '\0';
memset(&ofn, 0, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = NULL;
ofn.lpstrFilter = szFilter;
ofn.nFilterIndex = 1;
ofn.lpstrFile = szFile;
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFileTitle = szFileTitle;
ofn.nMaxFileTitle = sizeof(szFileTitle);
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_HIDEREADONLY;
if (GetSaveFileName(&ofn))
{
int Size;
char Buf[80];
Size=sprintf(Buf, "%s.bmp", ofn.lpstrFile);
Buf[Size]='\0';
return Buf;
}
else
return NULL;
}