2차원 평면 상에서 어느 한 점의 위상(phase)을 알고 싶을 때, 쉽게 말해서 x축과 이루는 각을 알고 싶을 때 사용할 수 있는 함수가 atan2(아크 탄젠트 투) 이다. 이 함수의 원형은 다음과 같다.

1
double atan2(double y, double x)
 

이 함수는 atan(y/x) 결과 값을 반환하며, 반환값의 범위는 -pi 부터 +pi 까지이다. (즉, -3.14 ~ + 3.14)

이 함수를 사용할 때 주의할 점은 점의 y좌표를 먼저 써주어야 한다는 것이다. 너무나 당연스럽게 (x, y) 좌표 순서대로 써줄 경우 잘못된 결과를 얻게 될 수 있다. 몇몇 2차원 좌표에 대하여 atan2 함수를 적용하였을 때 결과값을 아래 그림에 정리하였다. 다시 한 번 말하지만, (x, y) 좌표가 서로 뒤바뀌어 써주어야 한다는 점에 주의하기 바란다.


저작자 표시


여러 소스를 보았지만 가장 완벽한 소스는 아래와 같습니다.


출처 : http://borlandforum.com/impboard/impboard.dll?action=read&db=bcb_tip&no=880 + 알파

#include <stdio.h>

#include <math.h>


#define round(x)        ((x) >= 0 ? (long)((x) + 0.5) : (long)((x) - 0.5))


int getInternalAngle(int ox, int oy, int px, int py, int qx, int qy)

{

    float oq = sqrt(pow(pointO.x - pointQ.x, 2) + pow(pointO.y - pointQ.y, 2));

    float op = sqrt(pow(pointO.x - pointP.x, 2) + pow(pointO.y - pointP.y, 2));

    float pq = sqrt(pow(pointP.x - pointQ.x, 2) + pow(pointP.y - pointQ.y, 2));


    if (op < 1 || pq < 1) {

        return 0;

    }


    float temp = (pow(op,2) + pow(pq,2) - pow(oq,2)) / (2*op*pq);


    float angle = acos(temp);

    angle = angle * (180 / M_PI);


    if (pointO.x != pointP.x) {

        float a = (pointP.y - pointO.y) / (pointP.x - pointO.x);

        float b = (pointP.x * pointO.y - pointO.x*pointP.y) / (pointP.x - pointO.x);

        float y = a * pointQ.x + b;

        if (a > 0) {

            if (pointQ.y > y) {

                angle = 360.0f - angle;

            }

        } else {

            if (pointQ.y < y) {

                angle = 360.0f - angle;

            }

        }

    } else {

        if (pointQ.x < pointP.x) {

            angle = 360.0f - angle;

        }

    }


    return round(angle);

}


int main()

{

    int ax,ay,bx,by,cx,cy;

    printf("점 A의 좌표를 입력하세요 : \n");

    scanf("%d%d",&ax,&ay);

    printf("점 B의 좌표를 입력하세요 : \n");

    scanf("%d%d",&bx,&by);

    printf("점 C의 좌표를 입력하세요 : \n");

    scanf("%d%d",&cx,&cy);

    printf("ABC의 각도는 %d도 입니다.\n",getInternalAngle(ax,ay,bx,by,cx,cy));


    return 0;

}



별거 없는데... 생각하는데 시간이 너무 들었네요.. orz

+ Recent posts