⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 t3dlib4.cpp

📁 3D游戏编程大师技巧第十二章的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
///////////////////////////////////////////////////////////////

float Fast_Cos(float theta)
{
// this function uses the cos_look[] lookup table, but
// has logic to handle negative angles as well as fractional
// angles via interpolation, use this for a more robust
// cos computation that the blind lookup, but with with
// a slight hit in speed

// convert angle to 0-359
theta = fmodf(theta,360);

// make angle positive
if (theta < 0) theta+=360.0;

// compute floor of theta and fractional part to interpolate
int theta_int    = (int)theta;
float theta_frac = theta - theta_int;

// now compute the value of sin(angle) using the lookup tables
// and interpolating the fractional part, note that if theta_int
// is equal to 359 then theta_int+1=360, but this is fine since the
// table was made with the entries 0-360 inclusive
return(cos_look[theta_int] + 
       theta_frac*(cos_look[theta_int+1] - cos_look[theta_int]));

} // end Fast_Cos

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

void POLAR2D_To_POINT2D(POLAR2D_PTR polar, POINT2D_PTR rect)
{
// convert polar to rectangular
rect->x = polar->r*cosf(polar->theta);
rect->y = polar->r*sinf(polar->theta);

} // end POLAR2D_To_POINT2D

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

void POLAR2D_To_RectXY(POLAR2D_PTR polar, float *x, float *y)
{
// convert polar to rectangular
*x = polar->r*cosf(polar->theta);
*y = polar->r*sinf(polar->theta);

} // end POLAR2D_To_RectXY

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

void POINT2D_To_POLAR2D(POINT2D_PTR rect, POLAR2D_PTR polar)
{
// convert rectangular to polar
polar->r     = sqrtf((rect->x * rect->x) + (rect->y * rect->y));
polar->theta = atanf(rect->y/rect->x);

} // end POINT2D_To_POLAR2D

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

void POINT2D_To_PolarRTh(POINT2D_PTR rect, float *r, float *theta)
{
// convert rectangular to polar
*r=sqrtf((rect->x * rect->x) + (rect->y * rect->y));
*theta = atanf(rect->y/rect->x);

} // end POINT2D_To_PolarRTh

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

 void CYLINDRICAL3D_To_POINT3D(CYLINDRICAL3D_PTR cyl, POINT3D_PTR rect)
{
// convert cylindrical to rectangular
rect->x = cyl->r*cosf(cyl->theta);
rect->y = cyl->r*sinf(cyl->theta);
rect->z = cyl->z;

} // end CYLINDRICAL3D_To_POINT3D

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

void CYLINDRICAL3D_To_RectXYZ(CYLINDRICAL3D_PTR cyl,  
                              float *x, float *y, float *z)
{
// convert cylindrical to rectangular
*x = cyl->r*cosf(cyl->theta);
*y = cyl->r*sinf(cyl->theta);
*z = cyl->z;

} // end CYLINDRICAL3D_To_RectXYZ

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

void POINT3D_To_CYLINDRICAL3D(POINT3D_PTR rect, 
                              CYLINDRICAL3D_PTR cyl)
{
// convert rectangular to cylindrical
cyl->r     = sqrtf((rect->x * rect->x) + (rect->y * rect->y));
cyl->theta = atanf(rect->y/rect->x);
cyl->z     = rect->z;

} // end POINT3D_To_CYLINDRICAL3D

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

void POINT3D_To_CylindricalRThZ(POINT3D_PTR rect, 
                                       float *r, float *theta, float *z)
{
// convert rectangular to cylindrical
*r     = sqrtf((rect->x * rect->x) + (rect->y * rect->y));
*theta = atanf(rect->y/rect->x);
*z     = rect->z;

} // end POINT3D_To_CylindricalRThZ

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

void SPHERICAL3D_To_POINT3D(SPHERICAL3D_PTR sph, POINT3D_PTR rect)
{
// convert spherical to rectangular
float r;

// pre-compute r, and z
r       = sph->p*sinf(sph->phi);
rect->z = sph->p*cosf(sph->phi);

// use r to simplify computation of x,y
rect->x = r*cosf(sph->theta);
rect->y = r*sinf(sph->theta);

} // end SPHERICAL3D_To_POINT3D

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

void SPHERICAL3D_To_RectXYZ(SPHERICAL3D_PTR sph, 
                                   float *x, float *y, float *z)
{
// convert spherical to rectangular

float r;

// pre-compute r, and z
r  = sph->p*sinf(sph->phi);
*z = sph->p*cosf(sph->phi);

// use r to simplify computation of x,y
*x = r*cosf(sph->theta);
*y = r*sinf(sph->theta);

} // end SPHERICAL3D_To_RectXYZ

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

void POINT3D_To_SPHERICAL3D(POINT3D_PTR rect, SPHERICAL3D_PTR sph)
{
// convert rectangular to spherical
sph->p = sqrtf((rect->x*rect->x)+(rect->y*rect->y)+(rect->z*rect->z));

sph->theta = atanf(rect->y/rect->x);

// we need r to compute phi
float r = sph->p*sinf(sph->phi);

sph->phi   = asinf(r/sph->p);

} // end POINT3D_To_CYLINDRICAL3D

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

void POINT3D_To_SphericalPThPh(POINT3D_PTR rect, 
                                      float *p, float *theta, float *phi)
{
// convert rectangular to spherical
*p     = sqrtf((rect->x*rect->x)+(rect->y*rect->y)+(rect->z*rect->z));
*theta = atanf(rect->y/rect->x);

// we need r to compute phi
float r = sqrtf((rect->x * rect->x) + (rect->y * rect->y));
*phi    = asinf(r / (*p));

} // end POINT3D_To_SphericalPThPh

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

void VECTOR2D_Add(VECTOR2D_PTR va, 
                         VECTOR2D_PTR vb, 
                         VECTOR2D_PTR vsum)
{
// this function adds va+vb and return it in vsum
vsum->x = va->x + vb->x;
vsum->y = va->y + vb->y;

} // end VECTOR2D_Add

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

VECTOR2D VECTOR2D_Add(VECTOR2D_PTR va, 
                      VECTOR2D_PTR vb)
{
// this function adds va+vb and returns the result on 
// the stack
VECTOR2D vsum;

vsum.x = va->x + vb->x;
vsum.y = va->y + vb->y;

// return result
return(vsum);

} // end VECTOR2D_Add

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

void VECTOR2D_Sub(VECTOR2D_PTR va, 
                         VECTOR2D_PTR vb, 
                         VECTOR2D_PTR vdiff)
{
// this function subtracts va-vb and return it in vdiff
// the stack
vdiff->x = va->x - vb->x;
vdiff->y = va->y - vb->y;

} // end VECTOR2D_Sub

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

VECTOR2D VECTOR2D_Sub(VECTOR2D_PTR va, 
                      VECTOR2D_PTR vb)
{
// this function subtracts va-vb and returns the result on 
// the stack
VECTOR2D vdiff;

vdiff.x = va->x - vb->x;
vdiff.y = va->y - vb->y;

// return result
return(vdiff);                      

} // end VECTOR2D_Sub

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

void VECTOR2D_Scale(float k, 
                    VECTOR2D_PTR va, 
                    VECTOR2D_PTR vscaled)
{
// this function scales a vector by the constant k,
// leaves the original unchanged, and returns the result
// in vscaled

// multiply each component by scaling factor
vscaled->x = k*va->x;
vscaled->y = k*va->y;

} // end VECTOR2D_Scale

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

void VECTOR2D_Scale(float k, VECTOR2D_PTR va)
{
// this function scales a vector by the constant k,
// by scaling the original

// multiply each component by scaling factor
va->x*=k;
va->y*=k;

} // end VECTOR2D_Scale

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

float VECTOR2D_Dot(VECTOR2D_PTR va, VECTOR2D_PTR vb)
{
// computes the dot product between va and vb
return( (va->x * vb->x) + (va->y * vb->y) );
} // end VECTOR2D_Dot

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

float VECTOR2D_Length(VECTOR2D_PTR va)
{
// computes the magnitude of a vector, slow

return(sqrtf(va->x*va->x + va->y*va->y));

} // end VECTOR2D_Length

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

float VECTOR2D_Length_Fast(VECTOR2D_PTR va)
{
// computes the magnitude of a vector using an approximation
// very fast
return( (float)Fast_Distance_2D(va->x, va->y) );

} // end VECTOR2D_Length_Fast

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

void VECTOR2D_Normalize(VECTOR2D_PTR va)
{
// normalizes the sent vector in place

// compute length
float length = sqrtf(va->x*va->x + va->y*va->y );

// test for zero length vector
// if found return zero vector
if (length < EPSILON_E5) 
   return;

float length_inv = 1/length;

// compute normalized version of vector
va->x = va->x*length_inv;
va->y = va->y*length_inv;

} // end VECTOR2D_Normalize

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

void VECTOR2D_Normalize(VECTOR2D_PTR va, VECTOR2D_PTR vn)
{
// normalizes the sent vector and returns the result in vn

VECTOR2D_ZERO(vn);

// compute length
float length = (float)sqrtf(va->x*va->x + va->y*va->y );

// test for zero length vector
// if found return zero vector
if (length < EPSILON_E5) 
   return;

float length_inv = 1/length;

// compute normalized version of vector
vn->x = va->x*length_inv;
vn->y = va->y*length_inv;

} // end VECTOR2D_Normalize

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

void VECTOR2D_Build(VECTOR2D_PTR init,
                    VECTOR2D_PTR term,
                    VECTOR2D_PTR result)
{
// this function creates a vector from two vectors (or points)
//  in 3D space

result->x = term->x - init->x;
result->y = term->y - init->y;

} // end VECTOR2D_Build

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

float VECTOR2D_CosTh(VECTOR2D_PTR va, VECTOR2D_PTR vb)
{
// this function returns the cosine of the angle between
// two vectors. Note, we could compute the actual angle,
// many many times, in further calcs we will want ultimately
// compute cos of the angle, so why not just leave it!
return(VECTOR2D_Dot(va,vb)/(VECTOR2D_Length(va)*VECTOR2D_Length(vb)));

} // end VECTOR2D_CosTh

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

void VECTOR2D_Print(VECTOR2D_PTR va, char *name="v")
{
// this function prints out a VECTOR2D

Write_Error("\n%s=[",name);
for (int index=0; index<2; index++)
    Write_Error("%f, ",va->M[index]);
Write_Error("]");

} // end VECTOR2D_Print

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

void VECTOR3D_Add(VECTOR3D_PTR va, 
                  VECTOR3D_PTR vb, 
                  VECTOR3D_PTR vsum)
{
// this function adds va+vb and return it in vsum
vsum->x = va->x + vb->x;
vsum->y = va->y + vb->y;
vsum->z = va->z + vb->z;

} // end VECTOR3D_Add

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

VECTOR3D VECTOR3D_Add(VECTOR3D_PTR va, 
                      VECTOR3D_PTR vb)
{
// this function adds va+vb and returns the result on 
// the stack
VECTOR3D vsum;

vsum.x = va->x + vb->x;
vsum.y = va->y + vb->y;
vsum.z = va->z + vb->z;

// return result
return(vsum);

} // end VECTOR3D_Add

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

void VECTOR3D_Sub(VECTOR3D_PTR va, 
                  VECTOR3D_PTR vb, 
                  VECTOR3D_PTR vdiff)
{
// this function subtracts va-vb and return it in vdiff
// the stack
vdiff->x = va->x - vb->x;
vdiff->y = va->y - vb->y;
vdiff->z = va->z - vb->z;

} // end VECTOR3D_Sub

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

VECTOR3D VECTOR3D_Sub(VECTOR3D_PTR va, VECTOR3D_PTR vb)
{
// this function subtracts va-vb and returns the result on 
// the stack
VECTOR3D vdiff;

vdiff.x = va->x - vb->x;
vdiff.y = va->y - vb->y;
vdiff.z = va->z - vb->z;

// return result
return(vdiff);                      

} // end VECTOR3D_Sub

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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -