------

[ AD ] Port Monitor ( Try to use a Best WebSite Monitoring Tool )

------
http://en.wikipedia.org/wiki/Bresenham's_line_algorithm
      o-------                         |
     p1       --------                 | deltay
                      -------      p2  |
                             -------o  |
      ----------------------------------
                  deltax

where p1 = (x1,y1),
      p2 = (x2, y2),
      x and y are both increasing from p1 to p2,
      deltax = x2 - x1,
      deltay = y2 - y1 and
      deltax >= deltay.
#include 
#include 
#include 
#include 

/*
 * Point size의 Default 값은 1.0 이다.
 */
GLfloat size = 1.0;
GLint flag = 0;
GLint St_x=0, St_y=0, Ed_x=0, Ed_y=0;

/*
 * 파라메터로 들어온 x좌표와 y좌표를 이용하여 점을 찍는다.
 */
void RenderPoint(GLint x, GLint y)
{
	glColor3f(1.0, 1.0, 1.0);
	glPointSize(size);

	glBegin(GL_POINTS);
		glVertex3f(x/300.0, (300-y)/300.0, 0.0);
	glEnd();
	glFlush();
}

/*
 * 전역 좌표인 St_x, St_y, Ed_x, Ed_y를 이용하여 선분을 그리는 함수이다.
 */
void RenderLine()
{
	int DeltaX, DeltaY;
    int X, Y;
    int D;
	
    DeltaX = Ed_x - St_x;
	DeltaY = Ed_y - St_y;

	/*
	 * RenderPoint를 이용하여 Point를 찍어줄 때 
	 * X좌표와 Y좌표의 증가량의 변수이다.
	 * 기본 Default값은 양의 1이다.
	 */
	X = 1;
	Y = 1;
	
	/*
	 * X의 증가량이 음의 수 이므로 X의 증가량의 절대값을 구하고
	 * Line을 그리면 그릴 수록 RenderPoint함수를 통해 표현할 
	 * 점의 좌표가 -값을 갖고 후퇴하며 표현해야 하므로 X값을 -1값으로 한다.
	 */
	if( DeltaX < 0 )
	{
		DeltaX = -DeltaX;
		X = -1;
	}

	/*
	 * Y의 증가량이 음의 수 이므로 Y의 증가량의 절대값을 구하고
	 * Line을 그리면 그릴 수록 RenderPoint함수를 통해 표현할 
	 * 점의 좌표가 -값을 갖고 후퇴하며 표현해야 하므로 Y값을 -1값으로 한다.
	 */
	if( DeltaY < 0 )
	{
		DeltaY = -DeltaY;
		Y = -1;
	}
	
	/*
	 * 첫 시작점을 그린다.
	 */
	RenderPoint( St_x, St_y );
	
	/*
	 * X의 증가량이 Y의 증가량보다 큰 경우이다.
	 * 기울기는 "0< 기울기 < 1"의 크기를 갖고 있다.
	 */
	if( DeltaX > DeltaY )
	{
		/*
		 * 결정변수의 값은 2DeltaY - DeltaX의 값을 갖는다. (초기화) 
		 */
		D = ( 2*DeltaY) - DeltaX;
		
		/*
		 * x좌표를 검사하여 마지막 점을 표시할 때까지 무한 반복한다.
		 */
		while( St_x != Ed_x )
		{
			/*
			 * 결정변수의 값을 검사한다.
			 * 
			 * 양의 값인 경우 X좌표와 Y좌표를 증가시키면서 
			 * 다음 래스터를 결정하게 된다.
			 * 결정변수의 연산결과는 D += 2DeltaY - 2DeltaX이다.
			 * 
			 * 음인 경우 X좌표만을 증가시키며
			 * 다음 래스터를 결정한다.
			 * 결정변수의 연산결과는 D += 2DeltaY이다. 
			 */
			if( D >= 0 )
			{
				St_y += Y;
				D -= 2*DeltaX;
			}
			St_x += X;
			D += 2*DeltaY;
			
			/*
			 * 다음 래스터로 결정된 좌표에 점 찍기
			 */
			RenderPoint( St_x, St_y );
		}
	}

	/*
	 * Y의 증가량이 X의 증가량보다 큰 경우이다.
	 * 기울기는 " 1<기울기 "의 크기를 갖고 있다.
	 * 위의 연산과 정 반대의 연산을 갖는다.
	 */
	else
	{
		/*
		 * 결정변수의 값은 2DeltaY - DeltaX의 값을 갖는다. (초기화) 
		 */
		D = ( 2*DeltaX ) - DeltaY;
		
		/*
		 * y좌표를 검사하여 마지막 점을 표시할 때까지 무한 반복한다.
		 */
		while( St_y != Ed_y )
		{
			/*
			 * 결정변수의 값을 검사한다.
			 * 
			 * 양의 값인 경우 X좌표와 Y좌표를 증가시키면서 
			 * 다음 래스터를 결정하게 된다.
			 * 결정변수의 연산결과는 D += 2DeltaX - 2DeltaY이다.
			 * 
			 * 음인 경우 Y좌표만을 증가시키며
			 * 다음 래스터를 결정한다.
			 * 결정변수의 연산결과는 D += 2DeltaX이다. 
			 */
			if( D >= 0 )
			{
				St_x += X;
				D -= 2*DeltaY;
			}
			
			St_y += Y;
			D += 2*DeltaX;
			
			/*
			 * 다음 래스터로 결정된 좌표에 점 찍기
			 */
			RenderPoint( St_x, St_y );
		}
	}
	return;
}

/*
 * 마우스 이벤트 발생시 실행되는 함수이다.
 */
void MyMouse(GLint button, GLint state, GLint x, GLint y)
{
	/*
	 * 마우스 이벤트 발생의 상태가 클릭상태이고,(state)
	 * 버튼의 방향이 왼쪽인 경우 (button)
	 * 점을 하나 찍어준다.
	 */
	if(state == GLUT_DOWN && button == GLUT_LEFT_BUTTON)
	{
		/* 
		 * 선택한 좌표를 확인하도록 점을 찍어준다.
		 */
		RenderPoint(x,y);

		/*
		 * Flag는 이번 입력들어온 마우스의 좌표가 첫 번째 입력인지
		 * 두번째 입력인지를 구분한다.
		 * 첫번째인 경우 두번째 입력을 기다린다.
		 * 두번째인 경우 RenderLine함수를 호출하여 선분을 그린다. 
		 */
		if(flag ==1)
		{
			Ed_x = x;
			Ed_y = y;

			/* 
			 * 선분을 그리는 함수 호출 
			 */
			RenderLine();
			flag = 0;
		}
		else
		{
			St_x = x;
			St_y = y;

			/* 
			 * flag 값을 설정하여 첫번째 입력이 들어왔음을 표시한다.
			 */
			flag = 1;
		}
		/* 색은 흰색이다.*/
	}
}


/* 처음 윈도우를 만들 때 그리는 함수 */
void MyDisplay()
{
	/* Window의 색을 기본 색으로 채운다. 검은색이다. */
	glClear(GL_COLOR_BUFFER_BIT);
	glFlush();
}

/* 윈도우를 생성하고 콜백함수를 선언하는 메인함수이다. */
int main(int argc, char** argv)
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGB);
	glutInitWindowSize(300,300);
	glutInitWindowPosition(100,100);
	glutCreateWindow("CG HW#7 - Bresenham Algorithm");
	
	/* 검은색을 기본 색으로 한다.*/
	glClearColor(0.0, 0.0, 0.0, 1.0);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	/* 윈도우의 좌표계를 왼쪽 하단부를 0.0 에서 오른쪽 상단부를 1.0으로 지정한다.*/
	glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);

	/* 콜백함수를 선언한다.*/
	glutDisplayFunc(MyDisplay);
	glutMouseFunc(MyMouse);

	/* 루프에 들어간다. */
	glutMainLoop();
	return 0;
}

'온라인게임 > vc++' 카테고리의 다른 글

표준 c++ / C++ 시작 1  (0) 2010.10.02
게임 서버  (0) 2010.10.02
vs 2010 (vc++ 10)  (0) 2010.10.01
온라인 게임 서버  (0) 2010.10.01
파란 배경 Direct 3D 윈도우  (0) 2010.09.03

+ Recent posts