CMath.cpp
上传用户:hkb425
上传日期:2007-06-16
资源大小:34191k
文件大小:19k
源码类别:

游戏引擎

开发平台:

Visual C++

  1. // CMath.cpp: implementation of the CMath class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "CMath.h"
  6. //////////////////////////////////////////////////////////////////////
  7. // Construction/Destruction
  8. //////////////////////////////////////////////////////////////////////
  9. CMath::CMath()
  10. {}
  11. CMath::~CMath()
  12. {}
  13. /////////////////////////////
  14. bool CMath::IsLineSegmentCutByPolygon(VERTEX v1 ,VERTEX v2,VERTEX* pv,int num)
  15. {
  16. if(num<3)return false;
  17. PLANE plane;
  18. plane=GetPlaneEquation(pv,num);
  19. ///////////如果两点在同一侧
  20. if((ClassifyPointPlane(v1,plane)*ClassifyPointPlane(v2,plane))>=0)
  21. return false;
  22. //////////////获得线段与平面的交点
  23. VERTEX intersection;
  24. intersection=GetIntersection(v1,v2,plane);
  25. ///////////包围盒粗略判断
  26. float maxx,minx,  maxy,miny,  maxz,minz;
  27. maxx=minx=pv[0].xpos;
  28. maxy=miny=pv[0].ypos;
  29. maxz=minz=pv[0].zpos;
  30. for(int i=1;i<num;i++)
  31. {
  32. if(pv[i].xpos>maxx)maxx=pv[i].xpos;
  33. if(pv[i].xpos<minx)minx=pv[i].xpos;
  34. if(pv[i].ypos>maxy)maxy=pv[i].ypos;
  35. if(pv[i].ypos<miny)miny=pv[i].ypos;
  36. if(pv[i].zpos>maxz)maxz=pv[i].zpos;
  37. if(pv[i].zpos<minz)minz=pv[i].zpos;
  38. }
  39. if(intersection.xpos>maxx || intersection.xpos<minx)
  40. return false;
  41. if(intersection.ypos>maxy || intersection.ypos<miny)
  42. return false;
  43. if(intersection.zpos>maxz || intersection.zpos<minz)
  44. return false;
  45. //////////////找一个过交点intersection且与某一坐标轴垂直的平面
  46.     PLANE  p(0,0,0,0);
  47.     float absA,absB,absC;
  48. if(plane.A<0)absA=-plane.A;
  49. else absA=plane.A;
  50. if(plane.B<0)absB=-plane.B;
  51. else absB=plane.B;
  52. if(plane.C<0)absC=-plane.C;
  53. else absC=plane.C;
  54. if(absA<=absB && absA<=absC)
  55. {
  56. ///////////平面与X轴接近平行
  57. p.A=1;
  58. p.D=-intersection.xpos;
  59. ///////////////////////////////////////////
  60. if(absB>absC)
  61. {   //////比较 Z 轴坐标
  62.             VERTEX sect[6];/////可能有重复的交点,如顶点
  63.             int  index=0;
  64. for( i=0;i<(num-1);i++)
  65. {
  66. if(ClassifyPointPlane(pv[i],p)!=ClassifyPointPlane(pv[i+1],p))
  67. {
  68.                      sect[index]=GetIntersection(pv[i],pv[i+1],p);
  69.  index++;
  70. }
  71. }
  72. if(ClassifyPointPlane(pv[0],p)!=ClassifyPointPlane(pv[num-1],p))
  73. {
  74.                  sect[index]=GetIntersection(pv[0],pv[num-1],p);
  75.  index++;
  76. }
  77. /////////////////////////////
  78. float maxzz,minzz;
  79. maxzz=minzz=sect[0].zpos;
  80. for(i=0;i<index;i++)
  81. {
  82. if(sect[i].zpos>maxzz)maxzz=sect[i].zpos;
  83. if(sect[i].zpos<minzz)minzz=sect[i].zpos;
  84. }
  85. if(intersection.zpos>maxzz || intersection.zpos<minzz)return false;
  86. else 
  87. return true;
  88. }
  89. else
  90. {   //////比较 Y 轴坐标
  91.             VERTEX sect[6];/////可能有重复的交点,如顶点
  92.             int  index=0;
  93. for( i=0;i<(num-1);i++)
  94. {
  95. if(ClassifyPointPlane(pv[i],p)!=ClassifyPointPlane(pv[i+1],p))
  96. {
  97.                      sect[index]=GetIntersection(pv[i],pv[i+1],p);
  98.  index++;
  99. }
  100. }
  101. if(ClassifyPointPlane(pv[0],p)!=ClassifyPointPlane(pv[num-1],p))
  102. {
  103.                  sect[index]=GetIntersection(pv[0],pv[num-1],p);
  104.  index++;
  105. }
  106. /////////////////////////////
  107. float maxyy,minyy;
  108. maxyy=minyy=sect[0].ypos;
  109. for(i=0;i<index;i++)
  110. {
  111. if(sect[i].ypos>maxyy)maxyy=sect[i].ypos;
  112. if(sect[i].ypos<minyy)minyy=sect[i].ypos;
  113. }
  114. if(intersection.ypos>maxyy || intersection.ypos<minyy)return false;
  115. else 
  116. return true;
  117. }
  118. }
  119. else if(absB<=absA && absB<=absC)
  120. {
  121. ///////////平面与Y轴接近平行
  122. p.B=1;
  123. p.D=-intersection.ypos;
  124. ///////////////////////////////////////////
  125. if(absA>absC)
  126. {   //////比较 Z 轴坐标
  127.             VERTEX sect[6];/////可能有重复的交点,如顶点
  128.             int  index=0;
  129. for( i=0;i<(num-1);i++)
  130. {
  131. if(ClassifyPointPlane(pv[i],p)!=ClassifyPointPlane(pv[i+1],p))
  132. {
  133.                      sect[index]=GetIntersection(pv[i],pv[i+1],p);
  134.  index++;
  135. }
  136. }
  137. if(ClassifyPointPlane(pv[0],p)!=ClassifyPointPlane(pv[num-1],p))
  138. {
  139.                  sect[index]=GetIntersection(pv[0],pv[num-1],p);
  140.  index++;
  141. }
  142. /////////////////////////////
  143. float maxzz,minzz;
  144. maxzz=minzz=sect[0].zpos;
  145. for(i=0;i<index;i++)
  146. {
  147. if(sect[i].zpos>maxzz)maxzz=sect[i].zpos;
  148. if(sect[i].zpos<minzz)minzz=sect[i].zpos;
  149. }
  150. if(intersection.zpos>maxzz || intersection.zpos<minzz)return false;
  151. else 
  152. return true;
  153. }
  154. else
  155. {   //////比较 X 轴坐标
  156.             VERTEX sect[6];/////可能有重复的交点,如顶点
  157.             int  index=0;
  158. for( i=0;i<(num-1);i++)
  159. {
  160. if(ClassifyPointPlane(pv[i],p)!=ClassifyPointPlane(pv[i+1],p))
  161. {
  162.                      sect[index]=GetIntersection(pv[i],pv[i+1],p);
  163.  index++;
  164. }
  165. }
  166. if(ClassifyPointPlane(pv[0],p)!=ClassifyPointPlane(pv[num-1],p))
  167. {
  168.                  sect[index]=GetIntersection(pv[0],pv[num-1],p);
  169.  index++;
  170. }
  171. /////////////////////////////
  172. float maxxx,minxx;
  173. maxxx=minxx=sect[0].xpos;
  174. for(i=0;i<index;i++)
  175. {
  176. if(sect[i].xpos>maxxx)maxxx=sect[i].xpos;
  177. if(sect[i].xpos<minxx)minxx=sect[i].xpos;
  178. }
  179. if(intersection.xpos>maxxx || intersection.xpos<minxx)return false;
  180. else 
  181. return true;
  182. }
  183. }
  184. else  //(absC<absA && absC<absB)
  185. {
  186. ///////////平面与Z轴接近平行
  187. p.C=1;
  188. p.D=-intersection.zpos;
  189. ///////////////////////////////////////////
  190. if(absA>absB)
  191. {   //////比较 Y 轴坐标
  192.             VERTEX sect[6];/////可能有重复的交点,如顶点
  193.             int  index=0;
  194. for( i=0;i<(num-1);i++)
  195. {
  196. if(ClassifyPointPlane(pv[i],p)!=ClassifyPointPlane(pv[i+1],p))
  197. {
  198.                      sect[index]=GetIntersection(pv[i],pv[i+1],p);
  199.  index++;
  200. }
  201. }
  202. if(ClassifyPointPlane(pv[0],p)!=ClassifyPointPlane(pv[num-1],p))
  203. {
  204.                  sect[index]=GetIntersection(pv[0],pv[num-1],p);
  205.  index++;
  206. }
  207. /////////////////////////////
  208. float maxyy,minyy;
  209. maxyy=minyy=sect[0].ypos;
  210. for(i=0;i<index;i++)
  211. {
  212. if(sect[i].ypos>maxyy)maxyy=sect[i].ypos;
  213. if(sect[i].ypos<minyy)minyy=sect[i].ypos;
  214. }
  215. if(intersection.ypos>maxyy || intersection.ypos<minyy)return false;
  216. else 
  217. return true;
  218. }
  219. else
  220. {   //////比较 X 轴坐标
  221.             VERTEX sect[6];/////可能有重复的交点,如顶点
  222.             int  index=0;
  223. for( i=0;i<(num-1);i++)
  224. {
  225. if(ClassifyPointPlane(pv[i],p)!=ClassifyPointPlane(pv[i+1],p))
  226. {
  227.                      sect[index]=GetIntersection(pv[i],pv[i+1],p);
  228.  index++;
  229. }
  230. }
  231. if(ClassifyPointPlane(pv[0],p)!=ClassifyPointPlane(pv[num-1],p))
  232. {
  233.                  sect[index]=GetIntersection(pv[0],pv[num-1],p);
  234.  index++;
  235. }
  236. /////////////////////////////
  237. float maxxx,minxx;
  238. maxxx=minxx=sect[0].xpos;
  239. for(i=0;i<index;i++)
  240. {
  241. if(sect[i].xpos>maxxx)maxxx=sect[i].xpos;
  242. if(sect[i].xpos<minxx)minxx=sect[i].xpos;
  243. }
  244. if(intersection.xpos>maxxx || intersection.xpos<minxx)return false;
  245. else 
  246. return true;
  247. }
  248. }
  249. return true;
  250. }
  251. bool CMath::IsLineSegmentCutBy3DBoundary(VERTEX v1 ,VERTEX v2,BOUNDARY_3D bd)
  252. {
  253. if(v1.xpos>bd.maxx && v2.xpos>bd.maxx)return false;
  254. if(v1.xpos<bd.minx && v2.xpos<bd.minx)return false;
  255. if(v1.ypos>bd.maxy && v2.ypos>bd.maxy)return false;
  256. if(v1.ypos<bd.miny && v2.ypos<bd.miny)return false;
  257. if(v1.zpos>bd.maxz && v2.zpos>bd.maxz)return false;
  258. if(v1.zpos<bd.minz && v2.zpos<bd.minz)return false;
  259. /////////////
  260.     VERTEX v[8];
  261. v[0]=VERTEX(bd.minx,bd.miny,bd.minz);
  262. v[1]=VERTEX(bd.maxx,bd.miny,bd.minz);
  263. v[2]=VERTEX(bd.maxx,bd.maxy,bd.minz);
  264. v[3]=VERTEX(bd.minx,bd.maxy,bd.minz);
  265. v[4]=VERTEX(bd.minx,bd.miny,bd.maxz);
  266. v[5]=VERTEX(bd.maxx,bd.miny,bd.maxz);
  267. v[6]=VERTEX(bd.maxx,bd.maxy,bd.maxz);
  268. v[7]=VERTEX(bd.minx,bd.maxy,bd.maxz);
  269.     ///////////////
  270.     if(IsLineSegmentCutByStardQuad(v1,v2, v[0],v[1],v[2],v[3]))return true;
  271.     if(IsLineSegmentCutByStardQuad(v1,v2, v[4],v[5],v[6],v[7]))return true;
  272.     if(IsLineSegmentCutByStardQuad(v1,v2, v[2],v[3],v[7],v[6]))return true;
  273.     if(IsLineSegmentCutByStardQuad(v1,v2, v[1],v[0],v[4],v[5]))return true;
  274.     if(IsLineSegmentCutByStardQuad(v1,v2, v[1],v[2],v[6],v[5]))return true;
  275.     if(IsLineSegmentCutByStardQuad(v1,v2, v[0],v[3],v[7],v[4]))return true;
  276.     ///////////////
  277.     return false;
  278. }
  279. bool CMath::IsLineSegmentCutByStardQuad(VERTEX v1 ,VERTEX v2,VERTEX va,VERTEX vb,VERTEX vc,VERTEX vd)
  280. {
  281. PLANE plane;
  282. plane=GetPlaneEquation(va,vb,vc);
  283. ///////////如果两点在同一侧
  284. if((ClassifyPointPlane(v1,plane)*ClassifyPointPlane(v2,plane))>=0)
  285. return false;
  286. //////////////获得线段与平面的交点
  287. VERTEX intersection;
  288. intersection=GetIntersection(v1,v2,plane);
  289. ///////////包围盒判断
  290. float maxx,minx,  maxy,miny,  maxz,minz;
  291. maxx=minx=va.xpos;
  292. maxy=miny=va.ypos;
  293. maxz=minz=va.zpos;
  294. if(vb.xpos>maxx)maxx=vb.xpos;
  295. if(vb.xpos<minx)minx=vb.xpos;
  296. if(vb.ypos>maxy)maxy=vb.ypos;
  297. if(vb.ypos<miny)miny=vb.ypos;
  298. if(vb.zpos>maxz)maxz=vb.zpos;
  299. if(vb.zpos<minz)minz=vb.zpos;
  300. if(vc.xpos>maxx)maxx=vc.xpos;
  301. if(vc.xpos<minx)minx=vc.xpos;
  302. if(vc.ypos>maxy)maxy=vc.ypos;
  303. if(vc.ypos<miny)miny=vc.ypos;
  304. if(vc.zpos>maxz)maxz=vc.zpos;
  305. if(vc.zpos<minz)minz=vc.zpos;
  306. if(vd.xpos>maxx)maxx=vd.xpos;
  307. if(vd.xpos<minx)minx=vd.xpos;
  308. if(vd.ypos>maxy)maxy=vd.ypos;
  309. if(vd.ypos<miny)miny=vd.ypos;
  310. if(vd.zpos>maxz)maxz=vd.zpos;
  311. if(vd.zpos<minz)minz=vd.zpos;
  312. if(intersection.xpos>maxx || intersection.xpos<minx)
  313. return false;
  314. if(intersection.ypos>maxy || intersection.ypos<miny)
  315. return false;
  316. if(intersection.zpos>maxz || intersection.zpos<minz)
  317. return false;
  318.     return true;
  319. }
  320. bool CMath::IsLineSegmentCutByStardQuad(VERTEX v1 ,VERTEX v2,VERTEX *pv)
  321. {
  322. return IsLineSegmentCutByStardQuad(v1,v2,pv[0],pv[1],pv[2],pv[3]);
  323. }
  324. PLANE CMath::GetPlaneEquation(VERTEX v1,VERTEX v2,PLANE p)
  325. {
  326. PLANE plane;
  327. /////////////  n12不能与plane垂直
  328.     ////???????????????????????????
  329. ///////////////////////////////
  330.     double nnx,nny,nnz ;
  331. nnx=v2.xpos-v1.xpos;
  332. nny=v2.ypos-v1.ypos;
  333. nnz=v2.zpos-v1.zpos;
  334. double pA,pB,pC,pD;
  335.     pA=p.A; pB=p.B; pC=p.C; pD=p.D;
  336.     double a,b,c;
  337. a=(pC*nny-pB*nnz)*(pA*nny-pB*nnx);
  338.     b=(pC*nnx-pA*nnz)*(pB*nnx-pA*nny);
  339. c=(pB*nnx-pA*nny)*(pA*nny-pB*nnx);
  340. NORMAL n=Normalization(a,b,c);
  341. plane.A=n.nx;
  342. plane.B=n.ny;
  343. plane.C=n.nz;    
  344. plane.D=-(plane.A*v1.xpos+plane.B*v1.ypos+plane.C*v1.zpos);
  345. return plane;
  346. }
  347. PLANE CMath::GetPlaneEquation(VERTEX *pVertices,int VerticesNumber)
  348. {
  349. PLANE plane;
  350. if(VerticesNumber<3)
  351. {
  352. plane.A=plane.B=plane.C=plane.D=0;
  353. }
  354. else
  355. {
  356.      NORMAL N12,N13,N;
  357.      ////////////calculate n12 n13
  358.      N12.nx=pVertices[1].xpos-pVertices[0].xpos;
  359.      N12.ny=pVertices[1].ypos-pVertices[0].ypos;
  360.      N12.nz=pVertices[1].zpos-pVertices[0].zpos;
  361.      N13.nx=pVertices[2].xpos-pVertices[0].xpos;
  362.      N13.ny=pVertices[2].ypos-pVertices[0].ypos;
  363.      N13.nz=pVertices[2].zpos-pVertices[0].zpos;
  364.      ////////////////////////////
  365.         N=GetTwoNormalProduct(N12,N13);
  366.      plane.A=N.nx;
  367.      plane.B=N.ny;
  368.      plane.C=N.nz;
  369. plane.D= -(plane.A*pVertices->xpos+plane.B*pVertices->ypos+plane.C*pVertices->zpos);
  370. }
  371. return plane;
  372. }
  373. PLANE CMath::GetPlaneEquation(VERTEX v1,VERTEX v2,VERTEX v3)
  374. {
  375. PLANE plane;
  376.     NORMAL N12,N13,N;
  377.     ////////////calculate n12 n13
  378.     N12.nx=v2.xpos-v1.xpos;
  379.     N12.ny=v2.ypos-v1.ypos;
  380.     N12.nz=v2.zpos-v1.zpos;
  381.     N13.nx=v3.xpos-v1.xpos;
  382.     N13.ny=v3.ypos-v1.ypos;
  383.     N13.nz=v3.zpos-v1.zpos;
  384.     N=GetTwoNormalProduct(N12,N13);
  385.     plane.A=N.nx;
  386.     plane.B=N.ny;
  387.     plane.C=N.nz;
  388. plane.D= -(plane.A*v1.xpos+plane.B*v1.ypos+plane.C*v1.zpos);
  389. return plane;
  390. }
  391. PLANE CMath::GetPlaneEquation(VERTEX v,PLANE p1,PLANE p2)
  392. {
  393. PLANE plane;
  394.     NORMAL n1,n2,normal;
  395.     n1.nx=p1.A;  n1.ny=p1.B;  n1.nz=p1.C;
  396.     n2.nx=p2.A;  n2.ny=p2.B;  n2.nz=p2.C;
  397. normal=GetTwoNormalProduct(n1,n2);
  398. plane.A=normal.nx;
  399. plane.B=normal.ny;
  400. plane.C=normal.nz;
  401. plane.D=-(plane.A*v.xpos+plane.B*v.ypos+plane.C*v.zpos);
  402. return plane;
  403. }
  404. VERTEX CMath::GetIntersection(VERTEX v1,VERTEX v2,PLANE plane)
  405. {
  406. VERTEX point;
  407. double temp1=(plane.A*(v2.xpos-v1.xpos)+plane.B*(v2.ypos-v1.ypos)+plane.C*(v2.zpos-v1.zpos));
  408. double temp2=-plane.D-plane.A*v1.xpos-plane.B*v1.ypos-plane.C*v1.zpos;
  409.     ///// Line param is temp2/temp1
  410. point.xpos=v1.xpos+float((double(v2.xpos-v1.xpos)*temp2)/temp1);
  411. point.ypos=v1.ypos+float((double(v2.ypos-v1.ypos)*temp2)/temp1);
  412. point.zpos=v1.zpos+float((double(v2.zpos-v1.zpos)*temp2)/temp1);
  413.  
  414. return point;
  415. }
  416. TEXCOORD CMath::GetIntersectionTexCoord(VERTEX pointA,TEXCOORD texcoordA,
  417. VERTEX pointB,TEXCOORD texcoordB,  PLANE plane)
  418. {
  419. VERTEX intersect=GetIntersection(pointA,pointB,plane);
  420. float distA=GetDistance(pointA,intersect);
  421. float distAB=GetDistance(pointA,pointB);
  422. if(distAB<0.0001)return texcoordA; ///////safe
  423. TEXCOORD texcoord;
  424. texcoord.u=(texcoordA.u*distAB + distA*(texcoordB.u-texcoordA.u))/distAB;
  425. texcoord.v=(texcoordA.v*distAB + distA*(texcoordB.v-texcoordA.v))/distAB;
  426. return texcoord;
  427. }
  428. VERTEX CMath::GetPositionOnGrid(VERTEX *pQuads,float u,float v)
  429. {
  430. /////////u,v 的范围为0-1
  431. if(u<0)u=0; if(u>1)u=1;
  432. if(v<0)v=0; if(v>1)v=1;
  433. //////////////////////////////////////
  434. VERTEX v1,v2; //与u相关的两条边上的点
  435. v1=VERTEX(pQuads[0].xpos+(pQuads[1].xpos-pQuads[0].xpos)*u,
  436.               pQuads[0].ypos+(pQuads[1].ypos-pQuads[0].ypos)*u,
  437.               pQuads[0].zpos+(pQuads[1].zpos-pQuads[0].zpos)*u);
  438. v2=VERTEX(pQuads[3].xpos+(pQuads[2].xpos-pQuads[3].xpos)*u,
  439.               pQuads[3].ypos+(pQuads[2].ypos-pQuads[3].ypos)*u,
  440.               pQuads[3].zpos+(pQuads[2].zpos-pQuads[3].zpos)*u);
  441. ///////////////////////////////////////
  442. VERTEX vertex;    ///所求的点
  443.     vertex.xpos=v1.xpos+(v2.xpos-v1.xpos)*v;
  444.     vertex.ypos=v1.ypos+(v2.ypos-v1.ypos)*v;
  445.     vertex.zpos=v1.zpos+(v2.zpos-v1.zpos)*v;
  446. return vertex;
  447. }
  448. NORMAL CMath::GetTwoNormalProduct(NORMAL n1,NORMAL n2)
  449. {
  450. double n1x,n1y,n1z,n2x,n2y,n2z;
  451. n1x=n1.nx;  n1y=n1.ny;  n1z=n1.nz;
  452. n2x=n2.nx;  n2y=n2.ny;  n2z=n2.nz;
  453.     double nx,ny,nz;
  454.     nx=  n1y*n2z-n2y*n1z;
  455.     ny=-(n1x*n2z-n2x*n1z);
  456.     nz=  n1x*n2y-n2x*n1y;
  457. // return NORMAL(float(nx),float(ny),float(nz));
  458. return Normalization(nx,ny,nz);
  459. }
  460. NORMAL CMath::GetNormal(VERTEX v1,VERTEX v2,VERTEX v3)
  461. {
  462. NORMAL n1,n2;
  463. n1.nx=v2.xpos-v1.xpos;
  464. n1.ny=v2.ypos-v1.ypos;
  465. n1.nz=v2.zpos-v1.zpos;
  466. n2.nx=v3.xpos-v1.xpos;
  467. n2.ny=v3.ypos-v1.ypos;
  468. n2.nz=v3.zpos-v1.zpos;
  469. return GetTwoNormalProduct(n1,n2);
  470. }
  471. NORMAL  CMath::GetNormal(float *v1,float *v2,float *v3)
  472. {
  473. NORMAL n1,n2;
  474. n1.nx=v2[0]-v1[0];
  475. n1.ny=v2[1]-v1[1];
  476. n1.nz=v2[2]-v1[2];
  477. n2.nx=v3[0]-v1[0];
  478. n2.ny=v3[1]-v1[1];
  479. n2.nz=v3[2]-v1[2];
  480. return GetTwoNormalProduct(n1,n2);
  481. }
  482. float CMath::GetTwoVectorAngleCosine(NORMAL na,NORMAL nb)
  483. {
  484.     NORMAL n1,n2;
  485. n1=Normalization(na);
  486. n2=Normalization(nb);
  487. double temp,length1,length2;
  488. temp=n1.nx*n2.nx+n1.ny*n2.ny+n1.nz*n2.nz;
  489. length1=pow( n1.nx*n1.nx +n1.ny*n1.ny +n1.nz*n1.nz,0.5);
  490. length2=pow( n2.nx*n2.nx +n2.ny*n2.ny +n2.nz*n2.nz,0.5);
  491. return float(temp/(length1*length2));
  492. }
  493. float CMath::GetDistance(VERTEX v1,VERTEX v2)
  494. {
  495. float dist;
  496. dist=(float)pow((v2.xpos-v1.xpos)*(v2.xpos-v1.xpos)+
  497.             (v2.ypos-v1.ypos)*(v2.ypos-v1.ypos)+
  498. (v2.zpos-v1.zpos)*(v2.zpos-v1.zpos),0.5);
  499. return dist;
  500. }
  501. float CMath::GetDistance(VERTEX point,PLANE plane)
  502. {
  503. float abc=(float)sqrt(plane.A*plane.A+plane.B*plane.B+plane.C*plane.C);
  504. float dist=(plane.A*point.xpos+plane.B*point.ypos+plane.C*point.zpos+plane.D)/abc;
  505.     if(dist<0)dist=-dist;
  506.     return dist;
  507. }
  508. float CMath::GetDistance(VERTEX point,PLANE plane,float powABC)
  509. {
  510.     return (plane.A*point.xpos+plane.B*point.ypos+plane.C*point.zpos+plane.D)/powABC;
  511. }
  512. float CMath::GetTwoVectorAngleCosine(VERTEX  v1,VERTEX vCenter,VERTEX v2)
  513. {
  514. double temp,length1,length2;
  515. double n1nx,n1ny,n1nz,n2nx,n2ny,n2nz;
  516. n1nx=v1.xpos-vCenter.xpos;
  517. n1ny=v1.ypos-vCenter.ypos;
  518. n1nz=v1.zpos-vCenter.zpos;
  519. n2nx=v2.xpos-vCenter.xpos;
  520. n2ny=v2.ypos-vCenter.ypos;
  521. n2nz=v2.zpos-vCenter.zpos;
  522. temp=n1nx*n2nx+n1ny*n2ny+n1nz*n2nz;
  523. length1=pow( n1nx*n1nx +n1ny*n1ny +n1nz*n1nz,0.5);
  524. length2=pow( n2nx*n2nx +n2ny*n2ny +n2nz*n2nz,0.5);
  525. return float(temp/(length1*length2));
  526. }
  527. int CMath::ClassifyTwoNormal(NORMAL n1,NORMAL n2)
  528. {
  529. float temp;
  530. temp=n1.nx*n2.nx+n1.ny*n2.ny+n1.nz*n2.nz;
  531. if(temp==0)return PERPENDICULAR;
  532. if(temp>0)return SHARP_ANGLE;
  533.     if(temp<0)return OBTUSE_ANGLE; 
  534. return UNKNOW;
  535. }
  536. int CMath::ClassifyTwoNormal(VERTEX  v1,VERTEX vCenter,VERTEX v2)
  537. {
  538. float temp;
  539. NORMAL n1,n2;
  540. n1.nx=v1.xpos-vCenter.xpos;
  541. n1.ny=v1.ypos-vCenter.ypos;
  542. n1.nz=v1.zpos-vCenter.zpos;
  543. n2.nx=v2.xpos-vCenter.xpos;
  544. n2.ny=v2.ypos-vCenter.ypos;
  545. n2.nz=v2.zpos-vCenter.zpos;
  546. temp=n1.nx*n2.nx+n1.ny*n2.ny+n1.nz*n2.nz;
  547. if(temp==0)return PERPENDICULAR;
  548. if(temp>0)return SHARP_ANGLE;
  549.     if(temp<0)return OBTUSE_ANGLE; 
  550. return UNKNOW;
  551. }
  552. int CMath::ClassifyPointPlane(VERTEX point,PLANE plane)
  553. {
  554. float distance=plane.A*point.xpos+plane.B*point.ypos+plane.C*point.zpos+plane.D;
  555.     if(distance==0)return COINCIDENT;
  556. if(distance>0)return  IN_FRONT_OF;
  557. return  IN_BACK_OF;
  558. }
  559. int CMath::ClassifyPolygonPlane(PLANE plane,VERTEX *vertices,int num)
  560. {
  561. if(num<3)return UNKNOW;
  562. int current=0;
  563.     int dist=ClassifyPointPlane(vertices[0],plane);
  564. if(dist==IN_FRONT_OF)
  565. {
  566.         current=1;
  567. while(current<num && dist!=IN_BACK_OF)
  568. {
  569.              dist=ClassifyPointPlane(vertices[current],plane);
  570.  current++;
  571. }
  572. if(current<num)return SPANNING;
  573. else if(dist==IN_BACK_OF) return SPANNING;
  574. else return IN_FRONT_OF;
  575. }
  576. else if(dist==IN_BACK_OF)
  577. {
  578.         current=1;
  579. while(current<num && dist!=IN_FRONT_OF)
  580. {
  581.              dist=ClassifyPointPlane(vertices[current],plane);
  582.  current++;
  583. }
  584. if(current<num)return SPANNING;
  585. else if(dist==IN_FRONT_OF) return SPANNING;
  586. else return IN_BACK_OF;
  587. }
  588. else   //First point in the plane
  589. {
  590. int front,back;
  591. front=back=0;
  592. int temp;
  593. for(int i=1;i<num;i++)
  594. {
  595. temp=ClassifyPointPlane(vertices[i],plane);
  596. if(temp==IN_FRONT_OF)front++;
  597. if(temp==IN_BACK_OF)back--;
  598. }
  599. if(front==0 && back==0)return COINCIDENT;
  600. if((front+back)==back)return IN_BACK_OF;
  601. if((front+back)==front)return IN_FRONT_OF;
  602. return SPANNING;
  603. }
  604. }
  605. NORMAL CMath::Normalization(NORMAL n)
  606. {
  607. NORMAL normal;
  608. double x,y,z;
  609. x=n.nx; y=n.ny; z=n.nz;
  610. double max=sqrt(x*x+y*y+z*z);
  611.     if(max<0.0001)return NORMAL(0,1,0);
  612. x=x/max;
  613. y=y/max;
  614. z=z/max;
  615. normal.nx=float(x);
  616. normal.ny=float(y);
  617. normal.nz=float(z);
  618. return normal;
  619. }
  620. NORMAL CMath::Normalization(double x,double y,double z)
  621. {
  622. NORMAL normal=NORMAL(x,y,z);
  623.     return Normalization(normal);
  624. }