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

游戏引擎

开发平台:

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::IsLineSegmentCutBy3DBoundary(VERTEX v1 ,VERTEX v2,BOUNDARY_3D bd)
  280. {
  281. if(v1.xpos>bd.maxx && v2.xpos>bd.maxx)return false;
  282. if(v1.xpos<bd.minx && v2.xpos<bd.minx)return false;
  283. if(v1.ypos>bd.maxy && v2.ypos>bd.maxy)return false;
  284. if(v1.ypos<bd.miny && v2.ypos<bd.miny)return false;
  285. if(v1.zpos>bd.maxz && v2.zpos>bd.maxz)return false;
  286. if(v1.zpos<bd.minz && v2.zpos<bd.minz)return false;
  287. /////////////
  288.     VERTEX v[8];
  289. v[0]=VERTEX(bd.minx,bd.miny,bd.minz);
  290. v[1]=VERTEX(bd.maxx,bd.miny,bd.minz);
  291. v[2]=VERTEX(bd.maxx,bd.maxy,bd.minz);
  292. v[3]=VERTEX(bd.minx,bd.maxy,bd.minz);
  293. v[4]=VERTEX(bd.minx,bd.miny,bd.maxz);
  294. v[5]=VERTEX(bd.maxx,bd.miny,bd.maxz);
  295. v[6]=VERTEX(bd.maxx,bd.maxy,bd.maxz);
  296. v[7]=VERTEX(bd.minx,bd.maxy,bd.maxz);
  297.     ///////////////
  298.     if(IsLineSegmentCutByStardQuad(v1,v2, v[0],v[1],v[2],v[3]))return true;
  299.     if(IsLineSegmentCutByStardQuad(v1,v2, v[4],v[5],v[6],v[7]))return true;
  300.     if(IsLineSegmentCutByStardQuad(v1,v2, v[2],v[3],v[7],v[6]))return true;
  301.     if(IsLineSegmentCutByStardQuad(v1,v2, v[1],v[0],v[4],v[5]))return true;
  302.     if(IsLineSegmentCutByStardQuad(v1,v2, v[1],v[2],v[6],v[5]))return true;
  303.     if(IsLineSegmentCutByStardQuad(v1,v2, v[0],v[3],v[7],v[4]))return true;
  304.     ///////////////
  305.     return false;
  306. }
  307. bool CMath::IsLineSegmentCutByStardQuad(VERTEX v1 ,VERTEX v2,VERTEX va,VERTEX vb,VERTEX vc,VERTEX vd)
  308. {
  309. PLANE plane;
  310. plane=GetPlaneEquation(va,vb,vc);
  311. ///////////如果两点在同一侧
  312. if((ClassifyPointPlane(v1,plane)*ClassifyPointPlane(v2,plane))>=0)
  313. return false;
  314. //////////////获得线段与平面的交点
  315. VERTEX intersection;
  316. intersection=GetIntersection(v1,v2,plane);
  317. ///////////包围盒判断
  318. float maxx,minx,  maxy,miny,  maxz,minz;
  319. maxx=minx=va.xpos;
  320. maxy=miny=va.ypos;
  321. maxz=minz=va.zpos;
  322. if(vb.xpos>maxx)maxx=vb.xpos;
  323. if(vb.xpos<minx)minx=vb.xpos;
  324. if(vb.ypos>maxy)maxy=vb.ypos;
  325. if(vb.ypos<miny)miny=vb.ypos;
  326. if(vb.zpos>maxz)maxz=vb.zpos;
  327. if(vb.zpos<minz)minz=vb.zpos;
  328. if(vc.xpos>maxx)maxx=vc.xpos;
  329. if(vc.xpos<minx)minx=vc.xpos;
  330. if(vc.ypos>maxy)maxy=vc.ypos;
  331. if(vc.ypos<miny)miny=vc.ypos;
  332. if(vc.zpos>maxz)maxz=vc.zpos;
  333. if(vc.zpos<minz)minz=vc.zpos;
  334. if(vd.xpos>maxx)maxx=vd.xpos;
  335. if(vd.xpos<minx)minx=vd.xpos;
  336. if(vd.ypos>maxy)maxy=vd.ypos;
  337. if(vd.ypos<miny)miny=vd.ypos;
  338. if(vd.zpos>maxz)maxz=vd.zpos;
  339. if(vd.zpos<minz)minz=vd.zpos;
  340. if(intersection.xpos>maxx || intersection.xpos<minx)
  341. return false;
  342. if(intersection.ypos>maxy || intersection.ypos<miny)
  343. return false;
  344. if(intersection.zpos>maxz || intersection.zpos<minz)
  345. return false;
  346.     return true;
  347. }
  348. bool CMath::IsLineSegmentCutByStardQuad(VERTEX v1 ,VERTEX v2,VERTEX *pv)
  349. {
  350. return IsLineSegmentCutByStardQuad(v1,v2,pv[0],pv[1],pv[2],pv[3]);
  351. }
  352. bool CMath::IsVertexInsideCube(VERTEX vertex , CUBE cube )
  353. {
  354.     if(vertex.xpos < cube.V0.xpos)return false;
  355.     if(vertex.xpos > cube.V1.xpos)return false;
  356.     if(vertex.ypos < cube.V0.ypos)return false;
  357.     if(vertex.ypos > cube.V4.ypos)return false;
  358.     if(vertex.zpos < cube.V3.zpos)return false;
  359.     if(vertex.zpos > cube.V0.zpos)return false;
  360. return true;
  361. }
  362. bool CMath::IsVertexInsideCube(VERTEX *vertex , BOUNDARY_3D *boundary)
  363. {
  364.     if(vertex->xpos > boundary->maxx || vertex->xpos < boundary->minx)return false;
  365.     if(vertex->ypos > boundary->maxy || vertex->ypos < boundary->miny)return false;
  366.     if(vertex->zpos > boundary->maxz || vertex->zpos < boundary->minz)return false;
  367. return true;
  368. }
  369. bool CMath::IsCubeCutByQuad(CUBE cube , QUAD quad)
  370. {
  371. ////////////// 1.如果Quad上有一个点在cube内,则相交
  372.     if(IsVertexInsideCube(quad.V0,cube))return true;
  373.     if(IsVertexInsideCube(quad.V1,cube))return true;
  374.     if(IsVertexInsideCube(quad.V2,cube))return true;
  375.     if(IsVertexInsideCube(quad.V3,cube))return true;
  376. ////////////// 2. 现在quad的四个点都在cube外,
  377. if(quad.V0.xpos < cube.V0.xpos && 
  378.        quad.V1.xpos < cube.V0.xpos && 
  379.    quad.V2.xpos < cube.V0.xpos && 
  380.    quad.V3.xpos < cube.V0.xpos    )return false;
  381. if(quad.V0.xpos > cube.V1.xpos && 
  382.        quad.V1.xpos > cube.V1.xpos && 
  383.    quad.V2.xpos > cube.V1.xpos && 
  384.    quad.V3.xpos > cube.V1.xpos    )return false;
  385. if(quad.V0.ypos < cube.V0.ypos && 
  386.        quad.V1.ypos < cube.V0.ypos && 
  387.    quad.V2.ypos < cube.V0.ypos && 
  388.    quad.V3.ypos < cube.V0.ypos    )return false;
  389. if(quad.V0.ypos > cube.V4.ypos && 
  390.        quad.V1.ypos > cube.V4.ypos && 
  391.    quad.V2.ypos > cube.V4.ypos && 
  392.    quad.V3.ypos > cube.V4.ypos    )return false;
  393. if(quad.V0.zpos < cube.V2.zpos && 
  394.        quad.V1.zpos < cube.V2.zpos && 
  395.    quad.V2.zpos < cube.V2.zpos && 
  396.    quad.V3.zpos < cube.V2.zpos    )return false;
  397. if(quad.V0.zpos > cube.V1.zpos && 
  398.        quad.V1.zpos > cube.V1.zpos && 
  399.    quad.V2.zpos > cube.V1.zpos && 
  400.    quad.V3.zpos > cube.V1.zpos    )return false;
  401. /////////////// 3.现在判断cube上的8个点是否在Quad的同一侧
  402. int side[8];
  403. side[0] = ClassifyPointPlane(cube.V0,quad.plane);
  404. side[1] = ClassifyPointPlane(cube.V1,quad.plane);
  405. side[2] = ClassifyPointPlane(cube.V2,quad.plane);
  406. side[3] = ClassifyPointPlane(cube.V3,quad.plane);
  407. side[4] = ClassifyPointPlane(cube.V4,quad.plane);
  408. side[5] = ClassifyPointPlane(cube.V5,quad.plane);
  409. side[6] = ClassifyPointPlane(cube.V6,quad.plane);
  410. side[7] = ClassifyPointPlane(cube.V7,quad.plane);
  411. int count = 0;
  412. int index = 0;
  413. for(int i=0;i<8;i++)
  414. {
  415. // if(side[i] !=0 )
  416. {
  417. count+=side[i];
  418. index++;
  419. }
  420. }
  421. if(count==index || count==-index)return false;
  422. ////////////// 4.判断cube的12条边中有没有与Quad相交的
  423. // VERTEX vList[4];
  424. if(IsLineSegmentCutByPolygon(cube.V0,cube.V1,&quad.V0,4))return true;
  425. if(IsLineSegmentCutByPolygon(cube.V0,cube.V4,&quad.V0,4))return true;
  426. if(IsLineSegmentCutByPolygon(cube.V0,cube.V3,&quad.V0,4))return true;
  427.  
  428. if(IsLineSegmentCutByPolygon(cube.V6,cube.V7,&quad.V0,4))return true;
  429. if(IsLineSegmentCutByPolygon(cube.V6,cube.V2,&quad.V0,4))return true;
  430. if(IsLineSegmentCutByPolygon(cube.V6,cube.V5,&quad.V0,4))return true;
  431.  
  432. if(IsLineSegmentCutByPolygon(cube.V7,cube.V3,&quad.V0,4))return true;
  433. if(IsLineSegmentCutByPolygon(cube.V7,cube.V4,&quad.V0,4))return true;
  434. if(IsLineSegmentCutByPolygon(cube.V5,cube.V4,&quad.V0,4))return true;
  435.   if(IsLineSegmentCutByPolygon(cube.V5,cube.V1,&quad.V0,4))return true;
  436. if(IsLineSegmentCutByPolygon(cube.V2,cube.V1,&quad.V0,4))return true;
  437. if(IsLineSegmentCutByPolygon(cube.V2,cube.V3,&quad.V0,4))return true;
  438.  
  439. return false;
  440. }
  441. PLANE CMath::GetPlaneEquation(VERTEX v1,VERTEX v2,PLANE p)
  442. {
  443. PLANE plane;
  444. /////////////  n12不能与plane垂直
  445.     ////???????????????????????????
  446. ///////////////////////////////
  447.     double nnx,nny,nnz ;
  448. nnx=v2.xpos-v1.xpos;
  449. nny=v2.ypos-v1.ypos;
  450. nnz=v2.zpos-v1.zpos;
  451. double pA,pB,pC,pD;
  452.     pA=p.A; pB=p.B; pC=p.C; pD=p.D;
  453.     double a,b,c;
  454. a=(pC*nny-pB*nnz)*(pA*nny-pB*nnx);
  455.     b=(pC*nnx-pA*nnz)*(pB*nnx-pA*nny);
  456. c=(pB*nnx-pA*nny)*(pA*nny-pB*nnx);
  457. NORMAL n=Normalization(a,b,c);
  458. plane.A=n.nx;
  459. plane.B=n.ny;
  460. plane.C=n.nz;    
  461. plane.D=-(plane.A*v1.xpos+plane.B*v1.ypos+plane.C*v1.zpos);
  462. return plane;
  463. }
  464. PLANE CMath::GetPlaneEquation(VERTEX *pVertices,int VerticesNumber)
  465. {
  466. PLANE plane;
  467. if(VerticesNumber<3)
  468. {
  469. plane.A=plane.B=plane.C=plane.D=0;
  470. }
  471. else
  472. {
  473.      NORMAL N12,N13,N;
  474.      ////////////calculate n12 n13
  475.      N12.nx=pVertices[1].xpos-pVertices[0].xpos;
  476.      N12.ny=pVertices[1].ypos-pVertices[0].ypos;
  477.      N12.nz=pVertices[1].zpos-pVertices[0].zpos;
  478.      N13.nx=pVertices[2].xpos-pVertices[0].xpos;
  479.      N13.ny=pVertices[2].ypos-pVertices[0].ypos;
  480.      N13.nz=pVertices[2].zpos-pVertices[0].zpos;
  481.      ////////////////////////////
  482.         N=GetTwoNormalProduct(N12,N13);
  483.      plane.A=N.nx;
  484.      plane.B=N.ny;
  485.      plane.C=N.nz;
  486. plane.D= -(plane.A*pVertices->xpos+plane.B*pVertices->ypos+plane.C*pVertices->zpos);
  487. }
  488. return plane;
  489. }
  490. PLANE CMath::GetPlaneEquation(VERTEX v1,VERTEX v2,VERTEX v3)
  491. {
  492. PLANE plane;
  493.     NORMAL N12,N13,N;
  494.     ////////////calculate n12 n13
  495.     N12.nx=v2.xpos-v1.xpos;
  496.     N12.ny=v2.ypos-v1.ypos;
  497.     N12.nz=v2.zpos-v1.zpos;
  498.     N13.nx=v3.xpos-v1.xpos;
  499.     N13.ny=v3.ypos-v1.ypos;
  500.     N13.nz=v3.zpos-v1.zpos;
  501.     N=GetTwoNormalProduct(N12,N13);
  502.     plane.A=N.nx;
  503.     plane.B=N.ny;
  504.     plane.C=N.nz;
  505. plane.D= -(plane.A*v1.xpos+plane.B*v1.ypos+plane.C*v1.zpos);
  506. return plane;
  507. }
  508. PLANE CMath::GetPlaneEquation(VERTEX v,PLANE p1,PLANE p2)
  509. {
  510. PLANE plane;
  511.     NORMAL n1,n2,normal;
  512.     n1.nx=p1.A;  n1.ny=p1.B;  n1.nz=p1.C;
  513.     n2.nx=p2.A;  n2.ny=p2.B;  n2.nz=p2.C;
  514. normal=GetTwoNormalProduct(n1,n2);
  515. plane.A=normal.nx;
  516. plane.B=normal.ny;
  517. plane.C=normal.nz;
  518. plane.D=-(plane.A*v.xpos+plane.B*v.ypos+plane.C*v.zpos);
  519. return plane;
  520. }
  521. VERTEX CMath::GetIntersection(VERTEX v1,VERTEX v2,PLANE plane)
  522. {
  523. VERTEX point;
  524. double temp1=(plane.A*(v2.xpos-v1.xpos)+plane.B*(v2.ypos-v1.ypos)+plane.C*(v2.zpos-v1.zpos));
  525. double temp2=-plane.D-plane.A*v1.xpos-plane.B*v1.ypos-plane.C*v1.zpos;
  526.     ///// Line param is temp2/temp1
  527. point.xpos=v1.xpos+float((double(v2.xpos-v1.xpos)*temp2)/temp1);
  528. point.ypos=v1.ypos+float((double(v2.ypos-v1.ypos)*temp2)/temp1);
  529. point.zpos=v1.zpos+float((double(v2.zpos-v1.zpos)*temp2)/temp1);
  530.  
  531. return point;
  532. }
  533. VERTEX CMath::GetProjection(VERTEX vertex,PLANE plane)
  534. {
  535.     VERTEX v=VERTEX(vertex.xpos-plane.A,vertex.ypos-plane.B,vertex.zpos-plane.C);
  536. return GetIntersection(v,vertex,plane);
  537. }
  538. TEXCOORD CMath::GetIntersectionTexCoord(VERTEX pointA,TEXCOORD texcoordA,
  539. VERTEX pointB,TEXCOORD texcoordB,  PLANE plane)
  540. {
  541. VERTEX intersect=GetIntersection(pointA,pointB,plane);
  542. float distA=GetDistance(pointA,intersect);
  543. float distAB=GetDistance(pointA,pointB);
  544. if(distAB<0.0001)return texcoordA; ///////safe
  545. TEXCOORD texcoord;
  546. texcoord.u=(texcoordA.u*distAB + distA*(texcoordB.u-texcoordA.u))/distAB;
  547. texcoord.v=(texcoordA.v*distAB + distA*(texcoordB.v-texcoordA.v))/distAB;
  548. return texcoord;
  549. }
  550. VERTEX CMath::GetPositionOnGrid(VERTEX *pQuads,float u,float v)
  551. {
  552. /////////u,v 的范围为0-1
  553. if(u<0)u=0; if(u>1)u=1;
  554. if(v<0)v=0; if(v>1)v=1;
  555. //////////////////////////////////////
  556. VERTEX v1,v2; //与u相关的两条边上的点
  557. v1=VERTEX(pQuads[0].xpos+(pQuads[1].xpos-pQuads[0].xpos)*u,
  558.               pQuads[0].ypos+(pQuads[1].ypos-pQuads[0].ypos)*u,
  559.               pQuads[0].zpos+(pQuads[1].zpos-pQuads[0].zpos)*u);
  560. v2=VERTEX(pQuads[3].xpos+(pQuads[2].xpos-pQuads[3].xpos)*u,
  561.               pQuads[3].ypos+(pQuads[2].ypos-pQuads[3].ypos)*u,
  562.               pQuads[3].zpos+(pQuads[2].zpos-pQuads[3].zpos)*u);
  563. ///////////////////////////////////////
  564. VERTEX vertex;    ///所求的点
  565.     vertex.xpos=v1.xpos+(v2.xpos-v1.xpos)*v;
  566.     vertex.ypos=v1.ypos+(v2.ypos-v1.ypos)*v;
  567.     vertex.zpos=v1.zpos+(v2.zpos-v1.zpos)*v;
  568. return vertex;
  569. }
  570. NORMAL CMath::GetTwoNormalProduct(NORMAL n1,NORMAL n2)
  571. {
  572. double n1x,n1y,n1z,n2x,n2y,n2z;
  573. n1x=n1.nx;  n1y=n1.ny;  n1z=n1.nz;
  574. n2x=n2.nx;  n2y=n2.ny;  n2z=n2.nz;
  575.     double nx,ny,nz;
  576.     nx=  n1y*n2z-n2y*n1z;
  577.     ny=-(n1x*n2z-n2x*n1z);
  578.     nz=  n1x*n2y-n2x*n1y;
  579. // return NORMAL(float(nx),float(ny),float(nz));
  580. return Normalization(nx,ny,nz);
  581. }
  582. NORMAL CMath::GetNormal(VERTEX v1,VERTEX v2,VERTEX v3)
  583. {
  584. NORMAL n1,n2;
  585. n1.nx=v2.xpos-v1.xpos;
  586. n1.ny=v2.ypos-v1.ypos;
  587. n1.nz=v2.zpos-v1.zpos;
  588. n2.nx=v3.xpos-v1.xpos;
  589. n2.ny=v3.ypos-v1.ypos;
  590. n2.nz=v3.zpos-v1.zpos;
  591. return GetTwoNormalProduct(n1,n2);
  592. }
  593. NORMAL  CMath::GetNormal(float *v1,float *v2,float *v3)
  594. {
  595. NORMAL n1,n2;
  596. n1.nx=v2[0]-v1[0];
  597. n1.ny=v2[1]-v1[1];
  598. n1.nz=v2[2]-v1[2];
  599. n2.nx=v3[0]-v1[0];
  600. n2.ny=v3[1]-v1[1];
  601. n2.nz=v3[2]-v1[2];
  602. return GetTwoNormalProduct(n1,n2);
  603. }
  604. float CMath::GetTwoVectorAngleCosine(NORMAL na,NORMAL nb)
  605. {
  606.     NORMAL n1,n2;
  607. n1=Normalization(na);
  608. n2=Normalization(nb);
  609. double temp,length1,length2;
  610. temp=n1.nx*n2.nx+n1.ny*n2.ny+n1.nz*n2.nz;
  611. length1=pow( n1.nx*n1.nx +n1.ny*n1.ny +n1.nz*n1.nz,0.5);
  612. length2=pow( n2.nx*n2.nx +n2.ny*n2.ny +n2.nz*n2.nz,0.5);
  613. return float(temp/(length1*length2));
  614. }
  615. float CMath::GetDistance(VERTEX v1,VERTEX v2)
  616. {
  617. float dist;
  618. dist=(float)pow((v2.xpos-v1.xpos)*(v2.xpos-v1.xpos)+
  619.             (v2.ypos-v1.ypos)*(v2.ypos-v1.ypos)+
  620. (v2.zpos-v1.zpos)*(v2.zpos-v1.zpos),0.5);
  621. return dist;
  622. }
  623. float CMath::GetPointToLineDist2D(VERTEX lineV1,VERTEX lineV2,VERTEX point)
  624. {
  625. PLANE plane=GetPlaneEquation(lineV1,lineV2,VERTEX(lineV1.xpos,lineV1.ypos-200,lineV1.zpos));
  626.     float dist=GetDistance(point,plane);
  627. if(dist<0)dist=-dist;
  628. return dist;
  629. }
  630. float CMath::GetDistance(VERTEX point,PLANE plane)
  631. {
  632. float abc=(float)sqrt(plane.A*plane.A+plane.B*plane.B+plane.C*plane.C);
  633. float dist=(plane.A*point.xpos+plane.B*point.ypos+plane.C*point.zpos+plane.D)/abc;
  634. //    if(dist<0)dist=-dist;
  635.     return dist;
  636. }
  637. float CMath::GetDistance(VERTEX point,PLANE plane,float powABC)
  638. {
  639.     return (plane.A*point.xpos+plane.B*point.ypos+plane.C*point.zpos+plane.D)/powABC;
  640. }
  641. float CMath::GetTwoVectorAngleCosine(VERTEX  v1,VERTEX vCenter,VERTEX v2)
  642. {
  643. double temp,length1,length2;
  644. double n1nx,n1ny,n1nz,n2nx,n2ny,n2nz;
  645. n1nx=v1.xpos-vCenter.xpos;
  646. n1ny=v1.ypos-vCenter.ypos;
  647. n1nz=v1.zpos-vCenter.zpos;
  648. n2nx=v2.xpos-vCenter.xpos;
  649. n2ny=v2.ypos-vCenter.ypos;
  650. n2nz=v2.zpos-vCenter.zpos;
  651. temp=n1nx*n2nx+n1ny*n2ny+n1nz*n2nz;
  652. length1=pow( n1nx*n1nx +n1ny*n1ny +n1nz*n1nz,0.5);
  653. length2=pow( n2nx*n2nx +n2ny*n2ny +n2nz*n2nz,0.5);
  654. return float(temp/(length1*length2));
  655. }
  656. int CMath::ClassifyTwoNormal(NORMAL n1,NORMAL n2)
  657. {
  658. float temp;
  659. temp=n1.nx*n2.nx+n1.ny*n2.ny+n1.nz*n2.nz;
  660. if(temp==0)return PERPENDICULAR;
  661. if(temp>0)return SHARP_ANGLE;
  662.     if(temp<0)return OBTUSE_ANGLE; 
  663. return UNKNOW;
  664. }
  665. int CMath::ClassifyTwoNormal(VERTEX  v1,VERTEX vCenter,VERTEX v2)
  666. {
  667. float temp;
  668. NORMAL n1,n2;
  669. n1.nx=v1.xpos-vCenter.xpos;
  670. n1.ny=v1.ypos-vCenter.ypos;
  671. n1.nz=v1.zpos-vCenter.zpos;
  672. n2.nx=v2.xpos-vCenter.xpos;
  673. n2.ny=v2.ypos-vCenter.ypos;
  674. n2.nz=v2.zpos-vCenter.zpos;
  675. temp=n1.nx*n2.nx+n1.ny*n2.ny+n1.nz*n2.nz;
  676. if(temp==0)return PERPENDICULAR;
  677. if(temp>0)return SHARP_ANGLE;
  678.     if(temp<0)return OBTUSE_ANGLE; 
  679. return UNKNOW;
  680. }
  681. int CMath::ClassifyPointPlane(VERTEX point,PLANE plane)
  682. {
  683. float distance=plane.A*point.xpos+plane.B*point.ypos+plane.C*point.zpos+plane.D;
  684.     if(distance==0)return COINCIDENT;
  685. if(distance>0)return  IN_FRONT_OF;
  686. return  IN_BACK_OF;
  687. }
  688. int CMath::ClassifyPolygonPlane(PLANE plane,VERTEX *vertices,int num)
  689. {
  690. if(num<3)return UNKNOW;
  691. int current=0;
  692.     int dist=ClassifyPointPlane(vertices[0],plane);
  693. if(dist==IN_FRONT_OF)
  694. {
  695.         current=1;
  696. while(current<num && dist!=IN_BACK_OF)
  697. {
  698.              dist=ClassifyPointPlane(vertices[current],plane);
  699.  current++;
  700. }
  701. if(current<num)return SPANNING;
  702. else if(dist==IN_BACK_OF) return SPANNING;
  703. else return IN_FRONT_OF;
  704. }
  705. else if(dist==IN_BACK_OF)
  706. {
  707.         current=1;
  708. while(current<num && dist!=IN_FRONT_OF)
  709. {
  710.              dist=ClassifyPointPlane(vertices[current],plane);
  711.  current++;
  712. }
  713. if(current<num)return SPANNING;
  714. else if(dist==IN_FRONT_OF) return SPANNING;
  715. else return IN_BACK_OF;
  716. }
  717. else   //First point in the plane
  718. {
  719. int front,back;
  720. front=back=0;
  721. int temp;
  722. for(int i=1;i<num;i++)
  723. {
  724. temp=ClassifyPointPlane(vertices[i],plane);
  725. if(temp==IN_FRONT_OF)front++;
  726. if(temp==IN_BACK_OF)back--;
  727. }
  728. if(front==0 && back==0)return COINCIDENT;
  729. if((front+back)==back)return IN_BACK_OF;
  730. if((front+back)==front)return IN_FRONT_OF;
  731. return SPANNING;
  732. }
  733. }
  734. NORMAL CMath::Normalization(NORMAL n)
  735. {
  736. NORMAL normal;
  737. double x,y,z;
  738. x=n.nx; y=n.ny; z=n.nz;
  739. double max=sqrt(x*x+y*y+z*z);
  740.     if(max<0.0001)return NORMAL(0,1,0);
  741. x=x/max;
  742. y=y/max;
  743. z=z/max;
  744. normal.nx=float(x);
  745. normal.ny=float(y);
  746. normal.nz=float(z);
  747. return normal;
  748. }
  749. NORMAL CMath::Normalization(double x,double y,double z)
  750. {
  751. NORMAL normal=NORMAL(float(x),float(y),float(z));
  752.     return Normalization(normal);
  753. /*
  754. double absX,absY,absZ;
  755. if(x<0)absX=-x;
  756. else absX=x;
  757. if(y<0)absY=-y;
  758. else absY=y;
  759. if(z<0)absZ=-z;
  760. else absZ=z;
  761. double max=absX>absY?absX:absY;
  762. max=max>absZ?max:absZ ;
  763.   
  764. x=x/max;
  765. y=y/max;
  766. z=z/max;
  767. normal.nx=float(x);
  768. normal.ny=float(y);
  769. normal.nz=float(z);
  770. return normal;*/
  771. }