C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 자료실
C++Builder Programming Resources
[670] 3차원 엔진 구현 희귀 소스 (Opengl,DirectX 내부 구현 함수)
이용희 [topoview] 24559 읽음    2013-01-07 13:42
우리 민족의 가르침들
가정에서 부처가 되라.
가정에 충실해야 한다.
부모와 가족을 부양하는 것은 성스러운 일이다.
아내(남편)를 배려할 줄 알아야 한다.
가족을 부양하는 것은 사욕이 아니다.
남을 미워하기 전에 용서하라.
부모가 부처다.
부모 마음을 알면 하늘의 마음을 안다.
진정으로 남과 하나가 되어야 한다.
진정으로 남을 위하는 맘이 곧 진정한 법이다.
사람이 되야 일이 된다.
우리가 부모를 버리면 자식은 우리를 고려장 시킨다.
돈보다 사람을 앞세워야 한다.
있어도 편한 것이 아니고 없다고 불편한 것도 아니다.
부모에게 11조를 해야 한다.
자식은 부모의 거울이다.
편하게 살기 위하여 도를 닦는 것이다.
부모 말씀에 도맥이 있다.
아버지, 어머니만 알면 다 깨운친 것이다.
가족을 부양하는 것은 사욕이 아니다.
지는 것이 이기는 것이다.
마음을 내려 놓을 줄(下心) 알아야 한다.
가정을 벗어나는 것은 삿된 도이다.
가정이 도장이고 교회이고 절이다.
참 사람이 되야 한다.
가정이 화목해지면 온 세상이 화목해진다.
부모에게 잘하면  자식에게 돌아온다.
진심으로 어른을 공경할 줄 알아야 한다.
이웃과 더불어 살 줄 알아야 한다.
남의 고통을 내 고통으로 여길 줄 알아야 한다.
살아서 행복하게 살아야 죽어서도 행복하게 산다.
마음에 걸림이 없어야 한다.
돈에 너무 애착이 강하면 사람됨을 이탈한다.
종교 단체의 끈에 걸리면 가정을 이탈한다.
부모님이 있어서 하나님도 있고, 부처님도 있고, 공자님도 있는 것이다.
종교에 깊이 빠지면 자신을 잃어 버린다.
종교를  가까이 하면  가정이 멀어진다.
우리 고유의 의식주를 찾아야 한다.
남도 나만큼 귀하다.
--------------------------
3차원 좌표에서 3차원 회전 공식은 많으나
실제로 정확하게 구현된 것이 드물다.
모든 함수는 첨부 파일 참조 할것

OpenGl이나 DirectX 등에서
라이브러리 함수로만 구현되어 있어서 구현된 소오슷 를 설명한다.

로봇이나 항공기, 선반, 밀링 에서
현재의 3차원 좌표가 3차원 이동 및 3차원 회전에 의해 어느 점으로
옮겨 졌는지 계산하기 위한 필수 함수임.

도한 3차원 레더링 구현의 기초 함수입니다.
굉장히 중요한 함수 입니다.

특히 좌표계를 조심해서 다루어야 합니다.
오른쪽손 방향이 +X축
위쪽 방향이     +Y축
앞 방향이       +축 방향임.


사용는 방법
SGLPoint3D v; //회전 시킬 3차원 점의 변수
SGLPoint3D result; //회전후 저장할 변수

//회전 시킬 좌표를 변수에 넣는다.
v.x=10.23;
v.y=3.43;
v.z=-1.2;
v.w=0.0;

SGLMatrix44 tt; //4XX행열을 생성
tt.identity(); //단위 행렬을 만든다. 초기화 함.
tt.accumRotateXYZ(1.0, 0.0,0.0, 45.0); //x축으로 45도 회전

result=tt*v; //v점의 3차원 좌표가 x축으로 45도 회전하여 결과 값이 result에 들어감..

첨부파일 참조
===========================================
// 3차원 벡터 헤더 파일
class SGLVector3D
{
public:
float x, y, z, w;//X,Y,Z의 좌표와 W가 1.0이 아닌 것에 주의
public:
SGLVector3D(void) : x(0.0f), y(0.0f), z(0.0f), w(0.0f) //생성자
{}
SGLVector3D(const SGLVector3D& v) : x(v.x), y(v.y), z(v.z), w(0.0f) //1개의 인자로 생성자
{}
SGLVector3D(float X, float Y, float Z) : x(X), y(Y), z(Z), w(0.0f) //3개의 인자로 생성자
{}
~SGLVector3D(void)//소멸자
{}

float length(void) const; //벡터의 크기를 돌려준다.
void  normalize(void); //벡터를 정규화 한다.
float dot(const SGLVector3D& v) const; //두 벡터의 내적을 구한다.
SGLVector3D cross(const SGLVector3D& v) const; //두 벡터의 외적을 구한다.,

//VECTOR3D = VECTOR3D - VECTOR3D
SGLVector3D operator-(const SGLVector3D& v) const; //두 벡터의 빼기
const SGLVector3D& operator-(const SGLVector3D& v);
void operator-=(const SGLVector3D& v);

//VECTOR3D = VECTOR3D + VECTOR3D
SGLVector3D operator+(const SGLVector3D& v) const; // 두 벡터의 더하기
const SGLVector3D& operator+(const SGLVector3D& v);
void operator+=(const SGLVector3D& v);

//VECTOR3D = VECTOR3D + float
SGLVector3D operator+(const float f) const; //벡터의 값에 스칼라 값 더하기
const SGLVector3D& operator+(const float f);
void operator+=(const float f);

//VECTOR3D = VECTOR3D - float
SGLVector3D operator-(const float f) const;//벡터의 값에 스칼라값 빼기
const SGLVector3D& operator-(const float f);
void operator-=(const float f);

//VECTOR3D = VECTOR3D * float
SGLVector3D operator*(const float f) const; //벡터에 값에 스칼라값 곱하기, 나누기는 1.0/f를 사용한다.
//const SGLVector3D& operator*(const float f);
void operator*=(const float f);

};


#endif

===============================================
// 4X4 행렬 헤더파일

#ifndef SGLMATRIX44_H
#define SGLMATRIX44_H

#include "SGLVector3D.h" //3d 벡터
#include "SGLPoint3D.h"  //3d 정점
//4X4 행렬
class SGLMatrix44
{
public:
union
{
  //여러가지 표현방식을 사용함.
  struct // 각기 하나의변수로
  {
   float m11, m12, m13, m14; //1행4열
   float m21, m22, m23, m24; //2행4열
   float m31, m32, m33, m34; //3행4열
   float m41, m42, m43, m44; //4행4열
  };
  struct
  {
   float r1[4]; //회전 형태로
   float r2[4];
   float r3[4];
   float r4[4];
  };
  struct
  {
   float m[4][4];//2차원 배열 형태로
  };
};
public:
SGLMatrix44(void);//빈 생성자
SGLMatrix44(const SGLMatrix44& matrix); //행렬값을 가지고 생성
~SGLMatrix44(void);//소멸자

void identity(void);//단위 행렬로 만든다
void transpose(void);//전치 행렬로 변환
void rotateX(float angle); //X축 회전값 행렬에 할당
void rotateY(float angle); //Y축 회전값 행렬에 할당
void rotateZ(float angle); //Z축 회전값 행렬에 할당
void rotateXYZ(float x, float y, float z, float angle); //오일러 각도를 가지고 X,Y,Z축으로 회전값을 계산하여 행렬에 할당
void translate(float x, float y, float z); //X,Y,Z축으로 이동
void scale(float x, float y, float z); //X,Y,Z축으로 크기 변화

//accum
void accumRotateX(float angle); //X축 회전 값과 현재 값 곱하기 , 실제 X축으로 회전
void accumRotateY(float angle); //Y축 회전 값과 현재 값 곱하기,  실제 Y축으로 회전
void accumRotateZ(float angle); //Z축 회전값과 현재 값 곱하기, 실제  Z축으로 회전
void accumRotateXYZ(float x, float y, float z, float angle); //X,Y,Z축 회전 값과 현재 값 곱하기, 실제 x,y,z축으로 회전하기
void accumTranslate(float x, float y, float z); //이동 회전 값과 현재 값 곱하기, 실제 이동하기
void accumScale(float x, float y, float z);// x,y,z축 크기값과 현재 값 곱하기, 실제 크기 변화하기

//MATRIX44 = MATRIX44 + MATRIX44
SGLMatrix44 operator+(const SGLMatrix44& matrix) const; //4X4 행렬 더하기 연산자
//const SGLMatrix44& operator+(const SGLMatrix44& matrix);
void operator+=(const SGLMatrix44& matrix); //

//MATRIX44 = MATRIX44 - MATRIX44
SGLMatrix44 operator-(const SGLMatrix44& matrix) const;//4X4 행렬 빼기 연산자
//const SGLMatrix44& operator-(const SGLMatrix44& matrix);
void operator-=(const SGLMatrix44& matrix);

//MATRIX44 = MATRIX44 * MATRIX44
SGLMatrix44 operator*(const SGLMatrix44& matrix) const;//4X4 행렬 곱하기 연산자
//const SGLMatrix44& operator*(const SGLMatrix44& matrix);
void operator*=(const SGLMatrix44& matrix);

//VECTOR3D = MATRIX44 * VECTOR3D
SGLVector3D operator*(const SGLVector3D& v) const; //3차원 벡터 곱하기 연산자

//POINT3D = MATRIX44 * POINT3D
SGLPoint3D operator*(const SGLPoint3D& pt) const;//3차원 정점 곱하기 연산자

};


#endif
============================================


구현 파일
=============================================

#include "SGLMatrix44.h"
//생성자로서 0으로 초기화 한다.

SGLMatrix44::SGLMatrix44(void)
{
memset(this, 0, sizeof(SGLMatrix44));
}

//행열값을 가지고 초기화 한다.
SGLMatrix44::SGLMatrix44(const SGLMatrix44& matrix)
{
for(int i=0; i<4; i++)
  for(int j=0; j<4; j++)
   m[i][j] = matrix.m[i][j];

}
//소멸자
SGLMatrix44::~SGLMatrix44(void)
{
}
//단위 행렬로 만든다.
void SGLMatrix44::identity(void)
{
memset(this, 0, sizeof(SGLMatrix44));
m11 = m22 = m33 = m44 = 1.0f;
}
//전치 행렬을 만든다
void SGLMatrix44::transpose(void)
{
SGLMatrix44 t;

t.m11 = r1[0];
t.m12 = r1[1];
t.m13 = r1[2];
t.m14 = r1[3];

t.m21 = r2[0];
t.m22 = r2[1];
t.m23 = r2[2];
t.m24 = r2[3];

t.m31 = r3[0];
t.m32 = r3[1];
t.m33 = r3[2];
t.m34 = r3[3];

t.m41 = r4[0];
t.m42 = r4[1];
t.m43 = r4[2];
t.m44 = r4[3];

*this = t;
}
//x축으로 회전값 행렬에 할당
void SGLMatrix44::rotateX(float angle)
{
identity();
float COS = cos(angle);
float SIN = sin(angle);

m22 = COS;
m23 = -SIN;
m32 = SIN;
m33 = COS;
}
//Y축으로 회전값 행렬에 할당
void SGLMatrix44::rotateY(float angle)
{
identity();
float COS = cos(angle);
float SIN = sin(angle);

m21 = COS;
m23 = SIN;
m31 = -SIN;
m33 = COS;
}
//Z축으로 회전값 행렬에 할당
void SGLMatrix44::rotateZ(float angle)
{
identity();
float COS = cos(angle);
float SIN = sin(angle);

m11 = COS;
m12 = -SIN;
m21 = SIN;
m22 = COS;
}
//x,y,z축으로 회전값 행렬에 할당
void SGLMatrix44::rotateXYZ(float x, float y, float z, float angle)
{
identity();
SGLVector3D v(x, y, z);
v.normalize();

float COS = cos(angle);
float SIN = sin(angle);

m11 = v.x*v.x*(1-C)+C;
m12 = v.x*v.y*(1-C)-v.z*S;
m13 = v.z*v.x*(1-C)+v.y*S;
m14 = 0.0f;

m21 = v.x*v.y*(1-C)+v.z*S;
m22 = v.y*v.y*(1-C)+C;
m23 = v.y*v.z*(1-C)-v.x*S;
m24 = 0.0f;

m31 = v.z*v.x*(1-C)-v.y*S;
m32 = v.y*v.z*(1-C)+v.x*S;
m33 = v.z*v.z*(1-C)+C;
m34 = 0.0f;

m41 = 0.0f;
m42 = 0.0f;
m43 = 0.0f;
m44 = 1.0f;
}
//3 차원 이동값 할당
void SGLMatrix44::translate(float x, float y, float z)
{
identity();
m14 = x;
m24 = y;
m34 = z;
}
//3차원 확대/축소 값 할당
void SGLMatrix44::scale(float x, float y, float z)
{
identity();
m11 = x;
m22 = y;
m33 = z;
}

//x축으로 회전한다.
void SGLMatrix44::accumRotateX(float angle)
{
SGLMatrix44 tm;
tm.rotateX(angle);
*this *= tm;
}
//y축으로 회전한다.
void SGLMatrix44::accumRotateY(float angle)
{
SGLMatrix44 tm;
tm.rotateY(angle);
*this *= tm;
}
//z축으로 회전한다.
void SGLMatrix44::accumRotateZ(float angle)
{
SGLMatrix44 tm;
tm.rotateZ(angle);
*this *= tm;
}
//x,y,z,축으로 회전한다.
void SGLMatrix44::accumRotateXYZ(float x, float y, float z, float angle)
{
SGLMatrix44 tm;
tm.rotateXYZ(x, y, z, angle);
*this *= tm;
}
//x,y,z축으로 이동한다.
void SGLMatrix44::accumTranslate(float x, float y, float z)
{
SGLMatrix44 tm;
tm.translate(x, y, z);
*this *= tm;
}
//x,y,z축으로 크기를 변환한다.
void SGLMatrix44::accumScale(float x, float y, float z)
{
SGLMatrix44 tm;
tm.scale(x, y, z);
*this *= tm;
}


//4곱하기4 행열 더하기
//MATRIX44 = MATRIX44 + MATRIX44
SGLMatrix44 SGLMatrix44::operator+(const SGLMatrix44& matrix) const
{
SGLMatrix44 t;
int i, j=0;
for(i=0; i<4; i++)
{
  for(j=0; j<4; j++)
  {
   t.m[i][j] = m[i][j] + matrix.m[i][j];
  }
}
return t;
}
/*const SGLMatrix44& SGLMatrix44::operator+(const SGLMatrix44& matrix)
{
int i, j=0;
for(i=0; i<4; i++)
{
  for(j=0; j<4; j++)
  {
   m[i][j] += matrix.m[i][j];
  }
}
return *this;
}*/
//+= 행렬 연산자
void SGLMatrix44::operator+=(const SGLMatrix44& matrix)
{
int i, j=0;
for(i=0; i<4; i++)
{
  for(j=0; j<4; j++)
  {
   m[i][j] += matrix.m[i][j];
  }
}
}
//빼기 행렬 연산자
//MATRIX44 = MATRIX44 - MATRIX44
SGLMatrix44 SGLMatrix44::operator-(const SGLMatrix44& matrix) const
{
SGLMatrix44 t;
int i, j=0;
for(i=0; i<4; i++)
{
  for(j=0; j<4; j++)
  {
   t.m[i][j] = m[i][j] - matrix.m[i][j];
  }
}
return t;
}
/*const SGLMatrix44& SGLMatrix44::operator-(const SGLMatrix44& matrix)
{
int i, j=0;
for(i=0; i<4; i++)
{
  for(j=0; j<4; j++)
  {
   m[i][j] -= matrix.m[i][j];
  }
}
return *this;
}*/
//-= 행렬 연산자
void SGLMatrix44::operator-=(const SGLMatrix44& matrix)
{
int i, j=0;
for(i=0; i<4; i++)
{
  for(j=0; j<4; j++)
  {
   m[i][j] -= matrix.m[i][j];
  }
}
}
//해렬 곱하기 연산자
//MATRIX44 = MATRIX44 * MATRIX44
SGLMatrix44 SGLMatrix44::operator*(const SGLMatrix44& matrix) const
{
SGLMatrix44 t;
int i, j, k;
for(i=0; i<4; i++)
{
  for(j=0; j<4; j++)
  {
   t.m[i][j] = 0;
   for(k=0; k<4; k++)
   {
    t.m[i][j] += m[i][k] * matrix.m[k][j];
   }
  }
}
return t;
}
/*const SGLMatrix44& SGLMatrix44::operator*(const SGLMatrix44& matrix)
{
SGLMatrix44 t;
int i, j, k;
for(i=0; i<4; i++)
{
  for(j=0; j<4; j++)
  {
   t.m[i][j] = 0;
   for(k=0; k<4; k++)
   {
    t.m[i][j] += m[i][k] * matrix.m[k][j];
   }
  }
}
*this = t;
return *this;
}*/
//*= 행렬 연산자
void SGLMatrix44::operator*=(const SGLMatrix44& matrix)
{
SGLMatrix44 t;
int i, j, k;
for(i=0; i<4; i++)
{
  for(j=0; j<4; j++)
  {
   t.m[i][j] = 0;
   for(k=0; k<4; k++)
   {
    t.m[i][j] += m[i][k] * matrix.m[k][j];
   }
  }
}
*this = t;
}

//VECTOR3D = MATRIX44 * VECTOR3D
// 3차원 점과 4X4 해열 연산자.
SGLVector3D SGLMatrix44::operator*(const SGLVector3D& v) const
{

return SGLVector3D(
  m11*v.x + m12*v.y + m13*v.z + m14*v.w,
  m21*v.x + m22*v.y + m23*v.z + m24*v.w,
  m31*v.x + m32*v.y + m33*v.z + m34*v.w
  );
}

//POINT3D = MATRIX44 * POINT3D
//3차원 점과 4X4 행렬 연산자
SGLPoint3D SGLMatrix44::operator*(const SGLPoint3D& pt) const
{
SGLPoint3D out_p;
out_p.x = m11*pt.x + m12*pt.y + m13*pt.z + m14*pt.w;
out_p.y = m21*pt.x + m22*pt.y + m23*pt.z + m24*pt.w;
out_p.z = m31*pt.x + m32*pt.y + m33*pt.z + m34*pt.w;
out_p.w = m41*pt.x + m42*pt.y + m43*pt.z + m44*pt.w;
out_p.x /= out_p.w;
out_p.y /= out_p.w;
out_p.z /= out_p.w;
out_p.w /= out_p.w;
return out_p;
}
=================================

+ -

관련 글 리스트
670 3차원 엔진 구현 희귀 소스 (Opengl,DirectX 내부 구현 함수) 이용희 24559 2013/01/07
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.