As in the previous line drawing algorithm, we sample at unit intervals
and determine the closest pixel position to the specified circle path at
each step. For a given radius r and screen center position (xc, yc), we
can first set up our algorithm to calculate pixel positions around a
circle path centered at the coordinate origin (0, 0). Then each
calculated position (x, y) is moved to its proper screen position by
adding xc to x and yc to y. Along the circle section from x = 0 to x = y
in the first quadrant, the slope of the curve varies from 0 to –1.
Therefore, we can take unit steps in the positive x direction over this
octant and use a decision parameter to determine which of the two
possible y positions is closer to the circle path at each step. Position
in the other seven octants are then obtained by symmetry.
The following section implements Mid – Point Cicle Algorithm in C/C++.
The source code is complied using gcc Compiler and Code::Blocks IDE. To
print a pixel, SetPixel() function of windows.h is used.
Note: to run this code in your machine with Code::blocks IDE, add a
link library libgdi32.a (it is usually inside MinGW\lib ) in linker
setting. Souce Code
Output#include <windows.h>#include <cmath>#define ROUND(a) ((int) (a + 0.5))/* set window handle */static HWND sHwnd;static COLORREF redColor=RGB(255,0,0);static COLORREF blueColor=RGB(0,0,255);static COLORREF greenColor=RGB(0,255,0);void SetWindowHandle(HWND hwnd){sHwnd=hwnd;}/* SetPixel */void setPixel(int x,int y,COLORREF& color=redColor){if(sHwnd==NULL){MessageBox(NULL,"sHwnd was not initialized !","Error",MB_OK|MB_ICONERROR);exit(0);}HDC hdc=GetDC(sHwnd);SetPixel(hdc,x,y,color);ReleaseDC(sHwnd,hdc);return;}void circlePoints(int xCenter, int yCenter, int x, int y){setPixel(xCenter + x, yCenter + y);setPixel(xCenter - x, yCenter + y);setPixel(xCenter + x, yCenter - y);setPixel(xCenter - x, yCenter - y);setPixel(xCenter + y, yCenter + x);setPixel(xCenter - y, yCenter + x);setPixel(xCenter + y, yCenter - x);setPixel(xCenter - y, yCenter - x);}void drawCircle(int xCenter, int yCenter, int radius){int x = 0;int y = radius;int p = 1 - radius;circlePoints(xCenter, yCenter, x, y);while(x < y){x++;if (p < 0){p += 2 * x + 1;}else{y--;p += 2 * (x - y) + 1;}circlePoints(xCenter, yCenter, x, y);}}/* Window Procedure WndProc */LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam){switch(message){case WM_PAINT:SetWindowHandle(hwnd);drawCircle(200, 200, 100);break;case WM_CLOSE: // FAIL THROUGH to call DefWindowProcbreak;case WM_DESTROY:PostQuitMessage(0);return 0;default:break; // FAIL to call DefWindowProc //}return DefWindowProc(hwnd,message,wParam,lParam);}int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int iCmdShow){static TCHAR szAppName[] = TEXT("Circle");WNDCLASS wndclass;wndclass.style = CS_HREDRAW|CS_VREDRAW ;wndclass.lpfnWndProc = WndProc ;wndclass.cbClsExtra = 0 ;wndclass.cbWndExtra = 0 ;wndclass.hInstance = hInstance ;wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;wndclass.lpszMenuName = NULL ;wndclass.lpszClassName = szAppName ;// Register the window //if(!RegisterClass(&wndclass)){MessageBox(NULL,"Registering the class failled","Error",MB_OK|MB_ICONERROR);exit(0);}// CreateWindow //HWND hwnd=CreateWindow(szAppName,"Mid Point Circle Drawing - Programming Techniques",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL);if(!hwnd){MessageBox(NULL,"Window Creation Failed!","Error",MB_OK);exit(0);}// ShowWindow and UpdateWindow //ShowWindow(hwnd,iCmdShow);UpdateWindow(hwnd);// Message Loop //MSG msg;while(GetMessage(&msg,NULL,0,0)){TranslateMessage(&msg);DispatchMessage(&msg);}/* return no error to the operating system */return 0;}


19:59
Unknown
0 comments:
Post a Comment