원호를 그리는 것은 부동소수점이 지원되는 플랫폼에서는 어렵지 않은 일 입니다만, 만약 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를 사용하도록 만들어야 할텐데 ..
오늘은 일에 쩔어서 더이상 머리가 돌지를 않는군요(간단함에도 불구하고!!!)