3D_Math

图1:  用两个三角形画矩形,每个三个角形顶点有独立法线

图2:  用四个三角形画矩形,每个三个角形顶点有独立法线

 

 

图3:  用四个三角形画矩形,每个顶点取四周三角形的面法线平均值

 

 

/********************************************************
*文件名:  Sphere.h
*文件描述:  创建一个用三次样条曲线光滑化的不规则球体
*创建人:  陈泽丹
*创建时间:  2010-04-03
*版本:   1.0
*备注:   用角度和R构成三次样条曲线,这样X可单调递增
    如果模型渲染时某些地方有闪烁现象,
    可能是给的区域有重叠的三角形.
    光照球时,不强烈但细微的差距可以肉眼识别(通过阴影)
    色彩球时,强烈但细微的差距看不出差别
*********************************************************/

#pragma once
#include "D3D.h"
#include "D3DPosition.h"

struct SphereVertex
{
 SphereVertex(){}

 SphereVertex(float x, float y, float z, float nx, float ny, float nz, D3DCOLOR dif, D3DCOLOR spe)
 {
  _x  = x;  _y  = y; _z  = z;
  _nx = nx; _ny = ny; _nz = nz;
  _dif = dif;
  _spe = spe;
 }
 float  _x,  _y,  _z;
 float _nx, _ny, _nz;
 D3DCOLOR _dif;
 D3DCOLOR _spe;
 static const DWORD FVF;
};

 


class SphereEx:public virtual D3DPosition
{
public:
 SphereEx(void);
 virtual ~SphereEx(void);

 //建立模型
 bool Setup(IDirect3DDevice9* pDevice,
  const int in_iTS, const int in_iTE, const int in_iTStep,
  const int in_iPS, const int in_iPE, const int in_iPStep);
 //清空模型
 void CleanUp();
 //设置状态
 void SetState(IDirect3DDevice9* pDevice);
 //渲染
 void Rander(IDirect3DDevice9* pDevice);
 //设置最大半径
 void SetR(const float in_fR) { m_fRMAX = in_fR; }
 //开关灯
 void OnOffLight(bool in_bOpenLight) { m_bOpenLight = in_bOpenLight; }
 //初始化为0
 void InitCircle();
 //初始化为随机数
 void InitCircleRand(const int in_iTS, const int in_iTE, const int in_iTStep,
  const int in_iPS, const int in_iPE, const int in_iPStep);
 //设置数值
 void SetValue(const int in_iTA, const int in_iPA, const float in_fValue);

 

protected:
 //修正点(使首尾相连)
 bool Revise(const int in_iTS, const int in_iTE, const int in_iTStep,
  const int in_iPS, const int in_iPE, const int in_iPStep);
 //修正面(使首尾相连)
 void ReviseTriangle3(SphereVertex* v, int& in_ID,
  int in_iCx, int in_iCy,
  int in_iXDistance, int in_iYDistance);

 void CubicSpline_Circle(const int in_iTS, const int in_iTE, const int in_iTStep,
  const int in_iPS, const int in_iPE, const int in_iPStep);
 //三次样条曲线化Theta
 void CubicSplineEx_Theta(const int in_iTS, const int in_iTE, const int in_iTStep,
  const int in_iPS, const int in_iPE, const int in_iPStep,
  const int in_iCubicSplineExStep);
 //三次样条曲线化Phi
 void CubicSplineEx_Phi(const int in_iTS, const int in_iTE, const int in_iTStep,
  const int in_iPS, const int in_iPE, const int in_iPStep,
  const int in_iCubicSplineExStep);
 
 //上色方案
 float GetPointColor(float in_fValue);

 //三种光滑度不同的渲染方式
 //粗糙型
 void AddTriangle1(SphereVertex* v, int& in_ID, int in_iCx, int in_iCy, int in_iXDistance, int in_iYDistance);
 //过渡型
 void AddTriangle2(SphereVertex* v, int& in_ID, int in_iCx, int in_iCy, int in_iXDistance, int in_iYDistance);
 //细腻型
 void AddTriangle3(SphereVertex* v, int& in_ID, int in_iCx, int in_iCy, int in_iXDistance, int in_iYDistance);

 enum
 {
  LIGHT_DIRECT_ID = 0,
  DISTANCE_UNIT = 5,
  ITHETA_COUNT = 180/DISTANCE_UNIT+1,
  IPHI_COUNT = 360/DISTANCE_UNIT+1,
  XYZR = 4,
  POINTFACE = 4,
 };
 float m_fCirclePoint[ITHETA_COUNT][IPHI_COUNT][XYZR];
 float m_fNormal[ITHETA_COUNT][IPHI_COUNT][POINTFACE];
 float m_fDirLightPos[3];
 float m_fRMAX;

 int m_iTriangleCount;
 bool m_bOpenLight;
 D3DLIGHT9 m_DirLight;
 IDirect3DVertexBuffer9* m_pVB;
};

/****************************************
*文件名:  Sphere.cpp
*创建人:  陈泽丹
*创建时间:  2010-04-03
*版本:   1.0
*****************************************/


#include "SphereEx.h"
#include "3D_Math.h"
#include <time.h>

const DWORD SphereVertex::FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_SPECULAR;


SphereEx::SphereEx(void):
m_fRMAX(50),
m_iTriangleCount(0),
m_pVB(0),
m_bOpenLight(true)
{
 m_fDirLightPos[0] = 0.00041f;
 m_fDirLightPos[1] = -0.04470f;
 m_fDirLightPos[2] = 0.998998f;
 srand(time(0));
 InitCircleRand(0,180,30,0,330,30);
}

SphereEx::~SphereEx(void)
{
}

//粗糙型
void SphereEx::AddTriangle1(SphereVertex* v, int& in_ID, int in_iCx, int in_iCy, int in_iXDistance, int in_iYDistance)
{
 D3DXVECTOR3 pNormal;
 int Cx = in_iCx, Cy = in_iCy;

 int Rx = in_iCx+in_iXDistance, Lx = in_iCx-in_iXDistance;
 if( Rx >= ITHETA_COUNT) Rx = Rx-ITHETA_COUNT;
 if( Lx < 0) Lx = Lx+ITHETA_COUNT;


 int Uy = in_iCy+in_iYDistance, Dy = in_iCy-in_iYDistance;
 if( Uy >= IPHI_COUNT) Uy = Uy-IPHI_COUNT;
 if( Dy < 0) Dy = Dy+IPHI_COUNT;
 
 bool bIsClockwise;
 if( in_iCy <= IPHI_COUNT/2)
  bIsClockwise = true;
 else
  bIsClockwise = false;


 int IDX[3];
 int IDY[3];
 int ID_N = 3;

 //down_right
 ComputeCenterTriangle(IDX,IDY,ID_N, Center_DownRight, Cx,Cy,ITHETA_COUNT,IPHI_COUNT,in_iXDistance,in_iYDistance);
 D3DXVECTOR3 p0(m_fCirclePoint[IDX[0]][IDY[0]][0],m_fCirclePoint[IDX[0]][IDY[0]][1],m_fCirclePoint[IDX[0]][IDY[0]][2]);
 D3DXVECTOR3 p1(m_fCirclePoint[IDX[1]][IDY[1]][0],m_fCirclePoint[IDX[1]][IDY[1]][1],m_fCirclePoint[IDX[1]][IDY[1]][2]);
 D3DXVECTOR3 p2(m_fCirclePoint[IDX[2]][IDY[2]][0],m_fCirclePoint[IDX[2]][IDY[2]][1],m_fCirclePoint[IDX[2]][IDY[2]][2]);
 pNormal = ComputeCenterNormal_Sum(m_fCirclePoint,Cx,Cy,bIsClockwise,ITHETA_COUNT,IPHI_COUNT,in_iXDistance,in_iYDistance);
 v[in_ID++] = SphereVertex(p0.x,p0.y,p0.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Cx][Cy][3]), GetPointColor(m_fCirclePoint[Cx][Cy][3])); //0.3
 pNormal = ComputeCenterNormal_Sum(m_fCirclePoint,Cx,Uy,bIsClockwise,ITHETA_COUNT,IPHI_COUNT,in_iXDistance,in_iYDistance);
 v[in_ID++] = SphereVertex(p1.x,p1.y,p1.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Cx][Uy][3]), GetPointColor(m_fCirclePoint[Cx][Uy][3]));//0.8
 pNormal = ComputeCenterNormal_Sum(m_fCirclePoint,Rx,Cy,bIsClockwise,ITHETA_COUNT,IPHI_COUNT,in_iXDistance,in_iYDistance);
 v[in_ID++] = SphereVertex(p2.x,p2.y,p2.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Rx][Cy][3]), GetPointColor(m_fCirclePoint[Rx][Cy][3]));//1

 //up_left
 ComputeCenterTriangle(IDX,IDY,ID_N, Center_UpLef, Rx,Dy,ITHETA_COUNT,IPHI_COUNT,in_iXDistance,in_iYDistance);
 D3DXVECTOR3 p3(m_fCirclePoint[IDX[0]][IDY[0]][0],m_fCirclePoint[IDX[0]][IDY[0]][1],m_fCirclePoint[IDX[0]][IDY[0]][2]);
 D3DXVECTOR3 p4(m_fCirclePoint[IDX[1]][IDY[1]][0],m_fCirclePoint[IDX[1]][IDY[1]][1],m_fCirclePoint[IDX[1]][IDY[1]][2]);
 D3DXVECTOR3 p5(m_fCirclePoint[IDX[2]][IDY[2]][0],m_fCirclePoint[IDX[2]][IDY[2]][1],m_fCirclePoint[IDX[2]][IDY[2]][2]);
 pNormal = ComputeCenterNormal_Sum(m_fCirclePoint,Cx,Cy,bIsClockwise,ITHETA_COUNT,IPHI_COUNT,in_iXDistance,in_iYDistance);
 v[in_ID++] = SphereVertex(p3.x,p3.y,p3.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Cx][Cy][3]), GetPointColor(m_fCirclePoint[Cx][Cy][3]));
 pNormal = ComputeCenterNormal_Sum(m_fCirclePoint,Rx,Cy,bIsClockwise,ITHETA_COUNT,IPHI_COUNT,in_iXDistance,in_iYDistance);
 v[in_ID++] = SphereVertex(p4.x,p4.y,p4.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Rx][Cy][3]), GetPointColor(m_fCirclePoint[Rx][Cy][3]));
 pNormal = ComputeCenterNormal_Sum(m_fCirclePoint,Cx,Dy,bIsClockwise,ITHETA_COUNT,IPHI_COUNT,in_iXDistance,in_iYDistance);
 v[in_ID++] = SphereVertex(p5.x,p5.y,p5.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Cx][Dy][3]), GetPointColor(m_fCirclePoint[Cx][Dy][3]));
}

//过渡型
void SphereEx::AddTriangle2(SphereVertex* v, int& in_ID, int in_iCx, int in_iCy, int in_iXDistance, int in_iYDistance)
{
 D3DXVECTOR3 pNormal;
 int Cx = in_iCx, Cy = in_iCy;

 int Rx = in_iCx+in_iXDistance, Lx = in_iCx-in_iXDistance;
 if( Rx >= ITHETA_COUNT) Rx = Rx-ITHETA_COUNT;
 if( Lx < 0) Lx = Lx+ITHETA_COUNT;


 int Uy = in_iCy+in_iYDistance, Dy = in_iCy-in_iYDistance;
 if( Uy >= IPHI_COUNT) Uy = Uy-IPHI_COUNT;
 if( Dy < 0) Dy = Dy+IPHI_COUNT;
 

 //up_right
 D3DXVECTOR3 p0(m_fCirclePoint[Cx][Cy][0],m_fCirclePoint[Cx][Cy][1],m_fCirclePoint[Cx][Cy][2]);
 D3DXVECTOR3 p1(m_fCirclePoint[Cx][Uy][0],m_fCirclePoint[Cx][Uy][1],m_fCirclePoint[Cx][Uy][2]);
 D3DXVECTOR3 p2(m_fCirclePoint[Rx][Cy][0],m_fCirclePoint[Rx][Cy][1],m_fCirclePoint[Rx][Cy][2]);
 if( in_iCy <= IPHI_COUNT/2)
  pNormal = ComputeNormal(&p0,&p1,&p2);
 else
  pNormal = ComputeNormal(&p2,&p1,&p0);
 v[in_ID++] = SphereVertex(p0.x,p0.y,p0.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Cx][Cy][3]), GetPointColor(m_fCirclePoint[Cx][Cy][3])); //0.3
 v[in_ID++] = SphereVertex(p1.x,p1.y,p1.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Cx][Uy][3]), GetPointColor(m_fCirclePoint[Cx][Uy][3]));//0.8
 v[in_ID++] = SphereVertex(p2.x,p2.y,p2.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Rx][Cy][3]), GetPointColor(m_fCirclePoint[Rx][Cy][3]));//1

 //down_right
 D3DXVECTOR3 p3(m_fCirclePoint[Cx][Cy][0],m_fCirclePoint[Cx][Cy][1],m_fCirclePoint[Cx][Cy][2]);
 D3DXVECTOR3 p4(m_fCirclePoint[Rx][Cy][0],m_fCirclePoint[Rx][Cy][1],m_fCirclePoint[Rx][Cy][2]);
 D3DXVECTOR3 p5(m_fCirclePoint[Cx][Dy][0],m_fCirclePoint[Cx][Dy][1],m_fCirclePoint[Cx][Dy][2]);
 if( in_iCy <= IPHI_COUNT/2)
  pNormal = ComputeNormal(&p3,&p4,&p5);
 else
  pNormal = ComputeNormal(&p5,&p4,&p3);
 v[in_ID++] = SphereVertex(p3.x,p3.y,p3.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Cx][Cy][3]), GetPointColor(m_fCirclePoint[Cx][Cy][3]));
 v[in_ID++] = SphereVertex(p4.x,p4.y,p4.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Rx][Cy][3]), GetPointColor(m_fCirclePoint[Rx][Cy][3]));
 v[in_ID++] = SphereVertex(p5.x,p5.y,p5.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Cx][Dy][3]), GetPointColor(m_fCirclePoint[Cx][Dy][3]));

 //down_left
 D3DXVECTOR3 p6(m_fCirclePoint[Cx][Cy][0],m_fCirclePoint[Cx][Cy][1],m_fCirclePoint[Cx][Cy][2]);
 D3DXVECTOR3 p7(m_fCirclePoint[Cx][Dy][0],m_fCirclePoint[Cx][Dy][1],m_fCirclePoint[Cx][Dy][2]);
 D3DXVECTOR3 p8(m_fCirclePoint[Lx][Cy][0],m_fCirclePoint[Lx][Cy][1],m_fCirclePoint[Lx][Cy][2]);
 if( in_iCy <= IPHI_COUNT/2)
  pNormal = ComputeNormal(&p6,&p7,&p8);
 else
  pNormal = ComputeNormal(&p8,&p7,&p6);
 v[in_ID++] = SphereVertex(p6.x,p6.y,p6.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Cx][Cy][3]), GetPointColor(m_fCirclePoint[Cx][Cy][3]));
 v[in_ID++] = SphereVertex(p7.x,p7.y,p7.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Cx][Dy][3]), GetPointColor(m_fCirclePoint[Cx][Dy][3]));
 v[in_ID++] = SphereVertex(p8.x,p8.y,p8.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Lx][Cy][3]), GetPointColor(m_fCirclePoint[Lx][Cy][3]));

 //up_left
 D3DXVECTOR3 p9(m_fCirclePoint[Cx][Cy][0],m_fCirclePoint[Cx][Cy][1],m_fCirclePoint[Cx][Cy][2]);
 D3DXVECTOR3 p10(m_fCirclePoint[Lx][Cy][0],m_fCirclePoint[Lx][Cy][1],m_fCirclePoint[Lx][Cy][2]);
 D3DXVECTOR3 p11(m_fCirclePoint[Cx][Uy][0],m_fCirclePoint[Cx][Uy][1],m_fCirclePoint[Cx][Uy][2]);
 if( in_iCy <= IPHI_COUNT/2)
  pNormal = ComputeNormal(&p9,&p10,&p11);
 else
  pNormal = ComputeNormal(&p11,&p10,&p9);
 v[in_ID++] = SphereVertex(p9.x,p9.y,p9.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Cx][Cy][3]), GetPointColor(m_fCirclePoint[Cx][Cy][3]));
 v[in_ID++] = SphereVertex(p10.x,p10.y,p10.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Lx][Cy][3]), GetPointColor(m_fCirclePoint[Lx][Cy][3]));
 v[in_ID++] = SphereVertex(p11.x,p11.y,p11.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Cx][Uy][3]), GetPointColor(m_fCirclePoint[Cx][Uy][3]));
}

//细腻型
void SphereEx::AddTriangle3(SphereVertex* v, int& in_ID, int in_iCx, int in_iCy, int in_iXDistance, int in_iYDistance)
{
 D3DXVECTOR3 pNormal;
 int Cx = in_iCx, Cy = in_iCy;

 int Rx = in_iCx+in_iXDistance, Lx = in_iCx-in_iXDistance;
 if( Rx >= ITHETA_COUNT) Rx = Rx-ITHETA_COUNT;
 if( Lx < 0) Lx = Lx+ITHETA_COUNT;


 int Uy = in_iCy+in_iYDistance, Dy = in_iCy-in_iYDistance;
 if( Uy >= IPHI_COUNT) Uy = Uy-IPHI_COUNT;
 if( Dy < 0) Dy = Dy+IPHI_COUNT;
 
 bool bIsClockwise;
 if( in_iCy <= IPHI_COUNT/2)
  bIsClockwise = true;
 else
  bIsClockwise = false;


 //up_right
 D3DXVECTOR3 p0(m_fCirclePoint[Cx][Cy][0],m_fCirclePoint[Cx][Cy][1],m_fCirclePoint[Cx][Cy][2]);
 D3DXVECTOR3 p1(m_fCirclePoint[Cx][Uy][0],m_fCirclePoint[Cx][Uy][1],m_fCirclePoint[Cx][Uy][2]);
 D3DXVECTOR3 p2(m_fCirclePoint[Rx][Cy][0],m_fCirclePoint[Rx][Cy][1],m_fCirclePoint[Rx][Cy][2]);
 pNormal = ComputeCenterNormal_Sum(m_fCirclePoint,Cx,Cy,bIsClockwise,ITHETA_COUNT,IPHI_COUNT,in_iXDistance,in_iYDistance);
 v[in_ID++] = SphereVertex(p0.x,p0.y,p0.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Cx][Cy][3]), GetPointColor(m_fCirclePoint[Cx][Cy][3])); //0.3
 pNormal = ComputeCenterNormal_Sum(m_fCirclePoint,Cx,Uy,bIsClockwise,ITHETA_COUNT,IPHI_COUNT,in_iXDistance,in_iYDistance);
 v[in_ID++] = SphereVertex(p1.x,p1.y,p1.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Cx][Uy][3]), GetPointColor(m_fCirclePoint[Cx][Uy][3]));//0.8
 pNormal = ComputeCenterNormal_Sum(m_fCirclePoint,Rx,Cy,bIsClockwise,ITHETA_COUNT,IPHI_COUNT,in_iXDistance,in_iYDistance);
 v[in_ID++] = SphereVertex(p2.x,p2.y,p2.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Rx][Cy][3]), GetPointColor(m_fCirclePoint[Rx][Cy][3]));//1

 //down_right
 D3DXVECTOR3 p3(m_fCirclePoint[Cx][Cy][0],m_fCirclePoint[Cx][Cy][1],m_fCirclePoint[Cx][Cy][2]);
 D3DXVECTOR3 p4(m_fCirclePoint[Rx][Cy][0],m_fCirclePoint[Rx][Cy][1],m_fCirclePoint[Rx][Cy][2]);
 D3DXVECTOR3 p5(m_fCirclePoint[Cx][Dy][0],m_fCirclePoint[Cx][Dy][1],m_fCirclePoint[Cx][Dy][2]);
 pNormal = ComputeCenterNormal_Sum(m_fCirclePoint,Cx,Cy,bIsClockwise,ITHETA_COUNT,IPHI_COUNT,in_iXDistance,in_iYDistance);
 v[in_ID++] = SphereVertex(p3.x,p3.y,p3.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Cx][Cy][3]), GetPointColor(m_fCirclePoint[Cx][Cy][3]));
 pNormal = ComputeCenterNormal_Sum(m_fCirclePoint,Rx,Cy,bIsClockwise,ITHETA_COUNT,IPHI_COUNT,in_iXDistance,in_iYDistance);
 v[in_ID++] = SphereVertex(p4.x,p4.y,p4.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Rx][Cy][3]), GetPointColor(m_fCirclePoint[Rx][Cy][3]));
 pNormal = ComputeCenterNormal_Sum(m_fCirclePoint,Cx,Dy,bIsClockwise,ITHETA_COUNT,IPHI_COUNT,in_iXDistance,in_iYDistance);
 v[in_ID++] = SphereVertex(p5.x,p5.y,p5.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Cx][Dy][3]), GetPointColor(m_fCirclePoint[Cx][Dy][3]));

 //down_left
 D3DXVECTOR3 p6(m_fCirclePoint[Cx][Cy][0],m_fCirclePoint[Cx][Cy][1],m_fCirclePoint[Cx][Cy][2]);
 D3DXVECTOR3 p7(m_fCirclePoint[Cx][Dy][0],m_fCirclePoint[Cx][Dy][1],m_fCirclePoint[Cx][Dy][2]);
 D3DXVECTOR3 p8(m_fCirclePoint[Lx][Cy][0],m_fCirclePoint[Lx][Cy][1],m_fCirclePoint[Lx][Cy][2]);
 pNormal = ComputeCenterNormal_Sum(m_fCirclePoint,Cx,Cy,bIsClockwise,ITHETA_COUNT,IPHI_COUNT,in_iXDistance,in_iYDistance);
 v[in_ID++] = SphereVertex(p6.x,p6.y,p6.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Cx][Cy][3]), GetPointColor(m_fCirclePoint[Cx][Cy][3]));
 pNormal = ComputeCenterNormal_Sum(m_fCirclePoint,Cx,Dy,bIsClockwise,ITHETA_COUNT,IPHI_COUNT,in_iXDistance,in_iYDistance);
 v[in_ID++] = SphereVertex(p7.x,p7.y,p7.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Cx][Dy][3]), GetPointColor(m_fCirclePoint[Cx][Dy][3]));
 pNormal = ComputeCenterNormal_Sum(m_fCirclePoint,Lx,Cy,bIsClockwise,ITHETA_COUNT,IPHI_COUNT,in_iXDistance,in_iYDistance);
 v[in_ID++] = SphereVertex(p8.x,p8.y,p8.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Lx][Cy][3]), GetPointColor(m_fCirclePoint[Lx][Cy][3]));

 //up_left
 D3DXVECTOR3 p9(m_fCirclePoint[Cx][Cy][0],m_fCirclePoint[Cx][Cy][1],m_fCirclePoint[Cx][Cy][2]);
 D3DXVECTOR3 p10(m_fCirclePoint[Lx][Cy][0],m_fCirclePoint[Lx][Cy][1],m_fCirclePoint[Lx][Cy][2]);
 D3DXVECTOR3 p11(m_fCirclePoint[Cx][Uy][0],m_fCirclePoint[Cx][Uy][1],m_fCirclePoint[Cx][Uy][2]);
 pNormal = ComputeCenterNormal_Sum(m_fCirclePoint,Cx,Cy,bIsClockwise,ITHETA_COUNT,IPHI_COUNT,in_iXDistance,in_iYDistance);
 v[in_ID++] = SphereVertex(p9.x,p9.y,p9.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Cx][Cy][3]), GetPointColor(m_fCirclePoint[Cx][Cy][3]));
 pNormal = ComputeCenterNormal_Sum(m_fCirclePoint,Lx,Cy,bIsClockwise,ITHETA_COUNT,IPHI_COUNT,in_iXDistance,in_iYDistance);
 v[in_ID++] = SphereVertex(p10.x,p10.y,p10.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Lx][Cy][3]), GetPointColor(m_fCirclePoint[Lx][Cy][3]));
 pNormal = ComputeCenterNormal_Sum(m_fCirclePoint,Cx,Uy,bIsClockwise,ITHETA_COUNT,IPHI_COUNT,in_iXDistance,in_iYDistance);
 v[in_ID++] = SphereVertex(p11.x,p11.y,p11.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Cx][Uy][3]), GetPointColor(m_fCirclePoint[Cx][Uy][3]));
}

//修正面(使首尾相连)
void SphereEx::ReviseTriangle3(SphereVertex* v, int& in_ID, int in_iCx, int in_iCy, int in_iXDistance, int in_iYDistance)
{
 //D3DXVECTOR3 pNormal;
 //int Cx = in_iCx, Cy = in_iCy;

 //int Rx = in_iCx+in_iXDistance, Lx = in_iCx-in_iXDistance;
 //if( Rx >= ITHETA_COUNT) Rx = Rx-ITHETA_COUNT;
 //if( Lx < 0) Lx = Lx+ITHETA_COUNT;


 //int Uy = in_iCy+in_iYDistance, Dy = in_iCy-in_iYDistance;
 //if( Uy >= IPHI_COUNT) Uy = Uy-IPHI_COUNT;
 //if( Dy < 0) Dy = Dy+IPHI_COUNT;
 //
 //bool bIsClockwise;
 //if( in_iCy <= IPHI_COUNT/2)
 // bIsClockwise = true;
 //else
 // bIsClockwise = false;


 up_right
 //D3DXVECTOR3 p0(m_fCirclePoint[Cx][Cy][0],m_fCirclePoint[Cx][Cy][1],m_fCirclePoint[Cx][Cy][2]);
 //D3DXVECTOR3 p1(m_fCirclePoint[Cx][Uy][0],m_fCirclePoint[Cx][Uy][1],m_fCirclePoint[Cx][Uy][2]);
 //D3DXVECTOR3 p2(m_fCirclePoint[Rx][Cy][0],m_fCirclePoint[Rx][Cy][1],m_fCirclePoint[Rx][Cy][2]);
 //pNormal = ComputeCenterNormal_Sum(m_fCirclePoint,Cx,Cy,bIsClockwise,ITHETA_COUNT,IPHI_COUNT,in_iXDistance,in_iYDistance);
 //v[in_ID++] = SphereVertex(p0.x,p0.y,p0.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Cx][Cy][3]), GetPointColor(m_fCirclePoint[Cx][Cy][3])); //0.3
 //pNormal = ComputeCenterNormal_Sum(m_fCirclePoint,Cx,Uy,bIsClockwise,ITHETA_COUNT,IPHI_COUNT,in_iXDistance,in_iYDistance);
 //v[in_ID++] = SphereVertex(p1.x,p1.y,p1.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Cx][Uy][3]), GetPointColor(m_fCirclePoint[Cx][Uy][3]));//0.8
 //pNormal = ComputeCenterNormal_Sum(m_fCirclePoint,Rx,Cy,bIsClockwise,ITHETA_COUNT,IPHI_COUNT,in_iXDistance,in_iYDistance);
 //v[in_ID++] = SphereVertex(p2.x,p2.y,p2.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Rx][Cy][3]), GetPointColor(m_fCirclePoint[Rx][Cy][3]));//1

 down_right
 //D3DXVECTOR3 p3(m_fCirclePoint[Cx][Cy][0],m_fCirclePoint[Cx][Cy][1],m_fCirclePoint[Cx][Cy][2]);
 //D3DXVECTOR3 p4(m_fCirclePoint[Rx][Cy][0],m_fCirclePoint[Rx][Cy][1],m_fCirclePoint[Rx][Cy][2]);
 //D3DXVECTOR3 p5(m_fCirclePoint[Cx][Dy][0],m_fCirclePoint[Cx][Dy][1],m_fCirclePoint[Cx][Dy][2]);
 //pNormal = ComputeCenterNormal_Sum(m_fCirclePoint,Cx,Cy,bIsClockwise,ITHETA_COUNT,IPHI_COUNT,in_iXDistance,in_iYDistance);
 //v[in_ID++] = SphereVertex(p3.x,p3.y,p3.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Cx][Cy][3]), GetPointColor(m_fCirclePoint[Cx][Cy][3]));
 //pNormal = ComputeCenterNormal_Sum(m_fCirclePoint,Rx,Cy,bIsClockwise,ITHETA_COUNT,IPHI_COUNT,in_iXDistance,in_iYDistance);
 //v[in_ID++] = SphereVertex(p4.x,p4.y,p4.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Rx][Cy][3]), GetPointColor(m_fCirclePoint[Rx][Cy][3]));
 //pNormal = ComputeCenterNormal_Sum(m_fCirclePoint,Cx,Dy,bIsClockwise,ITHETA_COUNT,IPHI_COUNT,in_iXDistance,in_iYDistance);
 //v[in_ID++] = SphereVertex(p5.x,p5.y,p5.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Cx][Dy][3]), GetPointColor(m_fCirclePoint[Cx][Dy][3]));

 down_left
 //D3DXVECTOR3 p6(m_fCirclePoint[Cx][Cy][0],m_fCirclePoint[Cx][Cy][1],m_fCirclePoint[Cx][Cy][2]);
 //D3DXVECTOR3 p7(m_fCirclePoint[Cx][Dy][0],m_fCirclePoint[Cx][Dy][1],m_fCirclePoint[Cx][Dy][2]);
 //D3DXVECTOR3 p8(m_fCirclePoint[Lx][Cy][0],m_fCirclePoint[Lx][Cy][1],m_fCirclePoint[Lx][Cy][2]);
 //pNormal = ComputeCenterNormal_Sum(m_fCirclePoint,Cx,Cy,bIsClockwise,ITHETA_COUNT,IPHI_COUNT,in_iXDistance,in_iYDistance);
 //v[in_ID++] = SphereVertex(p6.x,p6.y,p6.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Cx][Cy][3]), GetPointColor(m_fCirclePoint[Cx][Cy][3]));
 //pNormal = ComputeCenterNormal_Sum(m_fCirclePoint,Cx,Dy,bIsClockwise,ITHETA_COUNT,IPHI_COUNT,in_iXDistance,in_iYDistance);
 //v[in_ID++] = SphereVertex(p7.x,p7.y,p7.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Cx][Dy][3]), GetPointColor(m_fCirclePoint[Cx][Dy][3]));
 //pNormal = ComputeCenterNormal_Sum(m_fCirclePoint,Lx,Cy,bIsClockwise,ITHETA_COUNT,IPHI_COUNT,in_iXDistance,in_iYDistance);
 //v[in_ID++] = SphereVertex(p8.x,p8.y,p8.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Lx][Cy][3]), GetPointColor(m_fCirclePoint[Lx][Cy][3]));

 up_left
 //D3DXVECTOR3 p9(m_fCirclePoint[Cx][Cy][0],m_fCirclePoint[Cx][Cy][1],m_fCirclePoint[Cx][Cy][2]);
 //D3DXVECTOR3 p10(m_fCirclePoint[Lx][Cy][0],m_fCirclePoint[Lx][Cy][1],m_fCirclePoint[Lx][Cy][2]);
 //D3DXVECTOR3 p11(m_fCirclePoint[Cx][Uy][0],m_fCirclePoint[Cx][Uy][1],m_fCirclePoint[Cx][Uy][2]);
 //pNormal = ComputeCenterNormal_Sum(m_fCirclePoint,Cx,Cy,bIsClockwise,ITHETA_COUNT,IPHI_COUNT,in_iXDistance,in_iYDistance);
 //v[in_ID++] = SphereVertex(p9.x,p9.y,p9.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Cx][Cy][3]), GetPointColor(m_fCirclePoint[Cx][Cy][3]));
 //pNormal = ComputeCenterNormal_Sum(m_fCirclePoint,Lx,Cy,bIsClockwise,ITHETA_COUNT,IPHI_COUNT,in_iXDistance,in_iYDistance);
 //v[in_ID++] = SphereVertex(p10.x,p10.y,p10.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Lx][Cy][3]), GetPointColor(m_fCirclePoint[Lx][Cy][3]));
 //pNormal = ComputeCenterNormal_Sum(m_fCirclePoint,Cx,Uy,bIsClockwise,ITHETA_COUNT,IPHI_COUNT,in_iXDistance,in_iYDistance);
 //v[in_ID++] = SphereVertex(p11.x,p11.y,p11.z, pNormal.x, pNormal.y, pNormal.z, GetPointColor(m_fCirclePoint[Cx][Uy][3]), GetPointColor(m_fCirclePoint[Cx][Uy][3]));
}

//三次样条曲线化Theta
void SphereEx::CubicSplineEx_Theta(const int in_iTS, const int in_iTE, const int in_iTStep,
           const int in_iPS, const int in_iPE, const int in_iPStep,
           const int in_iCubicSplineExStep)
{
 const int TPOINT_COUNT = (in_iTE-in_iTS)/DISTANCE_UNIT+1;
 float* TPOINT_X = new float[TPOINT_COUNT];
 float* TPOINT_Zx = new float[TPOINT_COUNT];
 for(int iP = in_iPS; iP <= in_iPE; iP += DISTANCE_UNIT)
 {
  for(int iT = in_iTS; iT <= in_iTE; iT += DISTANCE_UNIT)
  {
   TPOINT_X[(iT-in_iTS)/DISTANCE_UNIT] = iT;
   TPOINT_Zx[(iT-in_iTS)/DISTANCE_UNIT] = m_fCirclePoint[iT/DISTANCE_UNIT][iP/DISTANCE_UNIT][3];
  }
  CubicSplineEx(TPOINT_Zx,TPOINT_X,TPOINT_COUNT,in_iCubicSplineExStep);
  for(int iT = in_iTS; iT <= in_iTE; iT += DISTANCE_UNIT)
  {
   SetValue(iT, iP, TPOINT_Zx[(iT-in_iTS)/DISTANCE_UNIT]);
  }
 }
 if( NULL != TPOINT_X)
  delete TPOINT_X;
 if( NULL != TPOINT_Zx)
  delete TPOINT_Zx;
 TPOINT_X = NULL;
 TPOINT_Zx = NULL;
}

//三次样条曲线化Phi
void SphereEx::CubicSplineEx_Phi(const int in_iTS, const int in_iTE, const int in_iTStep,
  const int in_iPS, const int in_iPE, const int in_iPStep,
  const int in_iCubicSplineExStep)
{
 const int PPOINT_COUNT = (in_iPE-in_iPS)/DISTANCE_UNIT+1;
 float* PPOINT_X = new float[PPOINT_COUNT];
 float* PPOINT_Zx = new float[PPOINT_COUNT];

 for(int iT = in_iTS; iT <= in_iTE; iT += DISTANCE_UNIT)
 {
  for(int iP = in_iPS; iP <= in_iPE; iP += DISTANCE_UNIT)
  {
   PPOINT_X[(iP-in_iPS)/DISTANCE_UNIT] = iP;
   PPOINT_Zx[(iP-in_iPS)/DISTANCE_UNIT] = m_fCirclePoint[iT/DISTANCE_UNIT][iP/DISTANCE_UNIT][3];
  }
  CubicSplineEx(PPOINT_Zx,PPOINT_X,PPOINT_COUNT,in_iCubicSplineExStep);
  for(int iP = in_iPS; iP <= in_iPE; iP += DISTANCE_UNIT)
  {
   SetValue(iT, iP, PPOINT_Zx[(iP-in_iPS)/DISTANCE_UNIT]);
  }
 }

 if( NULL != PPOINT_X)
  delete PPOINT_X;
 if( NULL != PPOINT_Zx)
  delete PPOINT_Zx;
 PPOINT_X = NULL;
 PPOINT_Zx = NULL;
}


void SphereEx::InitCircle()
{
 for(int i=0; i<ITHETA_COUNT; i++)
 {
  for(int j=0; j<IPHI_COUNT; j++)
  {
   for(int k=0; k<XYZR; k++)
   {
    m_fCirclePoint[i][j][k] = 0;
   }
  }
 }
}

//上色方案
float SphereEx::GetPointColor(float in_fValue)
{
 int R,G,B;
 float fPly = (float)in_fValue/m_fRMAX;
 if( fPly > 1) fPly = 1;
 if( fPly < 0) fPly = 0;
 //R
 if( fPly > 0.75) R = 255;
 else if( fPly < 0.5) R = 0;
 else R = (fPly-0.5)/0.25*255;

 //G
 if( fPly > 0.75) G = 255-(fPly-0.75)/0.25*255;
 else if( fPly < 0.25) G = fPly/0.25*255;
 else G = 255;

 //B
 if( fPly > 0.5) B = 0;
 else if( fPly < 0.25) B = 255;
 else B = 255-(fPly-0.25)/0.25*255;

 return D3DCOLOR_ARGB(255,R,G,B);
}

//建立模型
bool SphereEx::Setup(IDirect3DDevice9* pDevice,
      const int in_iTS, const int in_iTE, const int in_iTStep,
      const int in_iPS, const int in_iPE, const int in_iPStep)
{
 CleanUp();
 Revise(in_iTS, in_iTE, in_iTStep, in_iPS, in_iPE, in_iPStep);
 CubicSpline_Circle(in_iTS, in_iTE, in_iTStep, in_iPS, in_iPE, in_iPStep);
 int iC = ((in_iTE-in_iTS)/DISTANCE_UNIT+1)*((in_iPE-in_iPS)/DISTANCE_UNIT+1)*12;
 pDevice->CreateVertexBuffer(
  iC * sizeof(SphereVertex),
  D3DUSAGE_WRITEONLY,
  SphereVertex::FVF,
  D3DPOOL_MANAGED,
  &m_pVB,
  0);
 SphereVertex* v;
 m_pVB->Lock(0, 0, (void**)&v, 0);
 int iID = 0;
 m_iTriangleCount = 0;
 for(int iT=in_iTS; iT<=in_iTE; iT+=DISTANCE_UNIT)
 {
  for(int iP=in_iPS; iP<=in_iPE; iP+=DISTANCE_UNIT)
   AddTriangle3(v,iID,iT/DISTANCE_UNIT,iP/DISTANCE_UNIT,1, 1);
 }
 m_iTriangleCount = iID/3;
 m_pVB->Unlock();
 v = NULL;


 SetupDirectLight(pDevice,LIGHT_DIRECT_ID,m_DirLight);
 SetLightDir(m_DirLight,m_fDirLightPos[0],m_fDirLightPos[1], m_fDirLightPos[2]);
 
 return true;
}

//清空模型
void SphereEx::CleanUp()
{
 D3D::Release<IDirect3DVertexBuffer9*>(m_pVB);
}

//设置状态
void SphereEx::SetState(IDirect3DDevice9* pDevice)
{
 pDevice->LightEnable(LIGHT_DIRECT_ID, true);
 pDevice->SetRenderState(D3DRS_LIGHTING, m_bOpenLight);
 pDevice->SetRenderState(D3DRS_SHADEMODE,D3DSHADE_GOURAUD);
 pDevice->SetRenderState(D3DRS_NORMALIZENORMALS, true);
 pDevice->SetRenderState(D3DRS_SPECULARENABLE, true);
 pDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE);
}

//渲染
void SphereEx::Rander(IDirect3DDevice9* pDevice)
{
 Transform_WORLD(pDevice);
 pDevice->SetStreamSource(0, m_pVB, 0, sizeof(SphereVertex));
 pDevice->SetFVF(SphereVertex::FVF);
 D3DMATERIAL9 mtrl;
 mtrl.Ambient = D3D::BLUE;
 mtrl.Diffuse  = D3D::WHITE;
 mtrl.Specular = D3D::WHITE;
 mtrl.Emissive = D3D::BLACK;
 mtrl.Power    = 120.0f;
 pDevice->SetMaterial(&mtrl);
 pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, m_iTriangleCount);
}

void SphereEx::InitCircleRand(const int in_iTS, const int in_iTE, const int in_iTStep,
    const int in_iPS, const int in_iPE, const int in_iPStep)
{
 InitCircle();
 float x,y,z;
 for(int iT = in_iTS; iT <= in_iTE; iT += in_iTStep)
 {
  for(int iP = in_iPS; iP <= in_iPE; iP += in_iPStep)
  {
   int R = m_fRMAX;
   if( iP < 30  ||  iP> 330 || (iP > 150  &&  iP < 210))
    R -= 15+rand()%15;
   else
   {
    R -= rand()%5;
    //R = rand()%30;
   }
   //R = 45+rand()%5;
   SetValue(iT,iP,R);
  }
 }
}

void SphereEx::CubicSpline_Circle(const int in_iTS, const int in_iTE, const int in_iTStep,
      const int in_iPS, const int in_iPE, const int in_iPStep)
{
 const int iTStep = in_iTStep/DISTANCE_UNIT;
 CubicSplineEx_Theta(in_iTS, in_iTE, in_iTStep, in_iPS, in_iPE, in_iPStep, iTStep);
 const int iPStep = in_iPStep/DISTANCE_UNIT;
 CubicSplineEx_Phi(in_iTS, in_iTE, in_iTStep, in_iPS, in_iPE, in_iPStep, iPStep);
}

void SphereEx::SetValue(const int in_iTA, const int in_iPA, const float in_fValue)
{
 float x,y,z;
 float fValue = in_fValue;
 if( fValue < 0)
  fValue *= -1;
 CumputerPosByTurnXY(x,y,z,0,fValue,0,in_iPA,in_iTA);
 m_fCirclePoint[in_iTA/DISTANCE_UNIT][in_iPA/DISTANCE_UNIT][0] = x;
 m_fCirclePoint[in_iTA/DISTANCE_UNIT][in_iPA/DISTANCE_UNIT][1] = y;
 m_fCirclePoint[in_iTA/DISTANCE_UNIT][in_iPA/DISTANCE_UNIT][2] = z;
 m_fCirclePoint[in_iTA/DISTANCE_UNIT][in_iPA/DISTANCE_UNIT][3] = fValue;
}

//修正(使首尾相连)
bool SphereEx::Revise(const int in_iTS, const int in_iTE, const int in_iTStep,
       const int in_iPS, const int in_iPE, const int in_iPStep)
{
 bool bIsRevise = false;
 float fValue = 0;
 if( 0 == in_iPS && 360 == in_iPE)
 {
  const int FirstPA = 0;
  const int EndPA = 360;
  for(int iT = in_iTS; iT <= in_iTE; iT += in_iTStep)
  {
   fValue = m_fCirclePoint[iT/DISTANCE_UNIT][FirstPA/DISTANCE_UNIT][3];
   SetValue(iT,EndPA,fValue);
  }
  bIsRevise = true;
 }

 if( 0 == in_iTS && 180 == in_iTE)
 {
  const int FirstTA = 0;
  const int EndTA = 180;
  float fValue = 0;
  for(int iP = in_iPS; iP <= in_iPE; iP += in_iPStep)
  {
   fValue = m_fCirclePoint[FirstTA/DISTANCE_UNIT][iP/DISTANCE_UNIT][3];
   SetValue(EndTA,360-iP,fValue);
  }
  bIsRevise = true;
 }
 return bIsRevise;
}

 

/****************************************
*文件名:  3D_Math.h
*文件描述:  建立3D开发里常用到的函数库
*创建人:  陈泽丹
*创建时间:  2010-04-03
*版本:   1.0
*****************************************/

#include <d3dx9.h>


const int Center_UpRight = 0;
const int Center_DownRight = 1;
const int Center_DownLeft = 2;
const int Center_UpLef = 3;


/* 三次样条曲线
out_fY   所求函数值
out_fDy  所求插值点的一阶导数
out_fDdy 所求插值点的二阶导数
in_fX    所求插值点的插值点的X轴坐标(升序排列)
in_fKnowX,in_fKnowY  已知点的节点坐标(升序排列)
in_fKnowDy,  in_fKnowDdy 已知点的节点的一阶导和二阶导(升序排列)
in_iN 已知节点个数
*/
void CubicSpline(float out_fY[], float out_fDy[], float out_fDdy[],
     float in_fX[], int in_M,
     float in_fKnowX[], float in_fKnowY[],
     float in_fKnowDy[], float in_fKnowDdy[],
     int in_iN);
//以估计的方法计算导数
void CalculateDyDdy(float out_fDy[], float out_fDdy[], 
     float in_fPx[], float in_fPy[], int in_iN,
     float in_fBdy = 0, float in_fEdy = 0,
     float in_fBDdy = 0, float in_fEDdy = 0);
//三次样条曲线
void CubicSplineEx(float out_fY[], float in_fX[], int in_M,
       float in_fKnowX[], float in_fKnowY[],int in_iN);
//三次样条曲线
void CubicSplineEx(float inout_fY[], const float in_fX[], const int in_M, const int in_KNOWSTEP);

/*
求in_fX,in_fY,in_fZ,绕Y轴转in_iA_XTAngle度[0,360],
绕X轴转in_iA_XTAngle度[0,360]的位置out_fX, out_fY, out_fZ
TurnXangle = A_Theta; TurnYangle = B_Phi;
cosB  0   -sinB  0
sinAsinB consA  sinAcosB 0
cosAsinB -sinA  cosAcosB 0
0   0   0   1
*/
void CumputerPosByTurnXY(float& out_fX, float& out_fY, float& out_fZ,
       const float in_fX, const float in_fY, const float in_fZ,
       const int& in_iA_XTAngle, const int& in_iB_YTAngle);

/*
求p0,p1,p2三点组成的面法线
*/
D3DXVECTOR3 ComputeNormal(const D3DXVECTOR3* p0, const D3DXVECTOR3* p1, const D3DXVECTOR3* p2);


/*
画矩型
*/
void CreateRectangle(D3DXVECTOR3 vTrianglePoint[], int& N,
      const float UpLeftX, const float UpLeftY, const float UpLeftZ,
      const float UpRightX, const float UpRightY, const float UpRightZ,
      const float DownLeftX, const float DownLeftY, const float DownLeftZ,
      const float DownRightX, const float DownRightY, const float DownRightZ);


/*
计算以in_iCx,in_iCy为中心点,被四个三角形环绕共享时
顺时针方向每个三角形三个点的ID
*/
void ComputeCenterTriangle(int out_iIDX[], int out_iIDY[], int& N,
       const int TYPE, const int CenterX, const int CenterY,
       const int XPOINT_COUNT, const int YPOINT_COUNT,
       const int W = 1, const int H = 1);

/*
计算以in_iCx,in_iCy为中心点,被四个三角形环绕共享时,
每个三角形中in_iCx,in_iCy的法线
*/
D3DXVECTOR3 ComputeCenterNormal(const float in_fPoint[][73][4],
        const int TYPE,
        const bool in_bIsClockwise,
        const int CenterX, const int CenterY,
        const int XPOINT_COUNT, const int YPOINT_COUNT,
        const int W = 1, const int H = 1);

/*
计算以in_iCx,in_iCy为中心点,被四个三角形环绕共享时,
中心点in_iCx,in_iCy的法线
*/
D3DXVECTOR3 ComputeCenterNormal_Sum(const float in_fPoint[][73][4],
         const int in_iCx, const int in_iCy,
         const bool in_bIsClockwise,
         const int XPOINT_COUNT, const int YPOINT_COUNT,
         const int W, const int H);

 

/****************************************
*文件名:  3D_Math.cpp
*创建人:  陈泽丹
*创建时间:  2010-04-03
*版本:   1.0
*****************************************/


#include "3D_Math.h"
#include <math.h>


#define NULL 0


/*三次样条函数
out_fY   所求函数值
out_fDy  所求插值点的一阶导数
out_fDdy 所求插值点的二阶导数
in_fX    所求插值点的插值点的X轴坐标(升序排列)
in_fKnowX,in_fKnowY  已知点的节点坐标(升序排列)
in_fKnowDy,  in_fKnowDdy 已知点的节点的一阶导和二阶导(升序排列)
in_iN 已知节点个数
*/
void CubicSpline(float out_fY[], float out_fDy[], float out_fDdy[],
     float in_fX[], int in_M,
     float in_fKnowX[], float in_fKnowY[],
     float in_fKnowDy[], float in_fKnowDdy[],
     int in_iN)  
{
 //三次样条函数
 int   i,j;  
 float   h0,h1,alpha,beta,g;
 int SCOUN = (in_M<400)? 400:(in_M/3);
 float* s = new float[in_M];

 in_fKnowDy[0]=-0.5;  
 h0=in_fKnowX[1]-in_fKnowX[0];  
 s[0]=3.0*(in_fKnowY[1]-in_fKnowY[0])/(2.0*h0)-in_fKnowDdy[0]*h0/4.0;  
 for(j=1;j<=in_iN-2;j++)  
 {
   h1=in_fKnowX[j+1]-in_fKnowX[j];  
   alpha=h0/(h0+h1);  
   beta=(1.0-alpha)*(in_fKnowY[j]-in_fKnowY[j-1])/h0;  
   beta=3.0*(beta+alpha*(in_fKnowY[j+1]-in_fKnowY[j])/h1);
   in_fKnowDy[j]=-alpha/(2.0+(1.0-alpha)*in_fKnowDy[j-1]);  
   s[j]=(beta-(1.0-alpha)*s[j-1]);  
   s[j]=s[j]/(2.0+(1.0-alpha)*in_fKnowDy[j-1]);  
   h0=h1;  
 }

 in_fKnowDy[in_iN-1]=(3.0*(in_fKnowY[in_iN-1]-in_fKnowY[in_iN-2])/h1+in_fKnowDdy[in_iN-1]*h1/2.0-s[in_iN-2])/(2.0+in_fKnowDy[in_iN-2]);  
 for(j=in_iN-2;j>=0;j--)
   in_fKnowDy[j]=in_fKnowDy[j]*in_fKnowDy[j+1]+s[j];  
 for(j=0;j<=in_iN-2;j++)  
   s[j]=in_fKnowX[j+1]-in_fKnowX[j];  
 for(j=0;j<=in_iN-2;j++)
 {
   h1=s[j]*s[j];
   in_fKnowDdy[j]=6.0*(in_fKnowY[j+1]-in_fKnowY[j])/h1-2.0*(2.0*in_fKnowDy[j]+in_fKnowDy[j+1])/s[j];
 }  
 h1=s[in_iN-2]*s[in_iN-2];  
 in_fKnowDdy[in_iN-1]=6.*(in_fKnowY[in_iN-2]-in_fKnowY[in_iN-1])/h1+2.*(2.*in_fKnowDy[in_iN-1]+in_fKnowDy[in_iN-2])/s[in_iN-2];  
 g=0.0;  
 for(i=0;i<=in_iN-2;i++)
 {
   h1=0.5*s[i]*(in_fKnowY[i]+in_fKnowY[i+1]);
   h1=h1-s[i]*s[i]*s[i]*(in_fKnowDdy[i]+in_fKnowDdy[i+1])/24.0;
   g=g+h1;
 }  

 for(j=0;j<=in_M-1;j++)
 {
   if(in_fX[j]>=in_fKnowX[in_iN-1])  
    i=in_iN-2;
   else
   {
    i=0;
    while(in_fX[j]>in_fKnowX[i+1])  
     i=i+1;
   }  
   h1=(in_fKnowX[i+1]-in_fX[j])/s[i];  
   h0=h1*h1;  
   out_fY[j]=(3.0*h0-2.0*h0*h1)*in_fKnowY[i];  
   out_fY[j]=out_fY[j]+s[i]*(h0-h0*h1)*in_fKnowDy[i];  
   out_fDy[j]=6.0*(h0-h1)*in_fKnowY[i]/s[i];  
   out_fDy[j]=out_fDy[j]+(3.0*h0-2.0*h1)*in_fKnowDy[i];  
   out_fDdy[j]=(6.0-12.0*h1)*in_fKnowY[i]/(s[i]*s[i]);  
   out_fDdy[j]=out_fDdy[j]+(2.0-6.0*h1)*in_fKnowDy[i]/s[i];  
   h1=(in_fX[j]-in_fKnowX[i])/s[i];  
   h0=h1*h1;  
   out_fY[j]=out_fY[j]+(3.0*h0-2.0*h0*h1)*in_fKnowY[i+1];  
   out_fY[j]=out_fY[j]-s[i]*(h0-h0*h1)*in_fKnowDy[i+1];  
   out_fDy[j]=out_fDy[j]-6.0*(h0-h1)*in_fKnowY[i+1]/s[i];  
   out_fDy[j]=out_fDy[j]+(3.0*h0-2.0*h1)*in_fKnowDy[i+1];  
   out_fDdy[j]=out_fDdy[j]+(6.0-12.0*h1)*in_fKnowY[i+1]/(s[i]*s[i]);  
   out_fDdy[j]=out_fDdy[j]-(2.0-6.0*h1)*in_fKnowDy[i+1]/s[i];
 }

 if( NULL != s)
  delete s;
 s = NULL;
}

//以估计的方法计算导数
void CalculateDyDdy(float out_fDy[], float out_fDdy[], 
     float in_fPx[], float in_fPy[], int in_iN,
     float in_fBdy, float in_fEdy,
     float in_fBDdy, float in_fEDdy)
{//以估计的方法计算导数
 out_fDy[0] = in_fBdy;
 out_fDdy[0] = in_fBDdy;
 out_fDy[in_iN-1] = in_fEdy;
 out_fDdy[in_iN-1] = in_fEDdy;
 for(int i=1; i<in_iN-1; i++)
 {
  float dx = in_fPx[i+1] - in_fPx[i];
  if( 0 != dx)
  {
   out_fDy[i] = (in_fPy[i+1] - in_fPy[i]) / (2*dx);
   out_fDdy[i] = (in_fPy[i+1] + in_fPy[i-1] - 2*in_fPy[i]) / dx / dx;
  }
 }
}

//三次样条曲线
void CubicSplineEx(float out_fY[], float in_fX[], int in_M,
       float in_fKnowX[], float in_fKnowY[],int in_iN)
{
 float* fKnowDy = new float[in_iN];
 float* fKnowDdy = new float[in_iN];
 float* fInsertDy = new float[in_M];
 float* fInsertDdy = new float[in_M];

 CalculateDyDdy(fKnowDy, fKnowDdy, in_fKnowX, in_fKnowY, in_iN);
 CubicSpline(out_fY, fInsertDy, fInsertDdy, in_fX, in_M,
  in_fKnowX, in_fKnowY, fKnowDy, fKnowDdy, in_iN);

 if( NULL != fInsertDdy)
  delete fInsertDdy;
 fInsertDdy = NULL;
 if( NULL != fInsertDy)
  delete fInsertDy;
 fInsertDy = NULL;
 if( NULL != fKnowDdy)
  delete fKnowDdy;
 fKnowDdy = NULL;
 if( NULL != fKnowDy)
  delete fKnowDy;
 fKnowDy = NULL;
}

//三次样条曲线
void CubicSplineEx(float inout_fY[], const float in_fX[], const int in_M, const int in_KNOWSTEP)
{
 const int KNOW_COUNT = in_M/in_KNOWSTEP+1;
 if( KNOW_COUNT <= 2)
 {
  float fV = (inout_fY[0]+inout_fY[in_M-1])*0.5;
  for(int i=1; i<in_M-1; i++)
  {
   if( 0 == i%in_KNOWSTEP)
    continue;
   inout_fY[i] = fV;
  }
 }
 else if( KNOW_COUNT < in_M)
 {
  float* KnowX = new float[KNOW_COUNT];
  float* KnowY = new float[KNOW_COUNT];
  float* fFindX = new float[in_M-KNOW_COUNT+1];
  float* fFindY = new float[in_M-KNOW_COUNT+1];

  int iFindID = 0;
  for(int i=0; i<in_M; i++)
  {
   if( 0 == i%in_KNOWSTEP)
   {
    KnowX[i/in_KNOWSTEP] = in_fX[i];
    KnowY[i/in_KNOWSTEP] = inout_fY[i];
   }
   else
   {
    fFindX[iFindID++] = in_fX[i];
   }
  }
  CubicSplineEx(fFindY,fFindX,iFindID, KnowX,KnowY,KNOW_COUNT);
  iFindID = 0;
  for(int i=0; i<in_M; i++)
  {
   if( 0 == i%in_KNOWSTEP)
    continue;
   inout_fY[i] = fFindY[iFindID++];
  }

  if( NULL != fFindY)
   delete fFindY;
  if( NULL != fFindX)
   delete fFindX;
  if( NULL != KnowY)
   delete KnowY;
  if( NULL != KnowX)
   delete KnowX;
  fFindY = NULL;
  fFindX = NULL;
  KnowY = NULL;
  KnowX = NULL;
 }
}

/*
求in_fX,in_fY,in_fZ,绕Y轴转in_iA_XTAngle度[0,360],
绕X轴转in_iA_XTAngle度[0,360]的位置out_fX, out_fY, out_fZ
TurnXangle = A_Theta; TurnYangle = B_Phi;
cosB  0   -sinB  0
sinAsinB consA  sinAcosB 0
cosAsinB -sinA  cosAcosB 0
0   0   0   1
*/
void CumputerPosByTurnXY(float& out_fX, float& out_fY, float& out_fZ,
       const float in_fX, const float in_fY, const float in_fZ,
       const int& in_iA_XTAngle, const int& in_iB_YTAngle)
 {
 const float fA = (float)in_iA_XTAngle/180*3.14159;
 const float fB = (float)in_iB_YTAngle/180*3.14159;
 out_fX = in_fX*cos((float)fB)+in_fY*sin((float)fA)*sin((float)fB)+in_fZ*cos((float)fA)*sin((float)fB);
 out_fY = in_fY*cos((float)fA)-in_fZ*sin((float)fA);
 out_fZ = in_fX*(-1*sin((float)fB))+in_fY*sin((float)fA)*cos((float)fB)+in_fZ*cos((float)fA)*cos((float)fB);
}

/*
求p0,p1,p2三点组成的面法线
*/
D3DXVECTOR3 ComputeNormal(const D3DXVECTOR3* p0, const D3DXVECTOR3* p1, const D3DXVECTOR3* p2)
{
 D3DXVECTOR3 v0ut;
 D3DXVECTOR3 u = *p1-*p0;
 D3DXVECTOR3 v = *p2-*p0;
 D3DXVec3Cross(&v0ut,&u,&v);
 D3DXVec3Normalize(&v0ut,&v0ut);
 return v0ut;
}

/*
画矩型
*/
void CreateRectangle(D3DXVECTOR3 vTrianglePoint[], int& N,
      const float UpLeftX, const float UpLeftY, const float UpLeftZ,
      const float UpRightX, const float UpRightY, const float UpRightZ,
      const float DownLeftX, const float DownLeftY, const float DownLeftZ,
      const float DownRightX, const float DownRightY, const float DownRightZ)
{
 vTrianglePoint[0].x = UpLeftX;
 vTrianglePoint[0].y = UpLeftY;
 vTrianglePoint[0].z = UpLeftZ;

 vTrianglePoint[1].x = DownRightX;
 vTrianglePoint[1].y = DownRightY;
 vTrianglePoint[1].z = DownRightZ;

 vTrianglePoint[2].x = DownLeftX;
 vTrianglePoint[2].y = DownLeftY;
 vTrianglePoint[2].z = DownLeftZ;

 vTrianglePoint[3].x = UpLeftX;
 vTrianglePoint[3].y = UpLeftY;
 vTrianglePoint[3].z = UpLeftZ;

 vTrianglePoint[4].x = UpRightX;
 vTrianglePoint[4].y = UpRightY;
 vTrianglePoint[4].z = UpRightZ;

 vTrianglePoint[5].x = DownRightX;
 vTrianglePoint[5].y = DownRightY;
 vTrianglePoint[5].z = DownRightZ;

 N = 6;
}


/*
计算以in_iCx,in_iCy为中心点,被四个三角形环绕共享时
顺时针方向每个三角形三个点的ID
*/
void ComputeCenterTriangle(int out_iIDX[], int out_iIDY[], int& N,
       const int TYPE, const int CenterX, const int CenterY,
       const int XPOINT_COUNT, const int YPOINT_COUNT,
       const int W, const int H)
{
 D3DXVECTOR3 vNormal;
 D3DXVECTOR3 vNormalUpRight,vNormaldownRight,vNormalDownLeft,vNormalUpLeft;

 int Cx = CenterX, Cy = CenterY;
 int Rx = Cx+W;
 while( Rx >= XPOINT_COUNT)
  Rx = Rx-XPOINT_COUNT;
 int Lx = Cx-W;
 while( Lx < 0)
  Lx = Lx+XPOINT_COUNT;
 int Uy = Cy+H;
 while( Uy >= YPOINT_COUNT)
  Uy = Uy-YPOINT_COUNT;
 int Dy = Cy-H;
 while( Dy < 0)
  Dy = Dy+YPOINT_COUNT;

 if( Center_UpRight == TYPE)
 {//up_right
  out_iIDX[0] = Cx;
  out_iIDY[0] = Cy;
  out_iIDX[1] = Cx;
  out_iIDY[1] = Uy;
  out_iIDX[2] = Rx;
  out_iIDY[2] = Cy;
 }
 else if( Center_DownRight == TYPE)
 {//down_right
  out_iIDX[0] = Cx;
  out_iIDY[0] = Cy;
  out_iIDX[1] = Rx;
  out_iIDY[1] = Cy;
  out_iIDX[2] = Cx;
  out_iIDY[2] = Dy;
 }
 else if( Center_DownLeft == TYPE)
 {//down_left
  out_iIDX[0] = Cx;
  out_iIDY[0] = Cy;
  out_iIDX[1] = Cx;
  out_iIDY[1] = Dy;
  out_iIDX[2] = Lx;
  out_iIDY[2] = Cy;
 }
 else if( Center_UpLef == TYPE)
 {//up_left
  out_iIDX[0] = Cx;
  out_iIDY[0] = Cy;
  out_iIDX[1] = Lx;
  out_iIDY[1] = Cy;
  out_iIDX[2] = Cx;
  out_iIDY[2] = Uy;
 }

 N = 3;
}

/*
计算以in_iCx,in_iCy为中心点,被四个三角形环绕共享时,
每个三角形中in_iCx,in_iCy的法线
*/
D3DXVECTOR3 ComputeCenterNormal(const float in_fPoint[][73][4],
        const int TYPE,
        const bool in_bIsClockwise,
        const int CenterX, const int CenterY,
        const int XPOINT_COUNT, const int YPOINT_COUNT,
        const int W, const int H)
{
 D3DXVECTOR3 vNormal;
 D3DXVECTOR3 vNormalUpRight,vNormaldownRight,vNormalDownLeft,vNormalUpLeft;
 int IDX[3];
 int IDY[3];
 int ID_N = 3;

 ComputeCenterTriangle(IDX,IDY,ID_N, TYPE, CenterX,CenterY,XPOINT_COUNT,YPOINT_COUNT,W,H);
 D3DXVECTOR3 p0(in_fPoint[IDX[0]][IDY[0]][0],in_fPoint[IDX[0]][IDY[0]][1],in_fPoint[IDX[0]][IDY[0]][2]);
 D3DXVECTOR3 p1(in_fPoint[IDX[1]][IDY[1]][0],in_fPoint[IDX[1]][IDY[1]][1],in_fPoint[IDX[1]][IDY[1]][2]);
 D3DXVECTOR3 p2(in_fPoint[IDX[2]][IDY[2]][0],in_fPoint[IDX[2]][IDY[2]][1],in_fPoint[IDX[2]][IDY[2]][2]);
 if( in_bIsClockwise)
  vNormal = ComputeNormal(&p0,&p1,&p2);
 else
  vNormal = ComputeNormal(&p2,&p1,&p0);
 return vNormal;
}

/*
计算以in_iCx,in_iCy为中心点,被四个三角形环绕共享时,
中心点in_iCx,in_iCy的法线
*/
D3DXVECTOR3 ComputeCenterNormal_Sum(const float in_fPoint[][73][4],
         const int in_iCx, const int in_iCy,
         const bool in_bIsClockwise,
         const int XPOINT_COUNT, const int YPOINT_COUNT,
         const int W, const int H)
{
 D3DXVECTOR3 pNormal;
 D3DXVECTOR3 pNormalUpRight,pNormaldownRight,pNormalDownLeft,pNormalUpLeft;
 bool bIsClockwise = in_bIsClockwise;
 //up_right
 pNormalUpRight = ComputeCenterNormal(in_fPoint,
  Center_UpRight,
  bIsClockwise,
  in_iCx,in_iCy,
  XPOINT_COUNT,YPOINT_COUNT,
  W,H);

 //down_right
 pNormaldownRight = ComputeCenterNormal(in_fPoint,
  Center_DownRight,
  bIsClockwise,
  in_iCx,in_iCy,
  XPOINT_COUNT,YPOINT_COUNT,
  W,H);

 
 //down_left
 pNormalDownLeft = ComputeCenterNormal(in_fPoint,
  Center_DownLeft,
  bIsClockwise,
  in_iCx,in_iCy,
  XPOINT_COUNT,YPOINT_COUNT,
  W,H);

 //up_left
 pNormalUpLeft = ComputeCenterNormal(in_fPoint,
  Center_UpLef,
  bIsClockwise,
  in_iCx,in_iCy,
  XPOINT_COUNT,YPOINT_COUNT,
  W,H);

 pNormal = (pNormalUpRight+pNormaldownRight+pNormalDownLeft+pNormalUpLeft)*0.2;
 return pNormal;
}

 

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值