Hi!
I do have half of arc.c that,,,, frack that! I'll commit it.
I have some arc code but it's not tested and I really want to finish this ASAP!
I need a booting system,,,, etc. SSDD!
Murphy, Ged (Bolton) wrote:
FAO JimT (or anyone else who may have secret fixes in
their tree, Filip ;) )
Do you have any improvements to the mentioned functions.
They need attention/improvement to improve the drawing of some of our UI
controls.
Don't wanna double up on work if someone already has something on this.
Cheers,
Ged.
Here is a test program. Guess what part doesn't work?
Thanks,
James
/*--------------------------------------------------------------------
DrawingCircles.c -- Comparing Circles Drawed By
Win32 API GDI, The Simplest Drawing Circle Algorithm,
Bresenham Circle Algorithm, Michener Algorithm
(c) Vladimir Tsvetkov, 2004
Happy Hacking!!!
--------------------------------------------------------------------*/
#include <windows.h>
#include <math.h>
#define RADIUS 100
#define REALLYSIMPLE_CIRCLE_COLOR RGB (255, 0, 0)
#define BRESENHAM_CIRCLE_COLOR RGB (255, 0, 255)
#define MIECHENER_CIRCLE_COLOR RGB (0, 0, 255)
#define DS_CIRCLE_COLOR RGB (0, 100, 100)
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain (HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("CircleDemoApp");
HWND hwnd;
MSG msg;
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;
if (!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT ("This program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}
hwnd = CreateWindow (szAppName, // window class name
TEXT("Comparing Circle Drawings"), // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
CW_USEDEFAULT, // initial x size
CW_USEDEFAULT, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL); // creation parameters
ShowWindow (hwnd, iCmdShow);
UpdateWindow (hwnd);
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
return msg.wParam;
}
// the simplest way to draw a circle:
void ReallySimpleCircle (HDC hdc, LONG radius, POINT ptCenter, COLORREF crColor)
{
LONG cx = 0, cy;
double xLimit = sqrt ((double) (radius * radius) / 2);
while (cx++ <= xLimit)
{
cy = (LONG) floor (sqrt (radius * radius - cx * cx));
SetPixel (hdc, cx + ptCenter.x, cy + ptCenter.y, crColor); // 45-90 degrees
SetPixel (hdc, cx + ptCenter.x, -cy + ptCenter.y, crColor); // 270-315 degrees
SetPixel (hdc, -cx + ptCenter.x, cy + ptCenter.y, crColor); // 90-135 degrees
SetPixel (hdc, -cx + ptCenter.x, -cy + ptCenter.y, crColor); // 225-270 degrees
SetPixel (hdc, cy + ptCenter.x, cx + ptCenter.y, crColor); // 0-45 degrees
SetPixel (hdc, cy + ptCenter.x, -cx + ptCenter.y, crColor); // 315-360 degrees
SetPixel (hdc, -cy + ptCenter.x, cx + ptCenter.y, crColor); // 135-180 degrees
SetPixel (hdc, -cy + ptCenter.x, -cx + ptCenter.y, crColor); // 180-225 degrees
}
}
// Win32API GDI circle:
void Win32APIGDICircle (HDC hdc, LONG radius, POINT ptCenter)
{
SelectObject (hdc, GetStockObject (NULL_BRUSH));
Ellipse (hdc,
ptCenter.x - RADIUS,
ptCenter.y + RADIUS,
ptCenter.x + RADIUS,
ptCenter.y - RADIUS);
}
////////////////////////////////////////////////////////
// Bresenham Circle Algorithm:
//
// -Yi Xi
// ---------------o---------------o---------------
// Hi <= | > Di <= | > Vi
// | |
// x++ | x++,y-- | y--
////////////////////////////////////////////////////////
void BresenhamCircle (HDC hdc, LONG radius, POINT ptCenter, COLORREF crColor)
{
LONG cx, cy, d;
cx = 0;
cy = radius;
d = 2 - 2 * radius;
// let's start drawing the circle:
SetPixel (hdc, cx + ptCenter.x, cy + ptCenter.y, crColor); // point (0, R);
SetPixel (hdc, cx + ptCenter.x, -cy + ptCenter.y, crColor); // point (0, -R);
SetPixel (hdc, cy + ptCenter.x, cx + ptCenter.y, crColor); // point (R, 0);
SetPixel (hdc, -cy + ptCenter.x, cx + ptCenter.y, crColor); // point (-R, 0);
while (1)
{
if (d > -cy)
{
--cy;
d += 1 - 2 * cy;
}
if (d <= cx)
{
++cx;
d += 1 + 2 * cx;
}
if (!cy) return; // cy is 0, but these points are already drawn;
// the actual drawing:
SetPixel (hdc, cx + ptCenter.x, cy + ptCenter.y, crColor); // 0-90 degrees
SetPixel (hdc, -cx + ptCenter.x, cy + ptCenter.y, crColor); // 90-180 degrees
SetPixel (hdc, -cx + ptCenter.x, -cy + ptCenter.y, crColor); // 180-270 degrees
SetPixel (hdc, cx + ptCenter.x, -cy + ptCenter.y, crColor); // 270-360 degrees
}
}
// Miechener circle algorithm:
void MiechenerCircle (HDC hdc, LONG radius, POINT ptCenter, COLORREF crColor)
{
LONG cx, cy, d;
d = 3 - 2 * radius;
cy = radius;
// let's start drawing the circle:
SetPixel (hdc, ptCenter.x, radius + ptCenter.y, crColor); // point (0, R);
SetPixel (hdc, ptCenter.x, -radius + ptCenter.y, crColor); // point (0, -R);
SetPixel (hdc, radius + ptCenter.x, ptCenter.y, crColor); // point (R, 0);
SetPixel (hdc, -radius + ptCenter.x, ptCenter.y, crColor); // point (-R, 0);
for (cx = 0; cx <= cy; cx++)
{
if (d >= 0)
// in this case we choose Hi:
d += 10 + 4 * cx - 4 * cy--;
else
// in this case we choose Di:
d += 6 + 4 * cx;
// the actual drawing:
SetPixel (hdc, cy + ptCenter.x, cx + ptCenter.y, crColor); // 0-45 degrees
SetPixel (hdc, cx + ptCenter.x, cy + ptCenter.y, crColor); // 45-90 degrees
SetPixel (hdc, -cx + ptCenter.x, cy + ptCenter.y, crColor); // 90-135 degrees
SetPixel (hdc, -cy + ptCenter.x, cx + ptCenter.y, crColor); // 135-180 degrees
SetPixel (hdc, -cy + ptCenter.x, -cx + ptCenter.y, crColor); // 180-225 degrees
SetPixel (hdc, -cx + ptCenter.x, -cy + ptCenter.y, crColor); // 225-270 degrees
SetPixel (hdc, cx + ptCenter.x, -cy + ptCenter.y, crColor); // 270-315 degrees
SetPixel (hdc, cy + ptCenter.x, -cx + ptCenter.y, crColor); // 315-360 degrees
}
}
///////////////////////////////////////////////////////////
// double substraction method for drawing a circle:
//
// d0 -> H -> d1 = d0H+d0 -> D -> d2 = d1D+d1
// d0H -> d1H = d0H+2 -> d2H = d1H+2
// d0D -> d1D = d0D+2 -> d2D = d1D+4
// step 0 step 1 step 2
//
///////////////////////////////////////////////////////////
void DSCircle (HDC hdc, LONG radius, POINT ptCenter, COLORREF crColor)
{
LONG cx, cy, d, dH, dD;
d = 1 - radius;
dH = 3;
dD = 5 - 2 * radius;
cy = radius;
// drawing the circle:
for (cx = 0; cx <= cy; cx++)
{
if (d < 0)
{
d += dH;
dH += 2;
dD += 2;
}
else
{
d += dD;
dH += 2;
dD += 4;
--cy;
}
// the actual drawing:
SetPixel (hdc, cy + ptCenter.x, cx + ptCenter.y, crColor); // 0-45 degrees
SetPixel (hdc, cx + ptCenter.x, cy + ptCenter.y, crColor); // 45-90 degrees
SetPixel (hdc, -cx + ptCenter.x, cy + ptCenter.y, crColor); // 90-135 degrees
SetPixel (hdc, -cy + ptCenter.x, cx + ptCenter.y, crColor); // 135-180 degrees
SetPixel (hdc, -cy + ptCenter.x, -cx + ptCenter.y, crColor); // 180-225 degrees
SetPixel (hdc, -cx + ptCenter.x, -cy + ptCenter.y, crColor); // 225-270 degrees
SetPixel (hdc, cx + ptCenter.x, -cy + ptCenter.y, crColor); // 270-315 degrees
SetPixel (hdc, cy + ptCenter.x, -cx + ptCenter.y, crColor); // 315-360 degrees
}
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static int cxClient, cyClient;
static POINT ptCenter;
HDC hdc;
PAINTSTRUCT ps;
switch (message)
{
case WM_SIZE:
cxClient = LOWORD (lParam);
cyClient = HIWORD (lParam);
ptCenter.x = cxClient / 2;
ptCenter.y = cyClient / 2;
return 0;
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps);
// draw streight horizontal line that splits the client area in half:
MoveToEx (hdc, 0, cyClient / 2, NULL);
LineTo (hdc, cxClient, cyClient / 2);
// draw streight vertical line that splits the client area in half:
MoveToEx (hdc, cxClient / 2, 0, NULL);
LineTo (hdc, cxClient / 2, cyClient);
// draw really simple circle:
ReallySimpleCircle (hdc, RADIUS, ptCenter, REALLYSIMPLE_CIRCLE_COLOR);
// Win32API GDI circle:
ptCenter.x += 20;
Win32APIGDICircle (hdc, RADIUS, ptCenter);
// Bresenham cirlce algorithm:
ptCenter.x += 20;
BresenhamCircle (hdc, RADIUS, ptCenter, BRESENHAM_CIRCLE_COLOR);
// Miechener circle algorithm:
ptCenter.x += 20;
MiechenerCircle (hdc, RADIUS, ptCenter, MIECHENER_CIRCLE_COLOR);
// Double Substractions circle algorithm:
ptCenter.x += 20;
DSCircle (hdc, RADIUS, ptCenter, DS_CIRCLE_COLOR);
EndPaint (hwnd, &ps);
return 0;
case WM_DESTROY:
PostQuitMessage (0);
return 0;
}
return DefWindowProc (hwnd, message, wParam, lParam);
}