DelaunayDoc.cpp
上传用户:azhong891
上传日期:2013-06-04
资源大小:197k
文件大小:32k
源码类别:

GIS编程

开发平台:

Visual C++

  1. // DelaunayDoc.cpp : implementation of the CDelaunayDoc class
  2. //
  3. #include "stdafx.h"
  4. #include "Delaunay.h"
  5. #include "DelaunayDoc.h"
  6. #include "pointview.h"
  7. #ifdef _DEBUG
  8. #define new DEBUG_NEW
  9. #undef THIS_FILE
  10. static char THIS_FILE[] = __FILE__;
  11. #endif
  12. /////////////////////////////////////////////////////////////////////////////
  13. // CDelaunayDoc
  14. IMPLEMENT_DYNCREATE(CDelaunayDoc, CDocument)
  15. BEGIN_MESSAGE_MAP(CDelaunayDoc, CDocument)
  16. //{{AFX_MSG_MAP(CDelaunayDoc)
  17. ON_COMMAND(ID_BUTTON_ADD, OnButtonAdd)
  18. ON_UPDATE_COMMAND_UI(ID_BUTTON_ADD, OnUpdateButtonAdd)
  19. ON_COMMAND(ID_BUTTON_BB, OnButtonBB)
  20. ON_UPDATE_COMMAND_UI(ID_BUTTON_BB, OnUpdateButtonBB)
  21. //}}AFX_MSG_MAP
  22. END_MESSAGE_MAP()
  23. /////////////////////////////////////////////////////////////////////////////
  24. // CDelaunayDoc construction/destruction
  25. CDelaunayDoc::CDelaunayDoc()
  26. {
  27. // TODO: add one-time construction code here
  28. }
  29. CDelaunayDoc::~CDelaunayDoc()
  30. {
  31. }
  32. BOOL CDelaunayDoc::OnNewDocument()
  33. {
  34. if (!CDocument::OnNewDocument())
  35. return FALSE;
  36. // TODO: add reinitialization code here
  37. // (SDI documents will reuse this document)
  38. //CPointPos* temp=new CPointPos;
  39. //m_point.Add(temp);
  40. return TRUE;
  41. }
  42. /////////////////////////////////////////////////////////////////////////////
  43. // CDelaunayDoc serialization
  44. void CDelaunayDoc::Serialize(CArchive& ar)
  45. {
  46. if (ar.IsStoring())
  47. {
  48. }
  49. else
  50. {
  51. // TODO: add loading code here
  52. }
  53. m_con.Serialize(ar);
  54. m_point.Serialize(ar);////////
  55. m_tri.Serialize(ar);
  56. // m_n.Serialize(ar);
  57. }
  58. /////////////////////////////////////////////////////////////////////////////
  59. // CDelaunayDoc diagnostics
  60. #ifdef _DEBUG
  61. void CDelaunayDoc::AssertValid() const
  62. {
  63. CDocument::AssertValid();
  64. }
  65. void CDelaunayDoc::Dump(CDumpContext& dc) const
  66. {
  67. CDocument::Dump(dc);
  68. }
  69. #endif //_DEBUG
  70. /////////////////////////////////////////////////////////////////////////////
  71. // CDelaunayDoc commands
  72. void CDelaunayDoc::AddPoint(double x, double y)
  73. {
  74. double z;
  75. int m_plen;//当前节点个数
  76. CPointPos *p;
  77. p=new CPointPos(x,y);
  78. if(x<=0.4)
  79. {
  80. z=0.03-(x-0.2)*(x-0.2)-(y-0.5)*(y-0.5);
  81.     if(z<0) z=0.1;
  82. p->m_z=sqrt(z)*double(3);
  83. }
  84. else{
  85.     if(x>=0.6)
  86. {
  87. z=0.05-(x-0.8)*(x-0.8)-(y-0.5)*(y-0.5);
  88.         if(z<0) z=0.1;
  89.     p->m_z=sqrt(z)*double(1.5);
  90. }
  91. else
  92.             p->m_z=0.5;
  93. }
  94. //p->m_z=sin((x-0.5)*(y-0.5));
  95. //z=0.25-(x-0.5)*(x-0.5)-(y-0.5)*(y-0.5);
  96. //if(z<0) z=0;
  97. //p->m_z=sqrt(z)*double(4);//;
  98. //p->m_z = (float)sin(3.0*x)*cos(3.0*y)/3.0f;
  99. ASSERT(p!=NULL);
  100. m_point.Add(p);
  101. POSITION pos;
  102. pos=GetFirstViewPosition();
  103. m_plen=m_point.GetSize();
  104. while(pos!=NULL)
  105. {
  106. CView *pp=GetNextView(pos);
  107. if(pp->IsKindOf(RUNTIME_CLASS(CPointView)))
  108. {
  109. CListCtrl &list=((CPointView*)pp)->GetListCtrl();
  110. LV_ITEM li;
  111. CString str;
  112. str.Format("%d",m_plen-1);
  113. li.mask=LVIF_TEXT;
  114. li.pszText=str.GetBuffer(10);;
  115. li.iItem=m_plen-1;
  116. li.iSubItem=0;
  117. list.InsertItem(&li);
  118. str.ReleaseBuffer();
  119. str.Format("%f",p->m_x);
  120. li.pszText=str.GetBuffer(10);
  121. li.iItem=m_plen-1;
  122. li.iSubItem=1;
  123. list.SetItem(&li);
  124. str.ReleaseBuffer();
  125. str.Format("%f",p->m_y);
  126. li.pszText=str.GetBuffer(10);
  127. li.iItem=m_plen-1;
  128. li.iSubItem=2;
  129. list.SetItem(&li);
  130. str.ReleaseBuffer();
  131. }
  132. }
  133. };
  134. ////////////////////////////////////////////
  135. void CDelaunayDoc::DeleteContents() 
  136. {
  137. int i,max;
  138. max=m_point.GetSize();
  139. for(i=0;i<max;i++)
  140. {
  141. if(m_point[i]!=NULL)
  142. delete m_point[i];
  143. //if(m_n[i]!=NULL)//????????
  144. // delete m_n[i];
  145. }
  146. m_point.RemoveAll();
  147. // m_n.RemoveAll();
  148. POSITION pos = m_tri.GetHeadPosition();
  149. while( pos != NULL )
  150. {
  151. delete m_tri.GetNext( pos );
  152. }
  153. m_tri.RemoveAll();
  154.     m_con.RemoveAll();
  155. m_index.RemoveAll();
  156. CDocument::DeleteContents();
  157. }
  158. ///////////////////////////////////////////////////
  159. void CDelaunayDoc::Center(CTriangle *temp)//外接圆心和半径
  160. {
  161. ASSERT(temp!=NULL);
  162. int p1,p2,p3;
  163. p1=temp->m_p1;
  164. p2=temp->m_p2;
  165. p3=temp->m_p3;
  166.     double k21,k31;
  167. CPointPos* p11=(CPointPos*)m_point[p1];
  168. CPointPos* p22=(CPointPos*)m_point[p2];
  169. CPointPos* p33=(CPointPos*)m_point[p3];
  170. if((p22->m_x-p11->m_x)==0) 
  171. {
  172. temp->m_yc=(p11->m_y+p22->m_y)/2;//circle 纵坐标
  173.         k31=(p33->m_y-p11->m_y)/(p33->m_x-p11->m_x);
  174. if (k31==0)
  175. {
  176. temp->m_xc=(p11->m_x+p33->m_x)/2;
  177. }
  178. else
  179. {
  180.    temp->m_xc=(p11->m_x+p33->m_x)/2+
  181.    ((p11->m_y+p33->m_y)/2-temp->m_yc)*k31;
  182. }
  183. }
  184. else 
  185. {
  186. k21=(p22->m_y-p11->m_y)/(p22->m_x-p11->m_x);
  187. if (k21==0)
  188. {
  189. temp->m_xc=(p11->m_x+p22->m_x)/2;
  190. if((p22->m_x-p33->m_x)==0) 
  191. {
  192. temp->m_yc=(p11->m_y+p33->m_y)/2;
  193. }
  194.     else
  195. {
  196.                 k31=(p33->m_y-p11->m_y)/
  197.            (p33->m_x-p11->m_x);
  198.         temp->m_yc=((p33->m_x+p11->m_x)/2-
  199.          temp->m_xc)/k31+
  200.  (p11->m_y+p33->m_y)/2;
  201. }
  202. }
  203. else
  204. {
  205.     if((p33->m_x-p11->m_x)==0)
  206. {
  207. temp->m_yc=(p33->m_y+p11->m_y)/2;
  208. temp->m_xc=k21*(p11->m_y/2+p22->m_y/2-temp->m_yc)+
  209. (p11->m_x+p22->m_x)/2;
  210. }
  211. else
  212. {
  213.  k31=(p33->m_y-p11->m_y)/(p33->m_x-p11->m_x);
  214.  if(k31==0)
  215.  {
  216.                       temp->m_xc=(p11->m_x+p33->m_x)/2;
  217.       temp->m_yc=((p11->m_x+p22->m_x)/2-
  218.          temp->m_xc)/k21+
  219.  (p11->m_y+p22->m_y)/2;
  220.  }
  221.  else
  222.  {
  223.                           temp->m_xc=(k21*k31*(p22->m_y-p33->m_y)+
  224. (p11->m_x+p22->m_x)*k31-(p11->m_x+p33->m_x)*k21)/(k31-k21);
  225.   temp->m_xc=temp->m_xc/2;
  226.                           temp->m_yc=((p11->m_x+p22->m_x)/2-
  227.          temp->m_xc)/k21+
  228.  (p11->m_y+p22->m_y)/2;
  229.  }
  230. }
  231. }
  232. }
  233. temp->m_rad=sqrt((p33->m_x-temp->m_xc)*(p33->m_x-temp->m_xc)
  234.               + (p33->m_y-temp->m_yc)*(p33->m_y-temp->m_yc));
  235. }
  236. ///////////////////////////////////////////////////
  237. void CDelaunayDoc::OnButtonAdd() 
  238. {
  239. m_DoWhat=DO_ADD;
  240. }
  241. void CDelaunayDoc::OnUpdateButtonAdd(CCmdUI* pCmdUI) 
  242. {
  243. if(m_DoWhat==DO_ADD)
  244. pCmdUI->SetCheck(1);
  245. else 
  246. pCmdUI->SetCheck(0);
  247. }
  248. void CDelaunayDoc::AddTriangle(int p)
  249. {
  250.    //add new triangles
  251. CTriangle* pTriangle;
  252. int max=m_edge.GetSize();
  253. for(int i=0;i<max;i++)
  254. {
  255.    //Every triangle is stored anticlockwise,too.
  256.    if(S(m_edge[i]->m_p1,m_edge[i]->m_p2,p)>0){
  257. pTriangle=new CTriangle(m_edge[i]->m_p1,m_edge[i]->m_p2,p);
  258.    }
  259.    else{
  260.               pTriangle=new CTriangle(m_edge[i]->m_p2,m_edge[i]->m_p1,p);
  261.    }
  262.    Center(pTriangle);
  263.        BaryCenter(pTriangle);
  264.    m_tri.AddTail(pTriangle);
  265. }
  266. }
  267. double CDelaunayDoc::S(int p1, int p2, int p3)
  268. {
  269. //求三角形面积,以右下角为原点时,s>0为逆时针(左转),
  270. //s=0为三点重合
  271. double s;
  272. //POI m_p1,m_p2,m_p3;
  273. CPointPos *m_p1=new CPointPos(m_point[p1]->m_x,m_point[p1]->m_y);
  274.     CPointPos *m_p2=new CPointPos(m_point[p2]->m_x,m_point[p2]->m_y);
  275.     CPointPos *m_p3=new CPointPos(m_point[p3]->m_x,m_point[p3]->m_y);
  276. s=m_p1->m_x*m_p2->m_y+m_p2->m_x*m_p3->m_y+m_p1->m_y*
  277. m_p3->m_x-m_p2->m_y*m_p3->m_x-m_p1->m_y*m_p2->m_x-m_p1->m_x*m_p3->m_y;
  278. s=s/2;
  279. delete m_p1;
  280. delete m_p2;
  281. delete m_p3;
  282. return s;
  283. }
  284. int CDelaunayDoc::TwoEdgeSuperposition(CBorder *b1, CBorder *b2)
  285. {
  286. if(b1==b2 || (b1->m_p1==b2->m_p2 && b1->m_p2==b2->m_p1) ) return 1;
  287. return 0;
  288. }
  289. int CDelaunayDoc::GetInitEdges(double x, double y, int p)
  290. {
  291. // GetInitEdges : ransack each trangle to record it's edges
  292. //when the piont belong it's circle,record the triangle's position in m_tri to m_index
  293. //'x' and 'y' are the coordinates of the insert point
  294. //'p' is the mark or th insert point in 'm_point'
  295. // the returned value 'k/2' is the number of cirecle the point belonged
  296. POSITION POS;
  297. CBorder *m_border;
  298. CBorder *m_border1;
  299. CTriangle* pTriangle;
  300. int j=0,i=0,k=0,max=0;
  301. CPointPos *point=new CPointPos(x,y);
  302.     POS = m_tri.GetHeadPosition();
  303. while(POS != NULL ){
  304.        i= m_tri.GetAt( POS )->Where(point);
  305.    
  306.    if(i==POS_ERROR){
  307.    return POS_ERROR;
  308.    }
  309.    if(i==POS_ON)//in circle POS_ON=2
  310.    {
  311.   k=k+i;
  312.   m_index.Add(POS);
  313.   pTriangle=m_tri.GetAt(POS);
  314.   //ransack three edge of a triangle,if an edge of a triangle
  315.   //have belong to the array 'm_pDoc->m_edge' delete both of them to form 
  316.   // the border of the inserted polygon which is stored in the array
  317.   //'m_pDoc->m_edge'
  318.   int array[4];
  319.   array[0]=pTriangle->m_p1;
  320.   array[1]=pTriangle->m_p2;
  321.   array[2]=pTriangle->m_p3;
  322.   array[3]=pTriangle->m_p1;
  323.           for(int h=0;h<3;h++)
  324.   {   
  325.  m_border=new CBorder(array[h],array[h+1]);
  326.  max=m_edge.GetSize();
  327.  if(max==0)
  328.  {
  329.                 m_edge.Add(m_border);
  330.  }
  331.  else
  332.  {
  333.     j=0;
  334.     for(int m=0;m<max;m++)
  335. {             
  336.    m_border1=m_edge[m];
  337.    if(TwoEdgeSuperposition(m_border,m_border1)==1)//?//???
  338.    {
  339.       m_edge.RemoveAt(m,1);
  340.   max=max-1;
  341.   j++;
  342.    }
  343. }
  344.     if(j==0)
  345. {
  346.                    m_edge.Add(m_border);
  347. }     
  348. }  
  349.   }/////for
  350.    }/////////////if(POS_ON)
  351.      pTriangle=m_tri.GetNext(POS);
  352. }//////////////while 
  353. //if(k==0)//the point don't belong any circle,
  354. //i.e.don't the convexity
  355. delete point;
  356. return k;
  357. }
  358. void CDelaunayDoc::DelTriMarked()
  359. {
  360.    int max=m_index.GetSize();
  361.    for(int i=0;i<max;i++)
  362.    {
  363.   m_tri.RemoveAt(m_index[i]);
  364.    }
  365. }
  366. void CDelaunayDoc::EditCon(int r, int l,int p)
  367. {
  368. // r : save the value of i as 右支撑点 or 应去凸包边界节点右边界   
  369. // l : save the value of i as 左支撑点 or 应去凸包边界节点左边界
  370. //'p' is the mark or th insert point in 'm_point'
  371.  CBorder *m_border;
  372.      int hr=0;//record the number of points on edge of convexity that should be deleted before r(include r) 
  373.  int hl=0;//record the number of points on edge of convexity that should be deleted after l(include l)
  374.  int i=r;
  375.  int i1;
  376.  int h=hr+hl;
  377.  int max=m_con.GetSize();
  378.  //search rightward, first
  379.  if((i+1)>max-1)  i1=i+1-max;  
  380.  else             i1=i+1;
  381.  while(S(p,m_con[i],m_con[i1])<0){                  
  382. m_border=new CBorder(m_con[i],m_con[i1]);
  383. m_edge.Add(m_border);
  384. r=i;
  385.             i++;
  386. hr++;
  387. if(i+1>max-1) i1=i+1-max;
  388. else         i1=i+1;
  389. if(i>max-1)     i=i-max;
  390. }
  391. i=l;
  392.     if((i-1)<0) i1=i-1+max;
  393. else        i1=i-1;
  394. while(S(m_con[i1],m_con[i],p)<0){
  395.     m_border=new CBorder(m_con[i],m_con[i1]);
  396. m_edge.Add(m_border);
  397. l=i;
  398. i--;
  399. hl++;
  400. if(i-1<0) i1=i-1+max;
  401. else      i1=i-1;
  402. if(i<0)   i=i+max;
  403. }
  404. h=hr+hl;
  405. if(h>0){
  406.        if(r<l){
  407.        if(hl>0){
  408.   if(hr>0){//both>0
  409.       m_con.RemoveAt(l,max-l);
  410.                   m_con.RemoveAt(0,hr);
  411.   }                            
  412.   else{//hl>0,hr=0
  413.       m_con.RemoveAt(l,max-l);
  414.       m_con.RemoveAt(0,hl-max+l);
  415.   }
  416.           m_con.InsertAt(0,p);                           
  417.   }//end if hl>0
  418.   else{//hl=0,hr>0         
  419.    m_con.RemoveAt(0,hr);
  420.        m_con.InsertAt(0,p);
  421.   }
  422. }//end if r<l
  423. else{//r>l
  424. if(hl>0){
  425.     m_con.RemoveAt(l,h);
  426.         m_con.InsertAt(l,p);                           
  427. }//end if hl>0
  428. else{//hl=0,hr>0         
  429.  m_con.RemoveAt(l+1,hr);
  430.      m_con.InsertAt(l+1,p);
  431. }
  432. }//end if r>l
  433. }//end if h>0
  434. else
  435. {
  436. if((r-l)>0){
  437.      if((r-l)==1) m_con.InsertAt(r,p);
  438.      else{
  439.  m_con.RemoveAt(l+1,r-l-1);
  440.  m_con.InsertAt(l+1,p);                  
  441.  }
  442. }
  443. else{//r<l,i.e. r and l 在 m_con[0] 两侧
  444. if(l<(max-1)) m_con.RemoveAt(l+1,max-l-1);
  445.             m_con.RemoveAt(0,r);
  446. m_con.InsertAt(0,p);       
  447. }
  448. }//h<0             
  449. }
  450. CPointPos* CDelaunayDoc::IntersectionPoint(CPointPos *point1, CPointPos *point2,CPointPos *point3, CPointPos *point4)
  451. {
  452. ASSERT(point1!=NULL);
  453.     ASSERT(point2!=NULL);
  454. ASSERT(point3!=NULL);
  455.     ASSERT(point4!=NULL);
  456.     CPointPos *pos=new CPointPos(0,0);
  457. double k21,k43;
  458. if((point2->m_x-point1->m_x)==0 || (point4->m_x-point3->m_x)==0)
  459. {
  460. if((point2->m_x-point1->m_x)==0 && (point4->m_x-point3->m_x)==0) return NULL;
  461. if((point2->m_x-point1->m_x)==0){
  462. k43=(point4->m_y-point3->m_y)/(point4->m_x-point3->m_x);
  463.             pos->m_x=point1->m_x;// x of the intersection point
  464.             pos->m_y=k43*(pos->m_x-point3->m_x)+point3->m_y;// y of the intersection point
  465.     return pos;
  466. }
  467. if((point4->m_x-point3->m_x)==0){
  468. k21=(point2->m_y-point1->m_y)/(point2->m_x-point1->m_x);
  469.             pos->m_x=point3->m_x;// x of the intersection point
  470.             pos->m_y=k21*(pos->m_x-point1->m_x)+point1->m_y;// y of the intersection point
  471.     return pos;
  472. }
  473. }
  474. else
  475. {
  476. k43=(point4->m_y-point3->m_y)/(point4->m_x-point3->m_x);
  477.         k21=(point2->m_y-point1->m_y)/(point2->m_x-point1->m_x);
  478. if(fabs(k43-k21)<0.0000000001) 
  479. return NULL;
  480. else{
  481. pos->m_x=(point3->m_y-point1->m_y+k21*point1->m_x-k43*point3->m_x)/(k21-k43);
  482.             pos->m_y=k43*(pos->m_x-point3->m_x)+point3->m_y;
  483. return pos;
  484. }
  485. }       
  486. }
  487. int CDelaunayDoc::TheOtherPoint(int p1, int p2, CTriangle *temp)
  488. {//p1,p2 are the mark recorded by m_tri in m_point
  489. int array[3];
  490. double s;
  491. array[0]=temp->m_p1;
  492. array[1]=temp->m_p2;
  493. array[2]=temp->m_p3;
  494. for(int i=0;i<3;i++)
  495. {
  496. s=S(array[i],p1,p2);
  497. if(fabs(s)>0.00000000001) return array[i];
  498. }
  499. }
  500. bool CDelaunayDoc::DelEdgeOrNot(int p1, int p2,int p)
  501. {
  502.    CTriangle* pTriangle;
  503.    //p1=m_pDoc->m_edge[j]->m_p1,record the point's mark in m_point
  504.    //p2=m_pDoc->m_edge[j]->m_p2,record the point's mark in m_point
  505.    int i,j;
  506.    for(i=0;i<m_index.GetSize();i++)
  507.    {
  508.    pTriangle=m_tri.GetAt(m_index[i]);
  509.    int array[3];
  510.    array[0]=pTriangle->m_p1;
  511.    array[1]=pTriangle->m_p2;
  512.    array[2]=pTriangle->m_p3;   
  513.    int a=-1,b=-1;
  514.    for(j=0;j<3;j++)
  515.    {
  516.    if(p1==array[j]) a=j;
  517.    }
  518.     for(j=0;j<3;j++)
  519.    {
  520.    if(p2==array[j]) b=j;
  521.    }
  522.        if((a>=0) & (b>=0))
  523.    {
  524.    int other_point=TheOtherPoint(p1,p2,pTriangle);
  525.    CPointPos* pPoint=IntersectionPoint(m_point[p1],m_point[p2],
  526.                       m_point[p],m_point[other_point]);
  527.    if(pTriangle->Where(pPoint)==POS_ON){//整数截断使交点在边外
  528.    return true;
  529.    }
  530.    }
  531.    }
  532.    return false;
  533. }
  534.  double CDelaunayDoc::S(CPointPos *p1,CPointPos *p2,CPointPos *p3)
  535.  {
  536.   //求三角形面积,以右下角为原点时,s>0为逆时针(左转),
  537.    //s=0为三点重合
  538.    double s;
  539.    s=p1->m_x*p2->m_y+p2->m_x*p3->m_y+p1->m_y*p3->m_x-
  540. p2->m_y*p3->m_x-p1->m_y*p2->m_x-p1->m_x*p3->m_y;
  541.    s=s/2.0;
  542.    return s;
  543.  }
  544. void CDelaunayDoc::OnButtonBB() 
  545. {
  546. m_DoWhat=DO_INTERPOLATION;
  547. int max=m_point.GetSize();
  548. for(int i=0;i<max;i++)
  549. {
  550. FindRelativeTri(i);//get Fx,Fy,N of a point in m_point
  551. }
  552. POSITION POS;CTriangle* temp;
  553. POS = m_tri.GetHeadPosition();
  554. temp=m_tri.GetAt(POS);
  555. while(POS != NULL ){
  556. temp=m_tri.GetNext(POS);
  557. double d;
  558. int p[4];p[0]=0;
  559.     p[1]=temp->m_p1;p[2]=temp->m_p2;p[3]=temp->m_p3;
  560. //////////////////////////////////////////////////////////////////////////
  561. //Get 6个 dij 计算无错 但沿边接的方向倒数的估算可能有问题,
  562. //1)可能不应单位化.2)?
  563. d=D(temp,2,3);
  564. temp->d12=m_point[p[2]]->m_z+d/double(3);
  565. d=D(temp,3,2);
  566. temp->d13=m_point[p[3]]->m_z+d/double(3);
  567.         
  568. d=D(temp,1,3);
  569. temp->d21=m_point[p[1]]->m_z+d/double(3);
  570.         
  571. d=D(temp,3,1);
  572. temp->d23=m_point[p[3]]->m_z+d/double(3);
  573. d=D(temp,1,2);
  574. temp->d31=m_point[p[1]]->m_z+d/double(3);
  575.         d=D(temp,2,1);
  576. temp->d32=m_point[p[2]]->m_z+d/double(3);
  577. //////////////////////////////////////////////////////////////////////////
  578. //计算无错
  579.         temp->c1=(temp->d21+temp->d31+m_point[p[1]]->m_z)/double(3);
  580. temp->c2=(temp->d12+temp->d32+m_point[p[2]]->m_z)/double(3);
  581. temp->c3=(temp->d13+temp->d23+m_point[p[3]]->m_z)/double(3);
  582. //////////////////////////////////////////////////////////////////////////
  583. /*Get 每边中点处f的法向导数值(XY平面上的) 
  584. 在这边的两顶点间对顶点的法向导数做插值
  585.  顶点的法向导数由该点的Fx,Fy取得,*/     
  586. temp->n1=F(temp,3,2);//计算无错
  587. temp->n2=F(temp,1,3);
  588. temp->n3=F(temp,2,1);
  589. //////////////////////////////////////////////////////////////////////////
  590. /*Get bi and b0(o), 220页公式(5.48) 应再推几遍.HCT 和 三角形面积 都用的是
  591. XY平面上的?????3维的又如何????*///计算无错
  592. CPointPos* h1;
  593. CPointPos* h2;
  594. CPointPos* h3;
  595. //三角形o,f2,f3
  596.         h1=GetChuiZu(temp->m_x,temp->m_y,m_point[p[2]],m_point[p[3]]);
  597. //三角形o,f3,f1
  598. h2=GetChuiZu(temp->m_x,temp->m_y,m_point[p[3]],m_point[p[1]]);
  599. //三角形o,f1,f2
  600. h3=GetChuiZu(temp->m_x,temp->m_y,m_point[p[1]],m_point[p[2]]);
  601. CPointPos* o=new CPointPos();//重心
  602. o->m_x=temp->m_x;
  603. o->m_y=temp->m_y;
  604. o->m_z=0;
  605. double s1=S(o,m_point[p[2]],m_point[p[3]]);
  606. double s2=S(o,m_point[p[3]],m_point[p[1]]);
  607. double s3=S(o,m_point[p[1]],m_point[p[2]]);
  608. temp->b1=S(o,m_point[p[3]],h2)/s2
  609.         *(m_point[p[1]]->m_z+temp->d21-temp->d23-m_point[p[3]]->m_z)+
  610.         S(o,m_point[p[1]],h3)/s3
  611.         *(m_point[p[2]]->m_z+temp->d32-temp->d31-m_point[p[1]]->m_z)-
  612. (temp->n3+temp->n2)/double(0.75)-temp->c3-temp->c2+
  613. m_point[p[1]]->m_z+m_point[p[3]]->m_z+temp->d21+temp->d32+(temp->d31+temp->d23)*
  614. double(2);
  615. temp->b1=temp->b1/double(6);
  616. temp->b2=S(o,m_point[p[2]],h1)/s1
  617.         *(m_point[p[3]]->m_z+temp->d13-temp->d12-m_point[p[2]]->m_z)+
  618.         S(o,m_point[p[1]],h3)/s3
  619.         *(m_point[p[2]]->m_z+temp->d32-temp->d31-m_point[p[1]]->m_z)-
  620. (temp->n3+temp->n1)/double(0.75)-temp->c3-temp->c1+
  621. m_point[p[1]]->m_z+m_point[p[2]]->m_z+temp->d32+temp->d13+(temp->d31+temp->d12)*
  622. double(2);
  623. temp->b2=temp->b2/double(6);
  624. temp->b3=S(o,m_point[p[2]],h1)/s1
  625.         *(m_point[p[3]]->m_z+temp->d13-temp->d12-m_point[p[2]]->m_z)+
  626.         S(o,m_point[p[3]],h2)/s2
  627.         *(m_point[p[1]]->m_z+temp->d21-temp->d23-m_point[p[3]]->m_z)-
  628. (temp->n1+temp->n2)/double(0.75)-temp->c1-temp->c2+
  629. m_point[p[2]]->m_z+m_point[p[3]]->m_z+temp->d13+temp->d21+(temp->d12+temp->d23)*
  630. double(2);
  631. temp->b3=temp->b3/double(6);
  632. delete o;
  633. temp->o=(temp->b1+temp->b2+temp->b3)/double(3);
  634. //////////////////////////////////////////////////////////////////////////
  635.        //Get ei//计算无错
  636.        temp->e1=double(3)*(-temp->b1+temp->b2+temp->b3)-(-temp->c1+temp->c2+temp->c3);
  637.    temp->e1=temp->e1/double(2);
  638.    temp->e2=double(3)*(temp->b1-temp->b2+temp->b3)-(temp->c1-temp->c2+temp->c3);
  639.    temp->e2=temp->e2/double(2);
  640.    temp->e3=double(3)*(temp->b1+temp->b2-temp->b3)-(temp->c1+temp->c2-temp->c3);
  641.    temp->e3=temp->e3/double(2);
  642. //////////////////////////////////////////////////////////////////////////
  643.    //NOW we have got the 19 control points in a triangle
  644. //       temp=m_tri.GetNext(POS);
  645.    delete h1;
  646.    delete h2;
  647.    delete h3;
  648. }   
  649. }
  650. void CDelaunayDoc::OnUpdateButtonBB(CCmdUI* pCmdUI) 
  651. {
  652. if(m_DoWhat==DO_INTERPOLATION)
  653. pCmdUI->SetCheck(1);
  654. else 
  655. pCmdUI->SetCheck(0);
  656. }
  657. void CDelaunayDoc::FindRelativeTri(int p)
  658. {
  659. CPointPos *point;
  660.     point=m_point[p];
  661. POSITION POS;
  662.     POS = m_tri.GetHeadPosition();
  663. while(POS != NULL ){
  664.   int array[3];
  665.   array[0]= m_tri.GetAt(POS)->m_p1;
  666.   array[1]= m_tri.GetAt(POS)->m_p2;
  667.   array[2]= m_tri.GetAt(POS)->m_p3;
  668.           for(int h=0;h<3;h++)
  669.   {     
  670.  if(point==m_point[array[h]])
  671.  {
  672.                 m_index.Add(POS);
  673.  }
  674.   }/////for
  675.       m_tri.GetNext(POS);
  676. }//////////////while 
  677. Get_Fx_Fy_N(p);
  678. }
  679. POI CDelaunayDoc::GetTriNormal(CTriangle *temp)
  680. {//得到三角片的单位法向
  681. POI a,b,n;
  682. int p1,p2,p3;
  683.     p1=temp->m_p1;
  684.     p2=temp->m_p2;
  685.     p3=temp->m_p3;
  686. a.x=m_point[p2]->m_x-m_point[p1]->m_x;
  687. a.y=m_point[p2]->m_y-m_point[p1]->m_y;
  688. a.z=m_point[p2]->m_z-m_point[p1]->m_z;
  689. b.x=m_point[p3]->m_x-m_point[p1]->m_x;
  690. b.y=m_point[p3]->m_y-m_point[p1]->m_y;
  691. b.z=m_point[p3]->m_z-m_point[p1]->m_z;
  692.     //get the normal n=a*b(外积)
  693. n=VectorProduct(a.x,a.y,a.z,b.x,b.y,b.z);
  694. //单位化 normal
  695. n=Unitization(n);
  696.     return n;
  697. }
  698. double CDelaunayDoc::GetDistance(CPointPos* p1, CPointPos* p2)
  699. {
  700. double distance;
  701. distance=(p1->m_x-p2->m_x)*(p1->m_x-p2->m_x)+
  702.      (p1->m_y-p2->m_y)*(p1->m_y-p2->m_y)+
  703.              (p1->m_z-p2->m_z)*(p1->m_z-p2->m_z);
  704. distance=sqrt(distance);
  705. return distance;
  706. }
  707. POI CDelaunayDoc::VectorProduct(double x1,double y1,double z1,double x2,double y2,double z2)
  708. {//get p1*p2(外积) 对!!!!
  709. POI product;
  710. product.x=y1*z2-z1*y2;
  711. product.y=z1*x2-x1*z2;
  712. product.z=x1*y2-y1*x2;
  713. return product;
  714. }
  715. POI CDelaunayDoc::Unitization(POI p)
  716. { //单位化 对!!!!
  717. double m;
  718. m=p.x*p.x+p.y*p.y+p.z*p.z;
  719. m=sqrt(m);
  720. p.x=p.x/m;
  721. p.y=p.y/m;
  722. p.z=p.z/m;
  723.     return p;
  724. }
  725. double CDelaunayDoc::DotProduction(double x1,double y1,double z1,double x2,double y2,double z2)
  726. {//(x1,y1,z1)(内积)(x2,y2,z2)
  727. double product;
  728.     product=x1*x2+y1*y2+z1*z2;
  729.     return product;
  730. }
  731. void CDelaunayDoc::Get_Fx_Fy_N(int p)
  732. {/*本处计算无错,但型值点法向没用,因算得是Fx and Fy,
  733. 然后用 Fx and Fy 在 xy 平面上沿边的方向计算方向倒数
  734. 没用型值点法向做沿空间三角形边的方向倒数:
  735.       D(i,i+1)=(Pi+1-Pi)-[(Pi+1-Pi)Ni]Ni
  736.   D(i,i+2)=(Pi+2-Pi)-[(Pi+2-Pi)Ni]Ni
  737. */
  738.    CPointPos *point;
  739.    point=m_point[p];
  740.    int max=m_index.GetSize();
  741.    double Fx=0;//点的x偏导
  742.    double Fy=0;
  743.   // POI n;//点的法向量
  744.   //n.x=0;n.y=0;n.z=0;
  745.    double w=0.0;//Little法
  746.    for(int i=0;i<max;i++)
  747.    {
  748.   CArray<double,double> a;//save 三角片所在平面的方程ax+by+cz+d=0的a 
  749.   CArray<double,double> b;//save 三角片所在平面的方程ax+by+cz+d=0的b
  750.   CArray<double,double> c;//save 三角片所在平面的方程ax+by+cz+d=0的c
  751.   int array[3];
  752.   CTriangle* Tri;
  753.   Tri=m_tri.GetAt(m_index[i]);
  754.   array[0]= Tri->m_p1;
  755.   array[1]= Tri->m_p2;
  756.   array[2]= Tri->m_p3;
  757.   //a,b,c 计算无错 对!!!!
  758.       a.SetAtGrow(i,(m_point[array[1]]->m_y-m_point[array[0]]->m_y)*
  759.    (m_point[array[2]]->m_z-m_point[array[0]]->m_z)-
  760.    (m_point[array[1]]->m_z-m_point[array[0]]->m_z)*
  761.    (m_point[array[2]]->m_y-m_point[array[0]]->m_y));
  762.   b.SetAtGrow(i,(m_point[array[1]]->m_z-m_point[array[0]]->m_z)*
  763.    (m_point[array[2]]->m_x-m_point[array[0]]->m_x)-
  764.    (m_point[array[1]]->m_x-m_point[array[0]]->m_x)*
  765.    (m_point[array[2]]->m_z-m_point[array[0]]->m_z));
  766.   c.SetAtGrow(i,(m_point[array[1]]->m_x-m_point[array[0]]->m_x)*
  767.    (m_point[array[2]]->m_y-m_point[array[0]]->m_y)-
  768.    (m_point[array[1]]->m_y-m_point[array[0]]->m_y)*
  769.    (m_point[array[2]]->m_x-m_point[array[0]]->m_x));
  770.   
  771.   CArray<CPointPos*,CPointPos*> P;
  772.   double l1,l2;   
  773.       for(int h=0;h<3;h++)
  774.   {     
  775.  if(point!=m_point[array[h]])
  776.  {
  777.             P.Add(m_point[array[h]]);
  778.  }
  779.   }/////for
  780.   l1=GetDistance(point,P[0]);
  781.   l2=GetDistance(point,P[1]);
  782.   P.RemoveAll();////????
  783.   l1=l1*l1;
  784.   l2=l2*l2;
  785.       w=w+double(1)/(l1*l2);//w ,Fx,Fy and n have been 初始化了 =0  
  786.   /*n.x=n.x+GetTriNormal(Tri).x/(l1*l2);
  787.   n.y=n.y+GetTriNormal(Tri).y/(l1*l2);
  788.   n.z=n.z+GetTriNormal(Tri).z/(l1*l2);*/
  789.   Fx=(-a[i]/c[i])/(l1*l2)+Fx;Fy=(-b[i]/c[i])/(l1*l2)+Fy;
  790.    }
  791.    /*m_point[p]->nx=n.x/w;///?????nx,ny,nz 有用吗
  792.    m_point[p]->ny=n.y/w;
  793.    m_point[p]->nz=n.z/w;*/
  794.    m_point[p]->Fx=Fx/w;m_point[p]->Fy=Fy/w;
  795.    m_index.RemoveAll();
  796. }
  797. void CDelaunayDoc::BaryCenter(CTriangle *temp)
  798. {//三角形重心
  799. ASSERT(temp!=NULL);
  800. int p1,p2,p3;
  801. p1=temp->m_p1;
  802. p2=temp->m_p2;
  803. p3=temp->m_p3;   
  804. CPointPos* p11=m_point[p1];
  805. CPointPos* p22=m_point[p2];
  806. CPointPos* p33=m_point[p3];
  807. temp->m_x=(p11->m_x+p22->m_x +p33->m_x )/double(3);
  808. temp->m_y=(p11->m_y+p22->m_y +p33->m_y )/double(3);
  809.     //temp->m_z=(p11->m_z+p22->m_z +p33->m_z )/double(3);
  810. }
  811. double CDelaunayDoc::GetMold(CPointPos *p)//取模
  812. {
  813. double m=0;
  814. m=p->m_x*p->m_x+p->m_y*p->m_y+p->m_z*p->m_z;
  815. m=sqrt(m);
  816. return m;
  817. }
  818. CPointPos* CDelaunayDoc::GetChuiZu(double x,double y, CPointPos* p2, CPointPos* p3)
  819. {//求 p1 对于p2和p3 的垂足.
  820. CPointPos* h=new CPointPos();
  821. double k23;
  822. if (p3->m_x-p2->m_x==0){
  823. h->m_x=p2->m_x;
  824. h->m_y=y;
  825. }
  826. else{
  827. k23=(p3->m_y-p2->m_y)/(p3->m_x-p2->m_x);
  828. if (k23==0){
  829. h->m_x=x;
  830. h->m_y=p2->m_y;
  831. }
  832. else{
  833.             h->m_x=(k23*k23*p2->m_x+x+(y-p2->m_y)*k23)/(1.0+k23*k23);
  834.             h->m_y=p2->m_y+k23*(h->m_x-p2->m_x);
  835. }
  836. }
  837. return h;
  838. }
  839. double CDelaunayDoc::D(CTriangle *temp, int i, int j)
  840. {//沿边方向导:i to j,用i点处的两个偏导Fx,Fy 和i to j 的边的方向上的单位矢量作内积
  841. int p[4];p[0]=0;
  842. p[1]=temp->m_p1;p[2]=temp->m_p2;p[3]=temp->m_p3;
  843. POI vector;
  844. double d;
  845. vector.x=m_point[p[j]]->m_x-m_point[p[i]]->m_x;
  846. vector.y=m_point[p[j]]->m_y-m_point[p[i]]->m_y;
  847.     vector=Unitization(vector);//要是单位化就错了
  848.     d=DotProduction(vector.x,vector.y,0,m_point[p[i]]->Fx,m_point[p[i]]->Fy,0);
  849. return d;
  850. }
  851. double CDelaunayDoc::F(CTriangle *temp, int i, int j)
  852. {//i to j,ij边上的法向导数
  853. int p[4];p[0]=0;
  854. p[1]=temp->m_p1;p[2]=temp->m_p2;p[3]=temp->m_p3;
  855. int h=TheOtherPoint(p[i],p[j],temp);
  856.     CPointPos* H=GetChuiZu(m_point[h]->m_x,m_point[h]->m_y,m_point[p[i]],m_point[p[j]]);
  857. POI n;
  858. n.x=H->m_x-m_point[h]->m_x;
  859. n.y=H->m_y-m_point[h]->m_y;
  860. n.z=0;
  861. //n=Unitization(n);//要是单位化就错了
  862. double n1,n2;
  863. n1=DotProduction(m_point[p[j]]->Fx,m_point[p[j]]->Fy,0,n.x,n.y,0);
  864. n2=DotProduction(m_point[p[i]]->Fx,m_point[p[i]]->Fy,0,n.x,n.y,0);
  865. delete H;
  866. return (n1+n2)/double(2);
  867. }
  868. void CDelaunayDoc::DrawTri(int m_p1,int m_p2,CTriangle *tri)
  869. {
  870. int i,j;
  871. POI p1,p2,o;
  872. p1.x=m_point[m_p1]->m_x;
  873. p1.y=m_point[m_p1]->m_y;
  874. p2.x=m_point[m_p2]->m_x;
  875. p2.y=m_point[m_p2]->m_y;
  876. o.x=tri->m_x;o.y=tri->m_y;
  877. int n;
  878. n=8;
  879. double x[8][8];
  880. double y[8][8];
  881. for(j=0;j<n;j++)
  882. {
  883. for(i=0;i<n-j;i++)
  884. {
  885. x[j][i]=p1.x+j*(p2.x-p1.x)/double(n-1)+
  886. i*(o.x+j*(p2.x-o.x)/double(n-1)-p1.x-j*(p2.x-p1.x)/double(n-1))
  887. /double(n-1-j);
  888. y[j][i]=p1.y+j*(p2.y-p1.y)/double(n-1)+
  889. i*(o.y+j*(p2.y-o.y)/double(n-1)-p1.y-j*(p2.y-p1.y)/double(n-1))
  890. /double(n-1-j);
  891. }
  892. }
  893. x[7][0]=p2.x;
  894. y[7][0]=p2.y;
  895.     for(j=0;j<n-1;j++)
  896. {
  897. for(i=0;i<n-j-1;i++)
  898. {
  899. //normal=GetTriNormal(m_hct[0],m_hct[1],m_hct[2]);
  900. //glNormal3d(normal.x,normal.y,normal.z);
  901. glBegin(GL_TRIANGLES);
  902.   glVertex3d(x[j][i],y[j][i],Bezier(x[j][i],y[j][i],m_p1,m_p2,tri));
  903.   glVertex3d(x[j+1][i],y[j+1][i],Bezier(x[j+1][i],y[j+1][i],m_p1,m_p2,tri));
  904.   glVertex3d(x[j][i+1],y[j][i+1],Bezier(x[j][i+1],y[j][i+1],m_p1,m_p2,tri));
  905. glEnd();
  906. }
  907. }
  908. for(j=1;j<n-1;j++)
  909. {
  910. for(i=0;i<n-j-1;i++)
  911. {
  912. //normal=GetTriNormal(m_hct[0],m_hct[1],m_hct[2]);
  913. //glNormal3d(normal.x,normal.y,normal.z);
  914. glBegin(GL_TRIANGLES);
  915.   glVertex3d(x[j][i],y[j][i],Bezier(x[j][i],y[j][i],m_p1,m_p2,tri));
  916.   glVertex3d(x[j][i+1],y[j][i+1],Bezier(x[j][i+1],y[j][i+1],m_p1,m_p2,tri));
  917.   glVertex3d(x[j-1][i+1],y[j-1][i+1],Bezier(x[j-1][i+1],y[j-1][i+1],m_p1,m_p2,tri)); 
  918. glEnd();
  919. }
  920. }
  921. /*
  922. for(j=1;j<n;j++)
  923. {
  924. for(i=0;i<n-j;i++)
  925. {
  926. glBegin(GL_LINES);
  927.   glVertex3d(x[j][i],y[j][i],Bezier(x[j][i],y[j][i],m_p1,m_p2,tri));
  928.   glVertex3d(x[j-1][i],y[j-1][i],Bezier(x[j-1][i],y[j-1][i],m_p1,m_p2,tri));
  929.   glVertex3d(x[j][i],y[j][i],Bezier(x[j][i],y[j][i],m_p1,m_p2,tri));
  930.   glVertex3d(x[j-1][i+1],y[j-1][i+1],Bezier(x[j-1][i+1],y[j-1][i+1],m_p1,m_p2,tri));
  931. glEnd();
  932. }
  933. }
  934. for(j=0;j<n-1;j++)
  935. {
  936. for(i=0;i<n-j-1;i++)
  937. {
  938. glBegin(GL_LINES);
  939.   glVertex3d(x[j][i],y[j][i],Bezier(x[j][i],y[j][i],m_p1,m_p2,tri));
  940.   glVertex3d(x[j][i+1],y[j][i+1],Bezier(x[j][i+1],y[j][i+1],m_p1,m_p2,tri));
  941. glEnd();
  942. }
  943. }
  944. */
  945. }
  946. double CDelaunayDoc::Bezier(double x, double y,int m_p1,int m_p2,CTriangle* tri)
  947. {
  948. //s1,s2,s3 : 面积坐标
  949. double s1,s2,s3,s;
  950. double b[4][4][4];
  951. POI p1,p2,o,p;
  952. p1.x=m_point[m_p1]->m_x;
  953. p1.y=m_point[m_p1]->m_y;
  954. p2.x=m_point[m_p2]->m_x;
  955. p2.y=m_point[m_p2]->m_y;
  956. o.x=tri->m_x;o.y=tri->m_y;
  957. p.x=x;p.y=y;
  958. s=S(o,p1,p2);
  959. s1=S(p,p1,p2)/s;
  960. s2=S(o,p,p2)/s;
  961. s3=S(o,p1,p)/s;
  962. if(fabs(s1)<0.000000000001) s1=0;
  963. if(fabs(s2)<0.000000000001) s2=0;
  964. if(fabs(s3)<0.000000000001) s3=0;
  965. int i,j,k;
  966. double B=0.0;
  967. b[0][0][3]=m_point[m_p2]->m_z;b[0][3][0]=m_point[m_p1]->m_z;b[3][0][0]=tri->o;
  968. if(m_p1==tri->m_p1)
  969. {
  970. b[1][1][1]=tri->e3;
  971. b[2][1][0]=tri->b1;b[1][2][0]=tri->c1;
  972. b[0][2][1]=tri->d31;b[0][1][2]=tri->d32;
  973. b[2][0][1]=tri->b2;b[1][0][2]=tri->c2;
  974. for(i=0;i<4;i++){
  975. for(j=0;j<=(3-i);j++){
  976. for(k=0;k<=(3-i-j);k++){
  977. if((i+j+k)==3){
  978. B=B+b[i][j][k]*double(6)/(Factorial(i)*Factorial(j)*Factorial(k))*
  979. Power(s1,i)*Power(s2,j)*Power(s3,k);
  980. }
  981. }
  982. }
  983. }
  984. }
  985. if(m_p1==tri->m_p2)
  986. {
  987. b[1][1][1]=tri->e1;
  988. b[2][1][0]=tri->b2;b[1][2][0]=tri->c2;
  989. b[0][2][1]=tri->d12;b[0][1][2]=tri->d13;
  990. b[2][0][1]=tri->b3;b[1][0][2]=tri->c3;
  991. for(i=0;i<4;i++){
  992. for(j=0;j<=(3-i);j++){
  993. for(k=0;k<=(3-i-j);k++){
  994. if((i+j+k)==3){
  995. B=B+b[i][j][k]*double(6)/(Factorial(i)*Factorial(j)*Factorial(k))*
  996. Power(s1,i)*Power(s2,j)*Power(s3,k);
  997. }
  998. }
  999. }
  1000. }
  1001. }
  1002. if(m_p1==tri->m_p3)
  1003. {
  1004. b[1][1][1]=tri->e2;
  1005. b[2][1][0]=tri->b3;b[1][2][0]=tri->c3;
  1006. b[0][2][1]=tri->d23;b[0][1][2]=tri->d21;
  1007. b[2][0][1]=tri->b1;b[1][0][2]=tri->c1;
  1008. for(i=0;i<4;i++){
  1009. for(j=0;j<=(3-i);j++){
  1010. for(k=0;k<=(3-i-j);k++){
  1011. if((i+j+k)==3){
  1012. B=B+b[i][j][k]*double(6)/(Factorial(i)*Factorial(j)*Factorial(k))*
  1013. Power(s1,i)*Power(s2,j)*Power(s3,k);
  1014. }
  1015. }
  1016. }
  1017. }
  1018. }
  1019. return B;
  1020. }
  1021. double CDelaunayDoc::S(POI p1, POI p2, POI p3)
  1022. {
  1023. //求三角形面积,以右下角为原点时,s>0为逆时针(左转),
  1024.    //s=0为三点重合
  1025.    double s;
  1026.    s=p1.x*p2.y+p2.x*p3.y+p1.y*p3.x-p2.y*p3.x-p1.y*p2.x-p1.x*p3.y;
  1027.    s=s/2.0;
  1028.    return s;
  1029. }
  1030. int CDelaunayDoc::Factorial(int n)
  1031. {//阶乘
  1032. int x=n;
  1033. if(n==0 ||n==1) 
  1034. return 1;
  1035. else{
  1036. for(int i=1;i<n;i++){
  1037. x=x*(n-i);
  1038. }
  1039. }
  1040.     return x;
  1041. }
  1042. double CDelaunayDoc::Power(double a, int e)
  1043. {
  1044. double x=1.0;
  1045. if(e==0){
  1046. return 1.0;
  1047. }
  1048. else{
  1049. if(a==0.0){
  1050. return 0.0;
  1051. }
  1052.         for(int i=1;i<=e;i++){
  1053. x=x*a;
  1054. }
  1055. }
  1056.     return x;
  1057. }
  1058. CTriangle* CDelaunayDoc::Belong(double x, double y)
  1059. {
  1060. CTriangle* tri;
  1061. POI p1,p2,p3,p;
  1062. p.x=x;p.y=y;
  1063. POSITION pos = m_tri.GetHeadPosition();
  1064. while( pos != NULL )
  1065. {
  1066.         tri=m_tri.GetAt( pos );
  1067. double s1,s2,s3;
  1068.     p1.x=m_point[tri->m_p1]->m_x;
  1069. p1.y=m_point[tri->m_p1]->m_y;
  1070. p2.x=m_point[tri->m_p2]->m_x;
  1071. p2.y=m_point[tri->m_p2]->m_y;
  1072.     p3.x=m_point[tri->m_p3]->m_x;
  1073. p3.y=m_point[tri->m_p3]->m_y;
  1074.     
  1075. s1=S(p,p1,p2);
  1076. s2=S(p,p2,p3);
  1077. s3=S(p,p3,p1);
  1078. if(s1>0 && s2>0 && s3>0)
  1079. return tri;
  1080. m_tri.GetNext( pos );
  1081. }
  1082.     return NULL;
  1083. }
  1084. int CDelaunayDoc::Belong(double x, double y, CTriangle *tri)
  1085. {
  1086. POI p1,p2,o,p;
  1087. p.x=x;p.y=y;
  1088. double s1,s2,s3;
  1089. o.x=tri->m_x;
  1090. o.y=tri->m_y;
  1091. int a[4];
  1092. a[0]=tri->m_p1;
  1093. a[1]=tri->m_p2;
  1094. a[2]=tri->m_p3;
  1095. a[3]=tri->m_p1;
  1096. for(int i=0;i<3;i++)
  1097. {
  1098. p1.x=m_point[a[i]]->m_x;
  1099. p1.y=m_point[a[i]]->m_y;
  1100. p2.x=m_point[a[i+1]]->m_x;
  1101. p2.y=m_point[a[i+1]]->m_y;
  1102. s1=S(p,o,p1);
  1103. s2=S(p,p1,p2);
  1104. s3=S(p,p2,o);
  1105. if(s1>0 && s2>0 && s3>0)
  1106.    return i;
  1107. }
  1108. }
  1109. void CDelaunayDoc::Wang()
  1110. {
  1111. int n=50;
  1112.     CTriangle* tri;
  1113. double x[60];
  1114. double y[60];
  1115. double z[60][60];
  1116. int i,j,what;
  1117. for(i=0;i<n;i++)
  1118. {
  1119. x[i]=double(i)/double(n);
  1120.     y[i]=double(i)/double(n);
  1121. }
  1122. for(i=0;i<n;i++)
  1123. {
  1124. for(j=0;j<n;j++)
  1125. {
  1126. tri=Belong(x[i],y[j]);
  1127. if(tri!=NULL)
  1128. {
  1129.    what=Belong(x[i],y[j],tri);
  1130.    switch(what)
  1131.    {
  1132.    case 0:
  1133.    z[i][j]=Bezier(x[i],y[j],tri->m_p1,tri->m_p2,tri);
  1134.    break;
  1135.    case 1:
  1136.    z[i][j]=Bezier(x[i],y[j],tri->m_p2,tri->m_p3,tri);
  1137.    break;
  1138.    default:
  1139.    z[i][j]=Bezier(x[i],y[j],tri->m_p3,tri->m_p1,tri);
  1140.    break;
  1141.    }
  1142.    //z[i][j]=z[i][j]-0.2;
  1143. }
  1144. else
  1145. z[i][j]=0;
  1146. }
  1147. }
  1148. for(i=0;i<n;i++)
  1149. {
  1150. for(j=0;j<n-1;j++)
  1151. {
  1152.     if((z[i][j]!=0) && (z[i][j+1]!=0))
  1153. {
  1154.    glBegin(GL_LINES);
  1155.  glVertex3d(x[i],y[j],z[i][j]);
  1156.  glVertex3d(x[i],y[j+1],z[i][j+1]);
  1157.    glEnd();
  1158. }
  1159. }
  1160. }
  1161. for(j=0;j<n;j++)
  1162. {
  1163. for(i=0;i<n-1;i++)
  1164. {
  1165. if((z[i][j]!=0) && (z[i+1][j]!=0))
  1166. {
  1167.    glBegin(GL_LINES);
  1168.     glVertex3d(x[i],y[j],z[i][j]);
  1169. glVertex3d(x[i+1],y[j],z[i+1][j]);
  1170.        glEnd();
  1171. }
  1172. }
  1173. }
  1174. }