void Draw( HDC hdc )
{
int ommd;
int x, y, xres, yres;
HBRUSH hobr;
HPEN hopen;
ommd = SetMapMode( hdc, MM_ANISOTROPIC );
// 가로 5눈금, 세로 6 눈금(unit)으로 구성되는 사각영역에 그림 그리기
SetWindowExtEx( hdc, 5, -6, 0 );
//위의 가로 5, 세로 6의 논리 눈금에 대한 디바이스(픽셀)눈금수는
//현재 디바이스에 적용되고 있는
//가로 길이 해상도(resolution)의 80%
//세로 길이 해상도(resolution)의 80%을 그리기 영역으로 사용한다고 가정
xres = GetDeviceCaps( hdc, HORZRES ) * 0.8;
yres = GetDeviceCaps( hdc, VERTRES ) * 0.8;
SetViewportExtEx( hdc, xres, yres, 0 );
// 디바이스 눈금단위로 사각형의 좌측 하단부의 좌표를 viewport 원점으로 삼는다.
// 대략 Xvo는 논리 1눈금의 디바이스 길이 절반 : xres / (5*2)
// 대략 Yvo는 논리 6눈금의 디바이스 길이 보다약간 길게 : yres * 1.1;
xres /=(5*2);
yres *= 1.1;
SetViewportOrgEx( hdc, xres, yres, 0 );
// 아래에서는 논리 단위 눈금으로 그리기를 시행합니다.
// 논리 1길이의 눈금은 너무 굵은 펜 ...
// hopen = (HPEN)SelectObject( hdc, CreatePen( PS_SOLID, 1, RGB(0,0,0) ) );
// x-축그리기사각형의 가로 길이(5 눈금)보다 길게
MoveToEx( hdc, -1, 0, NULL );
LineTo( hdc, 6, 0 );
// y-축 그리기 사각형의 세로 길이(6 눈금)보다 길게
MoveToEx( hdc, 0, 7, NULL );
LineTo( hdc, 0, -1 );
// 4 각 영역을 그립니다.
hobr = ( HBRUSH )SelectObject( hdc, CreateSolidBrush( RGB( 255,255,220 )) );
// MM_TEXT모드와 달리 y의 죄표들에 유념하여
Rectangle( hdc, 0, 0, 5, 6 );
// y-축의 눈금( 가로 눈금(unit)을 그리기 )
for( y = 1; y <= 5; y++ )
{
MoveToEx( hdc, 0, y, NULL );
LineTo( hdc, 5, y );
}
// x-축의 눈금( 세로 눈금(unit)을 그리기 )
for( x = 1; x <= 4; x++ )
{
MoveToEx( hdc, x, 0, NULL );
LineTo( hdc, x, 6 );
}
// 영역에서 직선 그리기
MoveToEx( hdc, 1,1, NULL );
LineTo( hdc, 4, 5 );
// 영역에서 타원 그리기
SelectObject( hdc, GetStockObject( NULL_BRUSH ) );
Ellipse( hdc, 0,0, 5, 6 );
// 맵핑모드를 복귀시킵니다.
SetMapMode( hdc, ommd );
DeleteObject( SelectObject( hdc, hobr ) );
// DeleteObject( SelectObject( hdc, hopen ) );
}
1. 좀 더 필요한 정보를 얻고 싶다면 아래 사이트들을 참고 하면 도움이 될 것이다.
http://www.funducode.com/freevc/gdi/gdi5/gdi5.htm
http://wvware.sourceforge.net/caolan/mapmode.html
void Draw(HDC hdc)
{
double f;
int y;
//MM_ANISOTROPIC은 x,y축 방향의 임의의 스케일을 가지는 임의의 크기의 눈금
//단위를 적용할 경우에사용할 수 있는 매핑모드입니다.
// ( MM_ISOTROPIC은 x,y축 동일한 스케일의 임의의 크기의 눈금단위사용 )
//여기서는 그리기의 스케일의 크기는 변화가 없지만 스케일의 방향이 변화가
//되었으므로 MM_ANISOTROPIC를 사용할 수 있습니다.
int ommd = SetMapMode(hdc, MM_ANISOTROPIC);
// 1. 님께서 처음 작성하신데로 viewport org을 옮깁니다.
SetViewportOrgEx(hdc, 280, 250, NULL);
// 2. scale를 변화시킵니다.( 여기서는 y-방향만 바꾸기 위하여 )
//MM_ANISOTROPIC이나 MM_ISOTROPIC의 매핑모드를 사용할 때는
//스케일을 적용할 수있도록 아래 두개의 함수를 호출합니다.
//여기서 논리단위 1에 대하여 디바이스 단위 크기 1픽셀을 적용하였을 경우에 대하여
// 두 함수를 다음과 같이 호출합니다.
// window의 x방향의 논리단위 1과 viewport의 x방향의 디바이스단위 1에 대응하고
// window의 y방향의 논리단위 -1과 viewport의 y방향의 디바이스단위 1에 대응합니다.
SetWindowExtEx( hdc, 1, -1, NULL);
SetViewportExtEx( hdc, 1, 1, NULL);
MoveToEx(hdc, -2000, 0, NULL); //X축 그림
LineTo(hdc, 2000, 0);
MoveToEx(hdc, 0, -2000, NULL); //y축 그림
LineTo(hdc, 0, 2000);
for (f=-500; f<1000; f++)
{
y = (int)(tan(f * PI / 180) * 100);
SetPixel(hdc, int(f), y, RGB(255,0,0));
}
// 맵핑모드를 복귀시킵니다.
SetMapMode( hdc, ommd );
}
///////////////////////////////////////////////////////////////////////////////
테스트해본 결과로는 주석해제해야 제대로 출력된다.
디폴트모드인 MM_TEXT는 y축값이 위쪽이 작고 아래쪽이 크므로 보통 수학에서 사용하는 좌표와는 반대이다.
SetMapMode(hdc, MM_LOENGLISH);를 해주어야 y축값이 위쪽이 크고 아래쪽이 작은 것이 된다.
#include<windows.h>
#include<math.h>
#define g_ClassName "GraphClass"
#defineg_Title"Graph"
HWND g_hwndMain;
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPreInstance, LPSTR lpszArgs, int nCmdShow)
{
MSG msg;
WNDCLASS wc;
wc.style=0;
wc.lpfnWndProc=WndProc;
wc.lpszClassName=g_ClassName;
wc.lpszMenuName=NULL;
wc.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
wc.hInstance=hInstance;
wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);
wc.hCursor=LoadCursor(NULL,IDC_ARROW);
wc.cbClsExtra=0;
wc.cbWndExtra=0;
if(!RegisterClass(&wc)) return FALSE;
g_hwndMain=CreateWindow(g_ClassName,
g_Title,
WS_OVERLAPPEDWINDOW,
0,0,600,600,
NULL,
NULL,
hInstance,
NULL
);
if(!g_hwndMain) return FALSE;
ShowWindow(g_hwndMain,nCmdShow);
UpdateWindow(g_hwndMain);
while(GetMessage(&msg,NULL,0,0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return TRUE;
}
HDC hdc;
PAINTSTRUCT ps;
void Draw(HDC hdc)
{
double f;
int y;
int prevmm=SetMapMode(hdc, MM_LOENGLISH);
SetViewportOrgEx(hdc, 280, 250, NULL);
MoveToEx(hdc, -2000, 0, NULL); //X축 그림
LineTo(hdc, 2000, 0);
MoveToEx(hdc, 0, -2000, NULL); //y축 그림
LineTo(hdc, 0, 2000);
for (f=-500; f<1000; f++)
{
y = (int)(tan(f * 3.14159f / 180) * 100);
SetPixel(hdc, int(f), y, RGB(255,0,0));
y = (int)(sin(f * 3.14159f / 180) * 100);
SetPixel(hdc, int(f), y, RGB(0,0,255));
}
SetMapMode(hdc,prevmm);
}
LRESULT CALLBACK WndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch(msg) {
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
Draw(hdc);
EndPaint(hWnd, &ps);
return 0;
default:
return DefWindowProc(hWnd,msg,wParam,lParam);
}
return 0;
}