TIN三角网的实现.docx
《TIN三角网的实现.docx》由会员分享,可在线阅读,更多相关《TIN三角网的实现.docx(32页珍藏版)》请在冰点文库上搜索。
TIN三角网的实现
#include"StdAfx.h"
#include"Mstruct.h"
#include"math.h"
CMstruct:
:
CMstruct(void)
{
}
~CMstruct(void)
//-----------------------------------------------------------------------------------------------------------------------
//Summary:
//LoadFile()
//Parameters:
//
//Returns:
//description:
//加载文件和数据的存储
boolCMstruct:
LoadFile()
////清空缓存数
m_Ps.clear();
m_Ts.clear();
m_Effective.clear();
m_Line.clear();
CStringfilename;
filename=Open();
if(filename!
=_T(""))
CStdioFilefile;
if(file.Open(filename,CFile:
modeRead))
CStringstr;
intiddata=0;
while(file.ReadString(str))
Pspsdata;
CStringarray[5];
intn=0;
inti=0;
//遇到分隔符时,返回以一个分隔符和这个之间的字符
for(;n!
=-1;i++)
array[i]=str.Tokenize(_T(","),n);
psdata.X=_wtof(array[0]);
psdata.Y=_wtof(array[1]);
if(array[2]==_T(""))
array[2]=_T("0.0");
psdata.Z=_wtof(array[2]);
psdata.ID=iddata;
m_Ps.push_back(psdata);
iddata++;
returntrue;
else
returnfalse;
//Open()
//通过通用对话框选择文件
CStringCMstruct:
Open()
CStringfileext;//文件扩展名
CStringfilepathname=_T("");
//下边为弹出对话框,选择要读取的文件
CFileDialogfpdlg(TRUE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,_T("(文件类型)(*.txt)|*.txt|(文件类型)(*.txt)|*.txt|所有文件(*.*)|*.*||"),NULL);
if(fpdlg.DoModal()==IDOK)
filename=fpdlg.GetFileName();
fileext=fpdlg.GetFileExt();//文件扩展名
filepathname=fpdlg.GetPathName();
returnfilepathname;
//ClosePoint(Pspsdata)
//Pspsdata点的数据对象
//id返回最近点的id
//找到该点的最近点
intCMstruct:
ClosePoint(Pspsdata)
floatd,dmin=0;
intidmin;
intm=0;
vector:
iteratorit=m_Ps.begin();
for(;it!
=m_Ps.end();it++)
//当遇到本身的点后,直接跳过去执行下一个循环
if((it->X==psdata.X)&&(it->Y==psdata.Y)&&(it->Z==psdata.Z))
continue;
d=sqrt(pow((it->X-psdata.X),2)+pow((it->Y-psdata.Y),2)+pow((it->Z-psdata.Z),2));
if(m==0)
idmin=it->ID;
dmin=d;
m=1;
if(d{dmin=d;idmin=it->ID;}}returnidmin;//返回最近点的id}//-----------------------------------------------------------------------------------------------------------------------//Summary://FirstClosePoint//Parameters://Pspsdata//Returns://最近点的ID//description://当插入点不在任何三角形内时找离他最近的数据点//-----------------------------------------------------------------------------------------------------------------------intCMstruct::FirstClosePoint(Pspsdata){floatd,dmin=0;intidmin;intm=0;vector::iteratorit=m_Ps.begin();for(;it!=m_Ps.end();it++){//当遇到本身的点后,直接跳过去执行下一个循环if((it->X==psdata.X)&&(it->Y==psdata.Y)&&(it->Z==psdata.Z)){continue;}d=sqrt(pow((it->X-psdata.X),2)+pow((it->Y-psdata.Y),2)/*+pow((it->Z-psdata.Z),2)*/);if(m==0){idmin=it->ID;dmin=d;m=1;}if(d{dmin=d;idmin=it->ID;}}returnidmin;//返回最近点的id}//-----------------------------------------------------------------------------------------------------------------------//Summary://CreateTin//Parameters:////Returns:////description://创建三维网格//-----------------------------------------------------------------------------------------------------------------------voidCMstruct::CreateTin(){intL=1;intK;Pspsdata;Tstsdata;tsdata.IB1=m_Ps.front().ID;tsdata.IB2=ClosePoint(m_Ps.front());//找到最近点并返回idpsdata=FindPt(tsdata.IB2);tsdata.IB3=EntClosePt(m_Ps.front(),psdata);m_Ts.push_back(tsdata);for(K=0;K!=L;K++)/*K为种子三角形的指针,L为当前三角形的指针,通过递归生成三角网,在K=L时结束。*/{Tsdts;inti=0;vector::iteratorit=m_Ts.begin();for(;it!=m_Ts.end();it++){if(K==i){dts.IB1=it->IB1;dts.IB2=it->IB2;dts.IB3=it->IB3;}i++;}if(m_Ts.size()==1){IsEffective(dts,1);if(m_Effective.size()>0)/*在1-2边新生成三角形,排除没有有效点的情况。*/{Tsnewts;//新的三角形数据newts.IB1=dts.IB1;newts.IB2=dts.IB2;Pspt1,pt2;pt1=FindPt(dts.IB1);pt2=FindPt(dts.IB2);newts.IB3=EntClosePt(pt1,pt2);if(IsRepeat(newts)){m_Ts.push_back(newts);L++;}}}IsEffective(dts,2);if(m_Effective.size()>0)/*在2-3边新生成三角形,排除没有有效点的情况。*/{Tsnewts;//新的三角形数据newts.IB1=dts.IB2;newts.IB2=dts.IB3;Pspt1,pt2;pt1=FindPt(dts.IB2);pt2=FindPt(dts.IB3);newts.IB3=EntClosePt(pt1,pt2);if(IsRepeat(newts)){m_Ts.push_back(newts);L++;}}IsEffective(dts,3);if(m_Effective.size()>0)/*在1-3边新生成三角形,排除没有有效点的情况。*/{Tsnewts;//新的三角形数据newts.IB1=dts.IB1;newts.IB2=dts.IB3;Pspt1,pt2;pt1=FindPt(dts.IB1);pt2=FindPt(dts.IB3);newts.IB3=EntClosePt(pt1,pt2);if(IsRepeat(newts)){m_Ts.push_back(newts);L++;}}}}//-----------------------------------------------------------------------------------------------------------------------//Summary://EntClosePt(Pspt1,Pspt2)//Parameters://Pspt1,Pspt2一边的起点和端点//Returns://id返回最近点的id//description://找到三角形一边的最近点//-----------------------------------------------------------------------------------------------------------------------intCMstruct::EntClosePt(Pspt1,Pspt2){intidmax;floatd1,d2,d3,s,C,Cmax=0;//判断是否已经构建出三角形if(m_Ts.empty()){vector::iteratorit=m_Ps.begin();for(;it!=m_Ps.end();it++){if(((it->X==pt1.X)&&(it->Y==pt1.Y)&&(it->Z==pt1.Z))||((it->X==pt2.X)&&(it->Y==pt2.Y)&&(it->Z==pt2.Z))){continue;}/*求三点连接的三边的长度*/d1=sqrt(pow((it->X-pt1.X),2)+pow((it->Y-pt1.Y),2)+pow((it->Z-pt1.Z),2));d2=sqrt(pow((it->X-pt2.X),2)+pow((it->Y-pt2.Y),2)+pow((it->Z-pt2.Z),2));d3=sqrt(pow((pt1.X-pt2.X),2)+pow((pt1.Y-pt2.Y),2)+pow((pt1.Z-pt2.Z),2));s=(d1*d1+d2*d2-d3*d3)/(2*d1*d2);if(s<1)C=acos(s);elseC=0;/*用arccos求角度*/if(C>Cmax)/*找最大角*/{Cmax=C;idmax=it->ID;}}returnidmax;}vector::iteratorit=m_Effective.begin();for(;it!=m_Effective.end();it++){if(((it->X==pt1.X)&&(it->Y==pt1.Y)&&(it->Z==pt1.Z))||((it->X==pt2.X)&&(it->Y==pt2.Y)&&(it->Z==pt1.Z))){continue;}/*求三点连接的三边的长度*/d1=sqrt(pow((it->X-pt1.X),2)+pow((it->Y-pt1.Y),2)+pow((it->Z-pt1.Z),2));d2=sqrt(pow((it->X-pt2.X),2)+pow((it->Y-pt2.Y),2)+pow((it->Z-pt2.Z),2));d3=sqrt(pow((pt1.X-pt2.X),2)+pow((pt1.Y-pt2.Y),2)+pow((pt1.Z-pt2.Z),2));s=(d1*d1+d2*d2-d3*d3)/(2*d1*d2);if(s<1)C=acos(s);elseC=0;/*用arccos求角度*/if(C>Cmax)/*找最大角*/{Cmax=C;idmax=it->ID;}}returnidmax;}//-----------------------------------------------------------------------------------------------------------------------//Summary://Draw()//Parameters:////Returns:////description://在屏幕上画出三角形网格//-----------------------------------------------------------------------------------------------------------------------voidCMstruct::Draw(){CreateTin();vector::iteratorit=m_Ts.begin();for(;it!=m_Ts.end();it++){Pspt1,pt2,pt3;boolf;pt1=FindPt(it->IB1);pt2=FindPt(it->IB2);pt3=FindPt(it->IB3);AcGePoint3dpoint1(pt1.X,pt1.Y,pt1.Z);AcGePoint3dpoint2(pt2.X,pt2.Y,pt2.Z);AcGePoint3dpoint3(pt3.X,pt3.Y,pt3.Z);AcDbLine*pline1=newAcDbLine;AcDbLine*pline2=newAcDbLine;AcDbLine*pline3=newAcDbLine;pline1->setStartPoint(point1);pline1->setEndPoint(point2);f=IsDrawed(it->IB1,it->IB2);if(f){linelidata;lidata.b1=it->IB1;lidata.b2=it->IB2;m_Line.push_back(lidata);HP::AppendAndClose(pline1);}else{deletepline1;pline1=NULL;}pline2->setStartPoint(point2);pline2->setEndPoint(point3);f=IsDrawed(it->IB2,it->IB3);if(f){linelidata;lidata.b1=it->IB2;lidata.b2=it->IB3;m_Line.push_back(lidata);HP::AppendAndClose(pline2);}else{deletepline2;pline2=NULL;}pline3->setStartPoint(point1);pline3->setEndPoint(point3);f=IsDrawed(it->IB1,it->IB3);if(f){linelidata;lidata.b1=it->IB1;lidata.b2=it->IB3;m_Line.push_back(lidata);HP::AppendAndClose(pline3);}else{deletepline3;pline3=NULL;}}}//-----------------------------------------------------------------------------------------------------------------------//Summary://IsEffective()//Parameters://intn选择条件//Returns:////description://找出各边有效点//-----------------------------------------------------------------------------------------------------------------------voidCMstruct::IsEffective(Tstsdata,intn){m_Effective.clear();//清空数据intp1,p2,p3;intm1,m2;
returnidmin;//返回最近点的id
//FirstClosePoint
//Pspsdata
//最近点的ID
//当插入点不在任何三角形内时找离他最近的数据点
FirstClosePoint(Pspsdata)
d=sqrt(pow((it->X-psdata.X),2)+pow((it->Y-psdata.Y),2)/*+pow((it->Z-psdata.Z),2)*/);
if(d{dmin=d;idmin=it->ID;}}returnidmin;//返回最近点的id}//-----------------------------------------------------------------------------------------------------------------------//Summary://CreateTin//Parameters:////Returns:////description://创建三维网格//-----------------------------------------------------------------------------------------------------------------------voidCMstruct::CreateTin(){intL=1;intK;Pspsdata;Tstsdata;tsdata.IB1=m_Ps.front().ID;tsdata.IB2=ClosePoint(m_Ps.front());//找到最近点并返回idpsdata=FindPt(tsdata.IB2);tsdata.IB3=EntClosePt(m_Ps.front(),psdata);m_Ts.push_back(tsdata);for(K=0;K!=L;K++)/*K为种子三角形的指针,L为当前三角形的指针,通过递归生成三角网,在K=L时结束。*/{Tsdts;inti=0;vector::iteratorit=m_Ts.begin();for(;it!=m_Ts.end();it++){if(K==i){dts.IB1=it->IB1;dts.IB2=it->IB2;dts.IB3=it->IB3;}i++;}if(m_Ts.size()==1){IsEffective(dts,1);if(m_Effective.size()>0)/*在1-2边新生成三角形,排除没有有效点的情况。*/{Tsnewts;//新的三角形数据newts.IB1=dts.IB1;newts.IB2=dts.IB2;Pspt1,pt2;pt1=FindPt(dts.IB1);pt2=FindPt(dts.IB2);newts.IB3=EntClosePt(pt1,pt2);if(IsRepeat(newts)){m_Ts.push_back(newts);L++;}}}IsEffective(dts,2);if(m_Effective.size()>0)/*在2-3边新生成三角形,排除没有有效点的情况。*/{Tsnewts;//新的三角形数据newts.IB1=dts.IB2;newts.IB2=dts.IB3;Pspt1,pt2;pt1=FindPt(dts.IB2);pt2=FindPt(dts.IB3);newts.IB3=EntClosePt(pt1,pt2);if(IsRepeat(newts)){m_Ts.push_back(newts);L++;}}IsEffective(dts,3);if(m_Effective.size()>0)/*在1-3边新生成三角形,排除没有有效点的情况。*/{Tsnewts;//新的三角形数据newts.IB1=dts.IB1;newts.IB2=dts.IB3;Pspt1,pt2;pt1=FindPt(dts.IB1);pt2=FindPt(dts.IB3);newts.IB3=EntClosePt(pt1,pt2);if(IsRepeat(newts)){m_Ts.push_back(newts);L++;}}}}//-----------------------------------------------------------------------------------------------------------------------//Summary://EntClosePt(Pspt1,Pspt2)//Parameters://Pspt1,Pspt2一边的起点和端点//Returns://id返回最近点的id//description://找到三角形一边的最近点//-----------------------------------------------------------------------------------------------------------------------intCMstruct::EntClosePt(Pspt1,Pspt2){intidmax;floatd1,d2,d3,s,C,Cmax=0;//判断是否已经构建出三角形if(m_Ts.empty()){vector::iteratorit=m_Ps.begin();for(;it!=m_Ps.end();it++){if(((it->X==pt1.X)&&(it->Y==pt1.Y)&&(it->Z==pt1.Z))||((it->X==pt2.X)&&(it->Y==pt2.Y)&&(it->Z==pt2.Z))){continue;}/*求三点连接的三边的长度*/d1=sqrt(pow((it->X-pt1.X),2)+pow((it->Y-pt1.Y),2)+pow((it->Z-pt1.Z),2));d2=sqrt(pow((it->X-pt2.X),2)+pow((it->Y-pt2.Y),2)+pow((it->Z-pt2.Z),2));d3=sqrt(pow((pt1.X-pt2.X),2)+pow((pt1.Y-pt2.Y),2)+pow((pt1.Z-pt2.Z),2));s=(d1*d1+d2*d2-d3*d3)/(2*d1*d2);if(s<1)C=acos(s);elseC=0;/*用arccos求角度*/if(C>Cmax)/*找最大角*/{Cmax=C;idmax=it->ID;}}returnidmax;}vector::iteratorit=m_Effective.begin();for(;it!=m_Effective.end();it++){if(((it->X==pt1.X)&&(it->Y==pt1.Y)&&(it->Z==pt1.Z))||((it->X==pt2.X)&&(it->Y==pt2.Y)&&(it->Z==pt1.Z))){continue;}/*求三点连接的三边的长度*/d1=sqrt(pow((it->X-pt1.X),2)+pow((it->Y-pt1.Y),2)+pow((it->Z-pt1.Z),2));d2=sqrt(pow((it->X-pt2.X),2)+pow((it->Y-pt2.Y),2)+pow((it->Z-pt2.Z),2));d3=sqrt(pow((pt1.X-pt2.X),2)+pow((pt1.Y-pt2.Y),2)+pow((pt1.Z-pt2.Z),2));s=(d1*d1+d2*d2-d3*d3)/(2*d1*d2);if(s<1)C=acos(s);elseC=0;/*用arccos求角度*/if(C>Cmax)/*找最大角*/{Cmax=C;idmax=it->ID;}}returnidmax;}//-----------------------------------------------------------------------------------------------------------------------//Summary://Draw()//Parameters:////Returns:////description://在屏幕上画出三角形网格//-----------------------------------------------------------------------------------------------------------------------voidCMstruct::Draw(){CreateTin();vector::iteratorit=m_Ts.begin();for(;it!=m_Ts.end();it++){Pspt1,pt2,pt3;boolf;pt1=FindPt(it->IB1);pt2=FindPt(it->IB2);pt3=FindPt(it->IB3);AcGePoint3dpoint1(pt1.X,pt1.Y,pt1.Z);AcGePoint3dpoint2(pt2.X,pt2.Y,pt2.Z);AcGePoint3dpoint3(pt3.X,pt3.Y,pt3.Z);AcDbLine*pline1=newAcDbLine;AcDbLine*pline2=newAcDbLine;AcDbLine*pline3=newAcDbLine;pline1->setStartPoint(point1);pline1->setEndPoint(point2);f=IsDrawed(it->IB1,it->IB2);if(f){linelidata;lidata.b1=it->IB1;lidata.b2=it->IB2;m_Line.push_back(lidata);HP::AppendAndClose(pline1);}else{deletepline1;pline1=NULL;}pline2->setStartPoint(point2);pline2->setEndPoint(point3);f=IsDrawed(it->IB2,it->IB3);if(f){linelidata;lidata.b1=it->IB2;lidata.b2=it->IB3;m_Line.push_back(lidata);HP::AppendAndClose(pline2);}else{deletepline2;pline2=NULL;}pline3->setStartPoint(point1);pline3->setEndPoint(point3);f=IsDrawed(it->IB1,it->IB3);if(f){linelidata;lidata.b1=it->IB1;lidata.b2=it->IB3;m_Line.push_back(lidata);HP::AppendAndClose(pline3);}else{deletepline3;pline3=NULL;}}}//-----------------------------------------------------------------------------------------------------------------------//Summary://IsEffective()//Parameters://intn选择条件//Returns:////description://找出各边有效点//-----------------------------------------------------------------------------------------------------------------------voidCMstruct::IsEffective(Tstsdata,intn){m_Effective.clear();//清空数据intp1,p2,p3;intm1,m2;
//CreateTin
//创建三维网格
voidCMstruct:
CreateTin()
intL=1;
intK;
Tstsdata;
tsdata.IB1=m_Ps.front().ID;
tsdata.IB2=ClosePoint(m_Ps.front());//找到最近点并返回id
psdata=FindPt(tsdata.IB2);
tsdata.IB3=EntClosePt(m_Ps.front(),psdata);
m_Ts.push_back(tsdata);
for(K=0;K!
=L;K++)/*K为种子三角形的指针,L为当前三角形的指针,通过递归生成三角网,在K=L时结束。
*/
Tsdts;
iteratorit=m_Ts.begin();
=m_Ts.end();it++)
if(K==i)
dts.IB1=it->IB1;
dts.IB2=it->IB2;
dts.IB3=it->IB3;
i++;
if(m_Ts.size()==1)
IsEffective(dts,1);
if(m_Effective.size()>0)/*在1-2边新生成三角形,排除没有有效点的情况。
Tsnewts;//新的三角形数据
newts.IB1=dts.IB1;
newts.IB2=dts.IB2;
Pspt1,pt2;
pt1=FindPt(dts.IB1);
pt2=FindPt(dts.IB2);
newts.IB3=EntClosePt(pt1,pt2);
if(IsRepeat(newts))
m_Ts.push_back(newts);
L++;
IsEffective(dts,2);
if(m_Effective.size()>0)/*在2-3边新生成三角形,排除没有有效点的情况。
newts.IB1=dts.IB2;
newts.IB2=dts.IB3;
pt1=FindPt(dts.IB2);
pt2=FindPt(dts.IB3);
IsEffective(dts,3);
if(m_Effective.size()>0)/*在1-3边新生成三角形,排除没有有效点的情况。
//EntClosePt(Pspt1,Pspt2)
//Pspt1,Pspt2一边的起点和端点
//找到三角形一边的最近点
EntClosePt(Pspt1,Pspt2)
intidmax;
floatd1,d2,d3,s,C,Cmax=0;
//判断是否已经构建出三角形
if(m_Ts.empty())
if(((it->X==pt1.X)&&(it->Y==pt1.Y)&&(it->Z==pt1.Z))||((it->X==pt2.X)&&(it->Y==pt2.Y)&&(it->Z==pt2.Z)))
/*求三点连接的三边的长度*/
d1=sqrt(pow((it->X-pt1.X),2)+pow((it->Y-pt1.Y),2)+pow((it->Z-pt1.Z),2));
d2=sqrt(pow((it->X-pt2.X),2)+pow((it->Y-pt2.Y),2)+pow((it->Z-pt2.Z),2));
d3=sqrt(pow((pt1.X-pt2.X),2)+pow((pt1.Y-pt2.Y),2)+pow((pt1.Z-pt2.Z),2));
s=(d1*d1+d2*d2-d3*d3)/(2*d1*d2);
if(s<1)C=acos(s);elseC=0;/*用arccos求角度*/
if(C>Cmax)/*找最大角*/
Cmax=C;
idmax=it->ID;
returnidmax;
iteratorit=m_Effective.begin();
=m_Effective.end();it++)
if(((it->X==pt1.X)&&(it->Y==pt1.Y)&&(it->Z==pt1.Z))||((it->X==pt2.X)&&(it->Y==pt2.Y)&&(it->Z==pt1.Z)))
//Draw()
//在屏幕上画出三角形网格
Draw()
CreateTin();
Pspt1,pt2,pt3;
boolf;
pt1=FindPt(it->IB1);
pt2=FindPt(it->IB2);
pt3=FindPt(it->IB3);
AcGePoint3dpoint1(pt1.X,pt1.Y,pt1.Z);
AcGePoint3dpoint2(pt2.X,pt2.Y,pt2.Z);
AcGePoint3dpoint3(pt3.X,pt3.Y,pt3.Z);
AcDbLine*pline1=newAcDbLine;
AcDbLine*pline2=newAcDbLine;
AcDbLine*pline3=newAcDbLine;
pline1->setStartPoint(point1);
pline1->setEndPoint(point2);
f=IsDrawed(it->IB1,it->IB2);
if(f)
linelidata;
lidata.b1=it->IB1;
lidata.b2=it->IB2;
m_Line.push_back(lidata);
HP:
AppendAndClose(pline1);
deletepline1;
pline1=NULL;
pline2->setStartPoint(point2);
pline2->setEndPoint(point3);
f=IsDrawed(it->IB2,it->IB3);
lidata.b1=it->IB2;
lidata.b2=it->IB3;
AppendAndClose(pline2);
deletepline2;
pline2=NULL;
pline3->setStartPoint(point1);
pline3->setEndPoint(point3);
f=IsDrawed(it->IB1,it->IB3);
AppendAndClose(pline3);
deletepline3;
pline3=NULL;
//IsEffective()
//intn选择条件
//找出各边有效点
IsEffective(Tstsdata,intn)
m_Effective.clear();//清空数据
intp1,p2,p3;
intm1,m2;
copyright@ 2008-2023 冰点文库 网站版权所有
经营许可证编号:鄂ICP备19020893号-2