본문 바로가기

Developement

[주절거림]원호 그리기 ...

원호를 그리는 것은 부동소수점이 지원되는 플랫폼에서는 어렵지 않은 일 입니다만, 만약 FPU 가 없이 ALU만 있는 CPU 에서 처리 한다는 것은 꽤 어려운 일이 아닐수가 없습니다.

원호를 그리는 것에 있어서 ALU 로 그리게 하는 방법 중 하나는 cos(), sin() 등의 특정 FPU 연산 결과를 이미 index 로 가지고 있는 방법이 있을 수 있겠습니다.
예를 들면 ...
static const WORD SIN_10[360] = {
   0,    18,    36,    54,    71,    89,   107,   125,   143,   160,
 178,   195,   213,   230,   248,   265,   282,   299,   316,   333, ... };
와 같이 미리 계산된 고정된 수에 대한 integer 값들을 가지고 있는 것이 한 방법 이겠죠.

그리고 원호를 그리는 것에 있어 필요한 몇가지 요소들...
중심 좌표 x,y 와 radial, angle, sweep angle 등 ..

이걸 integer 로 연산할 방법을 찾다 보니 일단은 openGL 코드가 먼저 눈에 들어 왔습니다.
⁄⁄segments - number of segments per full revolution!
⁄⁄d_angle - determines the direction and the ammount of the arc to draw
void DrawArc(float _x, float _y, float _r, float depth, float start_angle, float d_angle, int32_t color, int segments)
{
	float r,g,b,a;
 
	r = float(getr32(color)) ⁄ 255.0f;
	g = float(getg32(color)) ⁄ 255.0f;
	b = float(getb32(color)) ⁄ 255.0f;
	a = float(geta32(color)) ⁄ 255.0f;
 
	glColor4f(r, g, b, a);
	
	int real_segments = int(fabsf(d_angle) ⁄ (2 * AL_PI) * (float)segments) + 1;
	
	float theta = d_angle ⁄ float(real_segments);
	float tangetial_factor = tanf(theta);
	float radial_factor = 1 - cosf(theta);
	
	float x = _x + _r * cosf(start_angle);
	float y = _y + _r * sinf(start_angle);
	
	glBegin(GL_LINE_STRIP);
	for(int ii = 0; ii < real_segments + 1; ii++)
	{
		glVertex3f(x, y, depth);
		
		float tx = -(y - _y);
		float ty = x - _x;
		
		x += tx * tangetial_factor;
		y += ty * tangetial_factor;
		
		float rx = _x - x;
		float ry = _y - y;
		
		x += rx * radial_factor;
		y += ry * radial_factor;
	}
	glEnd();
	
	glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
}

그리고 어렵지 않게 원을 그리는 방법은 기본적으로 아래처럼 가능하다는 것도 알수 있죠.
void DrawCircle(float _x, float _y, float _r, float depth, int32_t color, int segments)
{    
	float r,g,b,a;
 
	r = float(getr32(color)) ⁄ 255.0f;
	g = float(getg32(color)) ⁄ 255.0f;
	b = float(getb32(color)) ⁄ 255.0f;
	a = float(geta32(color)) ⁄ 255.0f;
 
	glColor4f(r, g, b, a);
	
	float theta = 2 * AL_PI ⁄ float(segments);
	float tangetial_factor = tanf(theta);
	float radial_factor = 1 - cosf(theta);
	
	float x = _x + _r;
	float y = _y;
	
	glBegin(GL_LINE_LOOP);
	for(int ii = 0; ii < segments; ii++)
	{
		glVertex3f(x, y, depth);
		
		float tx = -(y - _y);
		float ty = x - _x;
		
		x += tx * tangetial_factor;
		y += ty * tangetial_factor;
		
		float rx = _x - x;
		float ry = _y - y;
		
		x += rx * radial_factor;
		y += ry * radial_factor;
	}
	glEnd();
	
	glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
}

이제 이를 integer를 사용하도록 만들어야 할텐데 ..
오늘은 일에 쩔어서 더이상 머리가 돌지를 않는군요(간단함에도 불구하고!!!)