가상화면에 삼각형을 그려할 일이 생겨.. 삼각형 그리기에 대한 포스팅을 하게 되었다;;

일단 쉽게 그릴수 있는 삼각형에 대해 생각을 하자.

쉽게 그릴수 있는 삼각형이란 한변이 x축이나 y축에 평행한 삼각형이다.


위와 같은 x축에 평행한 변을 삼각형을 그릴때의 알고리즘은 다음과 같다.

(P숫자.x = P숫자의 x좌표, P숫자.y = p숫자의 y좌표)

ScreenArray[screen_height][screen_width]
color = //삼각형 색

delta_left = (P3.x - P1.x) / (P3.y - P1.y)  // P3 ~ P1의 기울기
delta_right = (P3.x - P2.x) / (P3.y - P2.y) // P3 ~ P1의 기울기

start_x_position = P1.x
end_x_position  = P2.x

for( y_position = P1.x ; y_position <= P3.y; y_position++)
{
for(x_position = start_x_position ; x_position <= end_x_position; x_position++)
{
          ScreenArray[y_position][x_position] = color
}
start_x_position += delta_left;
end_x_position -= delta_right;
}


그럼 축에 평행한 변이 없는 삼각형은??????????

... 답은 간단하다.. 삼각형을 둘로 쪼갠다~


P4를 구하는 방법은. P3~P1의 직선 방정식을 구한후, y좌표에 P2를 대입한다.
식을 유도하면..


최종적으로 3번 공식으로 구해진 X와 Y2를 P4로 사용하면 되겠다 ^^



이올린에 북마크하기(0) 이올린에 추천하기(0)
Posted by 동자~
프로그래밍/시블2009/02/26 02:05

다음처럼 타임아웃 처리를 위해, 중요처리를 커널에 맡긴후, callback을 통해 임무수행 완료여부를 체크하는 기능이 있다고 가정하자.

    while(!worker->IsClosed()) <-- 3. 임무수행이 종료 되었는가?
        {           
            worker->ReadResponse();  <-- 1. 내부적 Callback을 통해 작업 처리완료시 Close 호출     
            if(timeChecker.CheckTimeOut() && !bTimeout)
            {
                WriteLog(LOG_ERR,worker->GetWorkerID(),"TIMEOUT [%d ms]",timeout_ms);
                worker->Close();       
                bTimeout = true;
            }           
            WriteLog(LOG_DBG,worker->GetWorkerID(),"START SLEEP");        
            Sleep(10);    <-- 2. CPU 점유율을 낮추기 위한 처리
            WriteLog(LOG_DBG,worker->GetWorkerID(),"END SLEEP");               
                  
        }

이때 가끔식.. Sleep에서 런타임에러가 나는 경우를 확인할 수 있다.

슈퍼 삽질후, Sleep 주변의 로그를 찍어 보았더니 다음과 같은 로그를 찍은후, 에러가 났다.

[02/25/09:19:25:06]::[51]::[#1]::[DBG]:::[CHECKING_TIMEOUT]:::[DURATION TIME=109ms]
[02/25/09:19:25:06]::[52]::[#1]::[DBG]:::START SLEEP
[02/25/09:19:25:06]::[53]::[#1]::[DBG]:::[CB]::[Status: Response Received (1024Bytes)]
[02/25/09:19:25:06]::[54]::[#1]::[SVC]:::Status Change[E_HTTP_READ_RESPONSE(5)]->[E_HTTP_READ_RESPONSE(5)]
[02/25/09:19:25:06]::[55]::[#1]::[DBG]:::[CB]::[Status: Request complete]


다음과 같은 상황을 예상해 볼 수 있다.

Process가 Sleep상태일때, Callback을 통해 무언가 작업을 하려하면, Sleep에서 런타임 에러가 발생한다.

즉 이런 경우에는 싱글스레드에서도, 크리티컬 섹션을 정의할 필요가 있다.

다음과 같이 임의로 크리티컬 섹션을 정의하여 위 문제를 해결하였다.
extern bool isSleep;

...

        while(!worker->IsClosed())
        {           
            worker->ReadResponse();       
            if(timeChecker.CheckTimeOut())
            {
                WriteLog(LOG_ERR,worker->GetWorkerID(),"TIMEOUT [%d ms]",timeout_ms);
                worker->Close();       
                //bTimeout = true;
                break;
            }       
            isSleep= false;           
            Sleep(10);               
            isSleep= true;           
           
        }

void CALLBACK AsyncWorkerCallback(
                                HINTERNET hInternet,
                                DWORD_PTR dwContext,
                                DWORD dwInternetStatus,
                                LPVOID lpvStatusInformation,
                                DWORD dwStatusInformationLength
)
{
HttpAsyncWorker* pWorker = (HttpAsyncWorker*)dwContext;
...
case INTERNET_STATUS_REQUEST_COMPLETE:       
            while(!isSleep)
            {           

            }
pWorker->someDoIt();
            break;
...
}


이올린에 북마크하기(0) 이올린에 추천하기(0)
Posted by 동자~
리눅스/c2009/02/24 17:22
lseek을 사용하여 file의 위치를 임의로 변경할 수 있다.


int oldMask = umask(0000);
int fd = open("fileData.data", O_RDWR | O_CREAT | O_APPEND, 0755);
umask(oldMask);

lseek(fd,0,SEEK_SET);

write(fd,(void*)BUFFER,BUFFER_SIZE);


하지만 위 예제 처럼 file open시 append 모드를 적용하였다면,

파일의 첫부분에 write되어야 하나.

write시 lseek으로 지정한 위치가 무시되어, 파일 마지막에 write하게 된다.

이올린에 북마크하기(0) 이올린에 추천하기(0)
Posted by 동자~