Sandundhammika's Blog











Finally I’d able to write my own implementation of the
Bersenham line drawing algorithm under win32 GDI.

I have used a mouse_click_state_machine state machine
class to track mouse clicks.

It will fill an entry when you first clicks and it will
fill the secondry ( x2,y2) when you hit another mouse
click.

Finally it uses the my implementation of Bersenham algo-
rithm to plot the line.

midpoint_line.cc

#include <windows.h>
#include "line_draw_algo.h"
#include "mouse_click_state_machine.h"

LRESULT CALLBACK WinProc(HWND,UINT,WPARAM,LPARAM);

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpStr,int iCmdShow)
{
	MSG msg;
	WNDCLASS wndclass ;
	HWND hwnd ;
	static TCHAR szAppName []= TEXT("Midpoint");

	// initialize the wndclass structure.
	wndclass.style= CS_HREDRAW |CS_VREDRAW ;
	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.lpszClassName = szAppName ;
	wndclass.lpszMenuName= NULL;
	wndclass.lpfnWndProc = WinProc ;

	// Register the class
	RegisterClass(&wndclass);
	/*{
		MessageBox(NULL ,TEXT("Register Class Failed!"),szAppName,0);
		ExitProcess(0);
	}*/

	// then create the window
	hwnd = CreateWindow( szAppName ,
			     szAppName ,
			     WS_OVERLAPPEDWINDOW ,
			     CW_USEDEFAULT ,CW_USEDEFAULT ,CW_USEDEFAULT,CW_USEDEFAULT ,
			     NULL ,
			     NULL ,
			     hInstance ,
			     NULL);
	// Then show the window.
	ShowWindow(hwnd , SW_SHOW);
	// Update Window.

	// Then enter to the message loop.
	while( GetMessage( &msg, NULL ,0,0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return msg.wParam;
}

LRESULT CALLBACK WinProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
	PAINTSTRUCT ps ;
	static MouseClickStateMachine mcsm;
	POINT point ;
	switch (message)
	{

		case WM_LBUTTONDOWN:
			point.x= LOWORD(lParam);
			point.y= HIWORD(lParam);
			mcsm.MouseClick(point);
			// initialize mcsm
			mcsm.SetHWND(hWnd);
			if( mcsm.GetState() == 3)
				LineDraw (mcsm);
			break;
		case WM_RBUTTONDOWN:

			break;
		case WM_PAINT:

			break;
		case WM_CREATE:

			break;
		case WM_DESTROY:
			PostQuitMessage(0);
			break;
		default:
			return DefWindowProc(hWnd,message,wParam,lParam);
	}
	return 0;
}

mouse_click_state_machine.h

#ifndef __MOUSE_CLICK_STATE_MACHINE__
#define __MOUSE_CLICK_STATE_MACHINE__

#include <windows.h>

class MouseClickStateMachine
{
	int state; // initially this is in the
		       // start state.
	HWND hwnd ;
	int x1 ;
	int y1;
	int x2;
	int y2 ;
public:
	int GetState()
	{
		return state;
	}
	void SetHWND(HWND hWnd)
	{
		hwnd=hWnd;
	}
	HWND GetHWND()
	{
		return hwnd;
	}

	POINT& GetPointOne(POINT& point)
	{
		point.x = x1;
		point.y = y1;
		return point;
	}

	POINT& GetPointTwo(POINT& point)
	{
		point.x =x2;
		point.y = y2;
		return point;
	}

	void MouseClick(POINT &point)
	{
		if( state==3)
			state=1;
		if ( state==0)
		{
			MessageBox(NULL,\
			TEXT("Exception: MouseClick was not initialized properly"),\
			TEXT("Midpoint Algo"),MB_OK);
			ExitProcess(1);
		}
		if ( state ==1)
		{
			// fill the x1 and y1
			x1= point.x;
			y1= point.y;
			state++;
			return;
		}
		if ( state ==2)
		{
			// fill the x2 and y2
			x2 = point.x;
			y2 = point.y;

		}
		state++;
	}

	MouseClickStateMachine()
	{
		state=1;

	}
	~MouseClickStateMachine()
	{

	}

};

#endif

line_draw_algo.h

#include <windows.h>
#include "mouse_click_state_machine.h"

void LineDraw(MouseClickStateMachine& mcsm);
void LineDraw(int x1, int y1, int x2 , int y2);

line_draw_algo.cc

#include <windows.h>
#include "mouse_click_state_machine.h"
#include "line_draw_algo.h"

static HDC hDC;
int abs( int a , int b);
void swap(int&,int&);
void PutPixel(int,int);

void LineDraw( MouseClickStateMachine& mcsm)
{
	POINT point;
	mcsm.GetPointOne(point);
	int x1= point.x;
	int y1= point.y;
	mcsm.GetPointTwo(point);
	int x2= point.x;
	int y2 = point.y;
	hDC = GetDC(mcsm.GetHWND());
	LineDraw (x1,y1,x2,y2);
	ReleaseDC(mcsm.GetHWND(),hDC);
}

void LineDraw(int x1, int y1,int x2,int y2)
{
	// so at last we are going to imlement the
	// line drawing algorithm here.

	// //--BersanHam Line drawing algorithm--// //

	int step1 =0;
	if (abs(x2-x1)< abs(y1-y2)){
		// then swap the x1,y1 with x2,y2.
		swap (x2,y2);
		swap (y1,x1);
		step1 = 0;
	} else
	{
		//if ((x2-x1)>=abs (y2-y1))
		// just do nothing..
		step1= 1;
	}
	if (x1>x2)
	{
		swap(x1,x2);
		swap(y1,y2);
	}
	int dx , dy;
	dx=x2 -x1;
	int step;
	if(y1>y2)
	{
		step =0;
		dy = y1 -y2 ;
	}else
	{
		dy=y2-y1;
		step =1;
	}
	int step_through_x;
	int d = 2* dy;
	int iN = 2* dy;
	int iNE = 2*(dy-dx);
	int y= y1;
	for ( int x = x1 ; x <= x2 ; x++)
	{
		if ( step1==1)
			PutPixel(x ,y);
		if(  step1==0)
			PutPixel(y,x);
		if ( d > 0)
		{
			d = d +iNE ;
			if (step)
			{
				y++;
			}else
			{
				y--;
			}
		}else
		{
			d = d + iN;
		}
	}

}

void swap(int &a,int &b)
{
	int temp ;
	temp = a ;
	a = b;
	b=temp ;
}

int abs( int x, int y)
{

	return (x>y)?(x-y):(y-x);

}

void PutPixel(int x, int y)
{
	//MessageBox( 0,"line draw algo -put pixel" ,"midpoint",MB_OK);
	SetPixel(hDC,x,y,0xFF0000);

}

compile.bat –use only -g if you want to debug this under gdb.

g++ -c line_draw_algo.cc -g
g++ -c midpoint_line.cc -g
g++ -o midpoint.exe midpoint_line.o line_draw_algo.o -mwindows -g

here is how this looks.

Try it yourself ,

here you can find the binary files and source files for this project.To compile assume you

had already installed mingw g++ and set the paths, then run compile bat by opening a

command prompt.

and to execute hit midpoint.exe

http://www.programmersheaven.com/download/56372/download.aspx

— Happy C0ding–

Advertisements


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

et cetera
%d bloggers like this: