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;
}

 

内容概要:本文档是一份关于交换路由配置的学习笔记,系统地介绍了网络设备的远程管理、交换机与路由器的核心配置技术。内容涵盖Telnet、SSH、Console三种远程控制方式的配置方法;详细讲解了VLAN划分原理及Access、Trunk、Hybrid端口的工作机制,以及端口镜像、端口汇聚、端口隔离等交换技术;深入解析了STP、MSTP、RSTP生成树协议的作用与配置步骤;在路由部分,涵盖了IP地址配置、DHCP服务部署(接口池与全局池)、NAT转换(静态与动态)、静态路由、RIP与OSPF动态路由协议的配置,并介绍了策略路由和ACL访问控制列表的应用;最后简要说明了华为防火墙的安全区域划分与基本安全策略配置。; 适合人群:具备一定网络基础知识,从事网络工程、运维或相关技术岗位1-3年的技术人员,以及准备参加HCIA/CCNA等认证考试的学习者。; 使用场景及目标:①掌握企业网络中常见的交换与路由配置技能,提升实际操作能力;②理解VLAN、STP、OSPF、NAT、ACL等核心技术原理并能独立完成中小型网络搭建与调试;③通过命令示例熟悉华为设备CLI配置逻辑,为项目实施和故障排查提供参考。; 阅读建议:此笔记以实用配置为主,建议结合模拟器(如eNSP或Packet Tracer)动手实践每一条命令,对照拓扑理解数据流向,重点关注VLAN间通信、路由选择机制、安全策略控制等关键环节,并注意不同设备型号间的命令差异。
`so3_math.h` 通常是一个用于 **SO(3) 特殊正交群(三维旋转群)数学运算** 的头文件,常见于机器人学、SLAM 或飞行控制等领域。以下是详细解析: --- ### **1. 核心功能** SO(3) 表示三维空间中的旋转矩阵集合(满足 `R^T R = I` 且 `det(R) = 1`)。该头文件通常包含以下数学工具: - **旋转表示转换**:四元数 ↔ 旋转矩阵 ↔ 轴角 ↔ 欧拉角 - **李代数运算**:SO(3) 与 so(3) 李代数之间的指数/对数映射 - **扰动模型**:旋转的雅可比矩阵计算(用于优化问题) - **旋转插值**:如球面线性插值 (Slerp) --- ### **2. 典型内容示例** ```cpp // 旋转矩阵 -> 轴角 Eigen::Vector3d RotationToAxisAngle(const Eigen::Matrix3d &R); // 轴角 -> 旋转矩阵 Eigen::Matrix3d AxisAngleToRotation(const Eigen::Vector3d &axis_angle); // SO(3) 李群指数映射(so(3) -> SO(3)) Eigen::Matrix3d ExpSO3(const Eigen::Vector3d &omega); // SO(3) 对数映射(SO(3) -> so(3)) Eigen::Vector3d LogSO3(const Eigen::Matrix3d &R); // 旋转矩阵的右雅可比(用于高斯牛顿优化) Eigen::Matrix3d RightJacobianSO3(const Eigen::Vector3d &omega); ``` --- ### **3. 关键数学原理** | 运算 | 数学形式 | 用途 | |---------------------|----------------------------|-------------------------| | **指数映射** | `R = exp(ω^)` | 从角速度生成旋转矩阵 | | **对数映射** | `ω^ = log(R)` | 从旋转矩阵提取轴角 | | **右雅可比** | `J_r(ω) = (I - exp(ω^))ω^ / |ω|^2 + ωω^T/|ω|` | 优化中的扰动模型 | --- ### **4. 实际应用场景** - **IMU 预积分**:计算旋转增量时避免重复积分 - **位姿图优化**:构建旋转残差项 - **飞行控制**:无人机姿态控制器中的旋转误差计算 - **点云配准**:ICP 算法中的旋转估计 --- ### **5. 实现依赖库** 通常基于以下库实现: - **Eigen**:核心矩阵运算(推荐使用 `Eigen::Matrix3d` 表示旋转矩阵) - **Sophus**:李群/李代数库(提供现成的 SO(3) 实现) - **Ceres Solver**:若涉及优化问题 --- ### **6. 代码示例(使用 Sophus 库)** ```cpp #include <sophus/so3.hpp> // 从轴角创建 SO(3) 对象 Eigen::Vector3d axis_angle(0.1, 0.2, 0.3); Sophus::SO3d R = Sophus::SO3d::exp(axis_angle); // 计算旋转后的点 Eigen::Vector3d p = R * Eigen::Vector3d(1, 0, 0); // 获取李代数 Eigen::Vector3d log_R = R.log(); ``` ---
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值