OneContour.cpp
资源名称:08.zip [点击查看]
上传用户:ynjin1970
上传日期:2014-10-13
资源大小:6438k
文件大小:7k
源码类别:
中间件编程
开发平台:
Visual C++
- // Contour.cpp: implementation of the COneContour class.
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- //#include "ct.h"
- #include "OneContour.h"
- #include <math.h>
- #include "smooth.h"
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[]=__FILE__;
- #define new DEBUG_NEW
- #endif
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
- COneContour::COneContour(CTriangulate *T, double z)
- {
- this->T = T;
- zvalue = z;
- segsum_ = 0;
- epsilon = 0.0000001;
- }
- COneContour::~COneContour()
- {
- for (int i=0; i<segsum_; i++)
- {
- delete []points_[i];
- if ( this->smoothmethod_ > 0 )
- delete []afterpoints_[i];
- }
- }
- //////////////////////////////////////////////////////////////////
- //
- // 从指定的三角形集合中画等直线
- // 查找符合zvalue值的三角形并绘制等值线。。。
- //
- void COneContour::SearchZValuePointsOfTris()
- {
- int MAXPOINTS = 1000; // 搜索到的点的最大个数,会动态变化
- int MAXUSEDTRIS = 1000; // 记录UsedTris的最大个数,会动态变化
- int p1, p2, p3; // 三角形的三个点
- int end1, end2, end1_bak, end2_bak; // 三角形中有等值线通过的两个边
- double z1, z2, z3;
- bool *flag; // 三角形是否使用过的标记
- XYZ *pv = T->GetVertex(); // 散点数据
- int vcount = T->GetVertexCount();
- TRIANGLE *ptri = T->GetTriangle(); // 网格数据
- int tcount = T->GetTriangleCount();
- XYZ *tmpxyz; // 临时数据
- int FirstTri, InTri;
- double zbak; //zvalue是常量,不能加上一个epsilon,故用此变量
- bool HadSearched; //是否找到了合适的相邻三角形
- int i, j;
- double *dArrayZ;
- flag = new bool[tcount]; // 缺省情况为没有用过
- for (i =0; i< tcount; i++)
- flag[i] = false;
- //以前采用临时调整zvalue的方法,现在采用临时调整
- //数组z的方法.但仍然保留老的方法,因为,同时采用两个方法
- //并不冲突,后者会自然屏蔽前者方法.声明内部变量
- dArrayZ = new double[vcount];
- for(i=0; i<vcount; i++)
- {
- dArrayZ[i] = pv[i].z; //对成员变量数组z进行备份,然后在结束时恢复数组z
- if (pv[i].z == zvalue)
- pv[i].z += epsilon; //只在这个地方对Z进行了修改
- }
- // 从序号为FirstTri的三角形的哪一条边开始追踪...
- // 追踪到的第二个三角形序号,正在追踪的三角形序号。
- // 注意:
- // 如果一条边被两个三角形共享,因此,可以从两个方向来追踪下一个三角形。
- // secondTri用于反向追踪时作为其实三角形使用。
- HadSearched = false;
- for(i = 0; i < tcount; i++)
- {
- //TRACE("%dn", i);
- // 判断第i个三角形是否已经存在于已用过的三角形列表中?
- if ( flag[i] ) continue; //判断第i个三角形是否已用过
- zbak = zvalue;
- p1 = ptri[i].p1;
- p2 = ptri[i].p2;
- p3 = ptri[i].p3;
- z1 = pv[p1].z; // 三角形的三个顶点的Z值
- z2 = pv[p2].z;
- z3 = pv[p3].z;
- if (!( ((z1 - zbak) * (z2 - zbak) <= 0) || ((z3 - zbak) * (z2 - zbak) <= 0) ) )
- continue; // Z值没有落在此三角形(第i个三角形)内
- HadSearched = true;
- //找到了合适的三角形!!!
- //从第一号三角形开始查找满足条件的等值点
- points_[segsum_] = new XYZ[MAXPOINTS]; // 成员变量
- pointscount_[segsum_] = 0;
- if ((z1 - zbak) * (z2 - zbak) < 0)
- {
- end1 = p1;
- end2 = p2;
- if ((z1 -zbak) * (z3 - zbak) < 0)
- {
- end1_bak = p1;
- end2_bak = p3;
- }
- else
- {
- end1_bak = p2;
- end2_bak = p3;
- }
- }
- else
- {
- end1 = p3;
- end2 = p2;
- end1_bak = p1;
- end2_bak = p3;
- }
- points_[segsum_][pointscount_[segsum_]].x = (pv[end1_bak].x * (zbak - pv[end2_bak].z) + pv[end2_bak].x * (pv[end1_bak].z-zbak) ) / (pv[end1_bak].z - pv[end2_bak].z);
- points_[segsum_][pointscount_[segsum_]].y = (pv[end1_bak].y * (zbak - pv[end2_bak].z) + pv[end2_bak].y * (pv[end1_bak].z-zbak) ) / (pv[end1_bak].z - pv[end2_bak].z);
- pointscount_[segsum_]++;
- points_[segsum_][pointscount_[segsum_]].x = (pv[end1].x * (zbak - pv[end2].z) + pv[end2].x * (pv[end1].z-zbak) ) / (pv[end1].z - pv[end2].z);
- points_[segsum_][pointscount_[segsum_]].y = (pv[end1].y * (zbak - pv[end2].z) + pv[end2].y * (pv[end1].z-zbak) ) / (pv[end1].z - pv[end2].z);
- pointscount_[segsum_]++;
- FirstTri =i;
- InTri = i;
- // UsedTris[UsedTrisCount] = InTri; // "已用过"
- // UsedTrisCount++;
- flag[i] = true;
- //然后从临接三角形中再次查找满足条件的等值点
- for (j=0; j<2; j++) //只循环两次,一次为正向追踪,另外一次为反向追踪
- {
- while(1)
- {
- if ( end1 + end2 == ptri[InTri].p1 + ptri[InTri].p2 )
- InTri = ptri[InTri].t3;
- else if ( end1 + end2 == ptri[InTri].p3 + ptri[InTri].p2 )
- InTri = ptri[InTri].t1;
- else
- InTri = ptri[InTri].t2;
- if ( InTri < 0 || flag[InTri] )
- break; // 不存在邻接三角形,正向追踪无可用的下一个三角形,停止正向追踪
- p3 = ptri[InTri].p1 + ptri[InTri].p2 + ptri[InTri].p3 - end1 - end2;
- z1 = pv[end1].z;
- z3 = pv[p3].z;
- if (( z1 - zvalue ) * ( z3 - zvalue ) <= 0 )
- end2 = p3;
- else
- end1 = p3;
- flag[InTri] = true;
- // 增加等值点
- points_[segsum_][pointscount_[segsum_]].x = (pv[end1].x * (zbak-pv[end2].z) + pv[end2].x * (pv[end1].z-zbak))/(pv[end1].z-pv[end2].z);
- points_[segsum_][pointscount_[segsum_]].y = (pv[end1].y * (zbak-pv[end2].z) + pv[end2].y * (pv[end1].z-zbak))/(pv[end1].z-pv[end2].z);
- pointscount_[segsum_]++;
- ASSERT(pointscount_[segsum_] < 4000); //Debug....
- if ( pointscount_[segsum_] >= MAXPOINTS ) // 重新分配内存
- {
- tmpxyz = points_[segsum_];
- points_[segsum_] = new XYZ[MAXPOINTS + 1000];
- memcpy(points_[segsum_], tmpxyz, sizeof(XYZ) * MAXPOINTS);
- delete []tmpxyz;
- MAXPOINTS += 1000;
- }
- }
- if(j==0) //如果正向追踪完毕,则设置反向追踪条件,继续追踪
- {
- for(int k=0; k<(int)floor(pointscount_[segsum_]/2); k++) //倒序排列正向追踪过程中已经追踪到的点
- {
- XYZ tmpPoint = points_[segsum_][k];
- points_[segsum_][k] = points_[segsum_][pointscount_[segsum_]-1-k];
- points_[segsum_][pointscount_[segsum_]-1-k] = tmpPoint;
- }
- //反向追踪,下面三条语句是根据两点(一条边)及一个三角形,必然能找到与这条边共享的另一个三角形
- end1 = end1_bak;
- end2 = end2_bak;
- InTri = FirstTri;
- }
- } // End for j
- segsum_++;
- // ASSERT(segsum_ == 1);
- } // End for i
- // if (HadSearched == false)
- // AfxMessageBox("不能找到第一个点!");
- for(i=0; i<vcount; i++) //恢复数组z原来的值
- pv[i].z = dArrayZ[i];
- delete []dArrayZ;
- delete []flag;
- }//end function
- // 选择平滑方法,如果为0,则不平滑
- void COneContour::CreateContour()
- {
- SearchZValuePointsOfTris();
- if ( smoothmethod_ > 0 )
- {
- for ( int i = 0; i < segsum_; i++)
- {
- CSmooth s(points_[i], pointscount_[i]);
- s.Smooth();
- s.GetSmoothedPoints(&afterpoints_[i], afterpointscount_[i]);
- }
- }
- }
- void COneContour::Initial(CTriangulate *T, double z, int smoothmethod)
- {
- this->T = T;
- zvalue = z;
- smoothmethod_ = smoothmethod;
- }
- COneContour::COneContour()
- {
- segsum_ = 0;
- epsilon = 0.0000001;
- }
- XYZ ** COneContour::GetPoints()
- {
- return points_;
- }
- int * COneContour::GetPointsCount()
- {
- return pointscount_;
- }
- XYZ ** COneContour::GetAfterPoints()
- {
- return afterpoints_;
- }
- int * COneContour::GetAfterPointsCount()
- {
- return afterpointscount_;
- }
- double COneContour::GetZValue()
- {
- return zvalue;
- }
- int COneContour::GetSegCount()
- {
- return segsum_;
- }