본문 바로가기

old drawer/programming

[Programming] 3D 프로그래밍에 필요한 간단한 수학 공식 소스

3d 프로그래밍을 하면서 필요한 공식들을 한 곳에 모아봤습니다.

공식은 아는데 막상 구현하기 귀찮고 찾자니 이곳저곳에 있어서

불편했었는데 이참에 이렇게 모아서 정리했습니다. 앞으로도

조금씩 추가할 생각이구요..그럼 즐프~!

함수 선언부

//2점이 이루는 백터 구하기(점1, 점2, 결과)
void HJGetVector(const float *p1,const float *p2, float *result);

//점과 평면의 거리(점, 평면의 방정식)
float HJGetLenPointFromPlane(const float *p,const float *plane);

//3점으로 이루는 외적 구하기(점1,점2,점3)
void HJOuterPoroduct(const float *p1,const float *p2,const float *p3 ,int*result);

//3점으로 평면방정식구하기(점3개, 결과)
void HJPlaneFunction(const float *p,float *result);

//3점으로 내적구하기
float HJInterPoroduct(const float *p1, const float *p2, const float *p3);

//직선과 평면의 교점 구하기
void HJCrossPlaneToLine(const float * p1,const float *p2,const float *plane, float*result);

//백터 크기구하기
float HJVectorSize(const float* v);

//백터의 단위백터 구하기
void HJOneVector(const float* v, float *result);

함수 정의


////////////////////////////////
//백터 구하기(점1,점2,결과값) //
////////////////////////////////
inline void HJGetVector(const float *p1,const float *p2, float *result)
{
result[0]=p2[0]-p1[0];
result[1]=p2[1]-p1[1];
result[2]=p2[2]-p1[2];
}


/////////////////////////////
//내적 구하기(점1,점2,점3) //
/////////////////////////////
inline float HJInterPoroduct(const float * p1,const float *p2,const float *p3)
{
//u,v백터
float u[3]={0,0,0}, v[3]={0,0,0};

HJGetVector(p1,p2,u); //첫백터 구하기
HJGetVector(p2,p3,v); //두번째 백터 구하기

double a = acos((u[0]*v[0]+u[1]*v[1]+u[2]*v[2]) / (sqrt(u[0]*u[0] + u[1]*u[1] +u[2]*u[2]) * sqrt(v[0]*v[0] + v[1]*v[1] +v[2]*v[2])) ) / 3.141592*180.0;
if( a > 180.0 ) return float(360-a);
else return (float)a;

}

///////////////////

//백터 크기구하기 //

///////////////////
inline float HJVectorSize(const float* v)
{
return sqrt( v[0]*v[0] + v[1]*v[1] + v[2]*v[2] );
}

///////////////////

//단위백터 구하기//

///////////////////
void HJOneVector(const float* v, float *result)
{
//백터 크기구하기
float len = HJVectorSize(v);

result[0]=v[0]/len;
result[1]=v[1]/len;
result[2]=v[2]/len;
}

///////////////////////////////////////////////////////////////////
//외적 구하기(점1,점2, 점3) //
//http://blog.naver.com/songsmir?Redirect=Log&logNo=100116737182 //
//p1부터 p2,p3으로 뻗어나가는 백터 //
///////////////////////////////////////////////////////////////////

void HJOuterPoroduct(const float *p1,const float *p2,const float *p3 ,int*result)
{
//u,v백터
float u[3]={0,0,0}, v[3]={0,0,0};

HJGetVector(p1,p2,u); //첫백터 구하기
HJGetVector(p1,p3,v); //두번째 백터 구하기

result[0]=u[1]*v[2]-u[2]*v[1];
result[1]=u[2]*v[0]-u[0]*v[2];
result[2]=u[0]*v[1]-u[1]*v[0];

}
//////////////////////////////////////////
//평면방정식구하기(3점의 1차원배열,결과) //
//http://www.gisdeveloper.co.kr/456 //
//3점은 시계방향으로 구성 //
/////////////////////////////////////////
void HJPlaneFunction(const float *p,float *result)
{
//////////////////////
//평면 방정식 구하기 //
//Ax+By+Cz+D=0 //
//////////////////////

//3점 세팅
float x1,y1,z1,x2,y2,z2,x3,y3,z3;
x1=p[0];
y1=p[1];
z1=p[2];

x2=p[3];
y2=p[4];
z2=p[5];

x3=p[6];
y3=p[7];
z3=p[8];

//평면방정식 유도
result[0] = y1*(z2-z3)+y2*(z3-z1)+y3*(z1-z2);
result[1] = z1*(x2-x3)+z2*(x3-x1)+z3*(x1-x2);
result[2] = x1*(y2-y3)+x2*(y3-y1)+x3*(y1-y2);
result[3] = -(x1*(y2*z3 - y3*z2)+x2*(y3*z1 - y1*z3)+x3*(y1*z2 - y2*z1));

}


//////////////////////////////////////
//점과 평면의 거리(점, 평면방정식) //
//http://www.gisdeveloper.co.kr/456 //
//3점은 시계방향으로 구성 //
//////////////////////////////////////
float HJGetLenPointFromPlane(const float *p,const float *planeFunc)
{
//점의 방향에 따라 결과는 음/양으로 나옴
return ( ( planeFunc[0]*p[0] + planeFunc[1]*p[1] + planeFunc[2]*p[2] + planeFunc[3] ) / sqrt(planeFunc[0]*planeFunc[0] + planeFunc[1]*planeFunc[1] + planeFunc[2]*planeFunc[2]) );

}

///////////////////////////////////////////////////////////////////////////////////
//평면과 직선(2점) 교점 구하기 //
//http://cafe.naver.com/gisdev.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=1329 //
///////////////////////////////////////////////////////////////////////////////////
void HJCrossPlaneToLine(const float *p1 ,const float *p2,const float *plane,float*result)
{
float dx=p2[0]-p1[0];
float dy=p2[1]-p1[1];
float dz=p2[2]-p1[2];

float A=p1[0];
float B=p1[1];
float C=p1[2];

float a=plane[0];
float b=plane[1];
float c=plane[2];
float d=plane[3];

float t=-(a*A+b*B+c*C+d)/(a*dx+b*dy+c*dz);

result[0]=A + dx * t;
result[1]=B + dy * t;
result[2]=C + dz * t;
}