본문 바로가기

기타/알고리즘

[WinAPI] C언어를 이용한 Recursion - Fractal Tree(프렉탈 tree)

사용자 삽입 이미지



주의할점 : 프로젝트 생성시
New - Project - Win32 Application 으로 생성해야합니다.
Win32 Consol Application으로 할 경우 링크애러(아래 글 참조)를 맞이할 수 있습니다;

프로젝트 생성후 새파일을 하고 아래 소스를 넣고 cpp로 파일을 저장합니다.

소스 :
invalid-file

cpp 소스입니다 ㅋ



#include <windows.h>
#include <math.h>

const double pi = 3.14159265358979;

void drawLineAngle(HDC hdc, int posX, int posY, double firstAngle, double firstLineLength);
// draw line with hdc, start position, Line Direct(Angle) and Line Length
void drawLine(HDC hdc, int posX, int posY, int tgtX, int tgtY);
// draw line with hdc, start position and object position
int drawTree(int depth, HDC hdc, void (*dLA)(HDC, int, int, double, double), void (*dL)(HDC, int, int, int, int),  int posX, int posY, double firstAngle, double firstLineLength, int isRoot, int diffAngle, double lenRate);
//depth, HDC, dLA func, dL func, posX, posY, firstAngle, firstLength, isRoot, diffAngle, lenRate

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hInst;
LPSTR lpszClass="First";

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance
    ,LPSTR lpszCmdParam,int nCmdShow)
{
 HWND hWnd;
 MSG Message;
 WNDCLASS WndClass;
 g_hInst=hInstance;
 
 WndClass.cbClsExtra=0;
 WndClass.cbWndExtra=0;
 WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
 WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
 WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
 WndClass.hInstance=hInstance;
 WndClass.lpfnWndProc=(WNDPROC)WndProc;
 WndClass.lpszClassName=lpszClass;
 WndClass.lpszMenuName=NULL;
 WndClass.style=CS_HREDRAW | CS_VREDRAW;
 RegisterClass(&WndClass);

 hWnd=CreateWindow(lpszClass,lpszClass,WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
    NULL,(HMENU)NULL,hInstance,NULL);
 ShowWindow(hWnd,nCmdShow);
 
 while(GetMessage(&Message,0,0,0)) {
  TranslateMessage(&Message);
  DispatchMessage(&Message);
 }
 return Message.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
 switch(iMessage) {
 case WM_DESTROY:
  PostQuitMessage(0);
  return 0;
 case WM_LBUTTONDOWN :
  {
   HDC hdc = GetDC(hWnd);
   drawTree(30, hdc, drawLineAngle, drawLine, 350, 400, 90 , 90, 1, 25, 0.8);
   //depth, HDC, dLA func, dL func, posX, posY, firstAngle, firstLength, isRoot, diffAngle, lenRate

   ReleaseDC(hWnd, hdc);
   break;
  }
 case WM_CREATE :
  break;

 }
 return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}

void drawLineAngle(HDC hdc, int posX, int posY, double firstAngle, double firstLineLength)
{
 int lenX, lenY;
 double radian;
 radian = (firstAngle - 90) / 180 * pi;
 lenX = int(double(firstLineLength) * sin(radian));
 lenY = int(double(firstLineLength) * cos(radian));
 MoveToEx(hdc, posX, posY, NULL);
 LineTo(hdc, posX + lenX, posY + lenY);
}

void drawLine(HDC hdc, int posX, int posY, int tgtX, int tgtY)
{
 MoveToEx(hdc, posX, posY, NULL);
 LineTo(hdc, tgtX, tgtY);
}

int drawTree(int depth, HDC hdc, void (*dLA)(HDC, int, int, double, double), void (*dL)(HDC, int, int, int, int),  int posX, int posY, double firstAngle, double firstLineLength, int isRoot, int diffAngle, double lenRate)
{
 if( !depth || firstLineLength < 3)
  return 0;

 int lenX, lenY, tgtX, tgtY;
 double radian = (firstAngle - 90) / 180 * pi;

 lenX = int(double(firstLineLength) * sin(radian));
 lenY = int(double(firstLineLength) * cos(radian));
 tgtX = posX - lenX;
 tgtY = posY - lenY;


 if(isRoot) {
   MoveToEx(hdc, posX, posY, NULL);
  dL(hdc, posX, posY, tgtX , tgtY);
 

 }
 else {
 // tgtX = posX;
 // tgtY = posY;
 }
  MoveToEx(hdc, tgtX, tgtY, NULL);

 dLA(hdc, tgtX, tgtY, firstAngle + 180 + diffAngle , double(firstLineLength) * lenRate);
 dLA(hdc, tgtX, tgtY, firstAngle + 180 - diffAngle , double(firstLineLength) * lenRate);

 drawTree(depth-1, hdc, dLA, dL,   tgtX,  tgtY, int( firstAngle + diffAngle ) % 360, double(firstLineLength) * lenRate, 0, diffAngle, lenRate);
 drawTree(depth-1, hdc, dLA, dL,   tgtX,  tgtY, int( firstAngle - diffAngle + 360 ) % 360, double(firstLineLength) * lenRate, 0, diffAngle, lenRate);
 return 0;
}