标签:
剧情提要:[工程师阿伟]正在和[机器小伟]一起研究[星球战争 BC2699 至 BC2600(公元前27世纪)]。
神农氏来找阿伟闲聊,谈到他准备去攻打河北,那里有一个部落不服他。那个部落叫什么名字,
他没有说。可能名字神马的不是很重要吧。
然后神农氏叹了口气说,路途遥远,要想去那里必须要有车,我费了很多心思,花了高价,
才从黑市上买到两张车辆的制造图纸。对方还不附说明书,意思是让阿伟帮他参详一下。
阿伟点头同意,于是神农掏出了第一张图纸:
<span style="font-size:18px;">///D:/360极速浏览器下载/Bowyer_Watson/Bowyer_Watson/BowyerWatson.cpp #include "Point.h" #include "Line.h" #include "Triangle.h" #include "BowyerWatson.h" CBowyerWatson* CBowyerWatson::m_pBowyerWatson = NULL; CBowyerWatson::CBowyerWatson() { ClearBowyerWatson(); } CBowyerWatson::~CBowyerWatson() { ClearBowyerWatson(); } CBowyerWatson* CBowyerWatson::GetInstance() { if( !m_pBowyerWatson ) m_pBowyerWatson = new CBowyerWatson; return m_pBowyerWatson; } void CBowyerWatson::ClearBowyerWatson() { m_bUpdateDrawFlag = false; std::list<CPoint*>::iterator iter_point = m_lstBowyerWatsonPointList.begin(); while (iter_point != m_lstBowyerWatsonPointList.end()) { std::list<CPoint*>::iterator iter_pointNext = iter_point; iter_pointNext++; SAFE_DELETE(*iter_point); m_lstBowyerWatsonPointList.erase(iter_point); iter_point = iter_pointNext; }//Point std::list<CLine*>::iterator iter_line = m_lstBowyerWatsonLineList.begin(); while (iter_line != m_lstBowyerWatsonLineList.end()) { std::list<CLine*>::iterator iter_lineNext = iter_line; iter_lineNext++; SAFE_DELETE(*iter_line); m_lstBowyerWatsonLineList.erase(iter_line); iter_line = iter_lineNext; }//line std::list<CTriangle*>::iterator iter_triangle = m_lstBowyerWatsonTriangleList.begin(); while (iter_triangle != m_lstBowyerWatsonTriangleList.end()) { std::list<CTriangle*>::iterator iter_triangleNext = iter_triangle; iter_triangleNext++; SAFE_DELETE(*iter_triangle); m_lstBowyerWatsonTriangleList.erase(iter_triangle); iter_triangle = iter_triangleNext; }//Triangle iter_point = m_lstAddPointList.begin(); while (iter_point != m_lstAddPointList.end()) { std::list<CPoint*>::iterator iter_pointNext = iter_point; iter_pointNext++; SAFE_DELETE(*iter_point); m_lstAddPointList.erase(iter_point); iter_point = iter_pointNext; }//Point } void CBowyerWatson::CreateHelperPoint(CPoint pt1, CPoint pt2, CPoint pt3, CPoint pt4) { mHelperPoints[0] = pt1; mHelperPoints[1] = pt2; mHelperPoints[2] = pt3; mHelperPoints[3] = pt4; //加入辅助点4个 AddBowyerWatsonPoint(pt1); AddBowyerWatsonPoint(pt2); AddBowyerWatsonPoint(pt3); AddBowyerWatsonPoint(pt4); //加入辅助窗体的5条边 CLine line1 = CLine(pt1,pt2); CLine line2 = CLine(pt2,pt3); CLine line3 = CLine(pt3,pt4); CLine line4 = CLine(pt4,pt1); CLine line5 = CLine(pt2,pt4); AddBowyerWatsonLine(line1); AddBowyerWatsonLine(line2); AddBowyerWatsonLine(line3); AddBowyerWatsonLine(line4); AddBowyerWatsonLine(line5); //加入辅助三角形2个 CTriangle tg1 = CTriangle(pt1,pt2,pt4); CTriangle tg2 = CTriangle(pt2,pt3,pt4); AddBowyerWatsonTriangle(tg1); AddBowyerWatsonTriangle(tg2); } void CBowyerWatson::AddNewPoint(CPoint pt) { bool existflag = false; std::list<CPoint*>::iterator iter_point = m_lstAddPointList.begin(); for ( ;iter_point != m_lstAddPointList.end();iter_point++) { if (pt == (**iter_point)) { existflag = true; } } if (!existflag) { CPoint* newPoint = new CPoint(pt.x,pt.y); m_lstAddPointList.push_back(newPoint); } } void CBowyerWatson::UpdateNewPoint() { std::list<CPoint*>::iterator iter_point = m_lstAddPointList.begin(); while (iter_point != m_lstAddPointList.end()) { ProcessNewPoint(**iter_point); std::list<CPoint*>::iterator iter_pointNext = iter_point; iter_pointNext++; SAFE_DELETE(*iter_point); m_lstAddPointList.erase(iter_point); iter_point = iter_pointNext; }//Point //剔除辅助边 std::list<CLine*>::iterator iter = m_lstBowyerWatsonLineList.begin(); while(iter != m_lstBowyerWatsonLineList.end()) { CLine line = (**iter); if (line.CheckPointExist(mHelperPoints[0]) || line.CheckPointExist(mHelperPoints[1]) || line.CheckPointExist(mHelperPoints[2]) || line.CheckPointExist(mHelperPoints[3])) { std::list<CLine*>::iterator iter_next = iter; iter_next++; SAFE_DELETE(*iter); m_lstBowyerWatsonLineList.erase(iter); iter = iter_next; } else{ iter++; } } //剔除辅助三角形 std::list<CTriangle*>::iterator iter_triangle = m_lstBowyerWatsonTriangleList.begin(); while(iter_triangle != m_lstBowyerWatsonTriangleList.end()) { CTriangle triangle = (**iter_triangle); if (triangle.CheckPointExist(mHelperPoints[0]) || triangle.CheckPointExist(mHelperPoints[1]) || triangle.CheckPointExist(mHelperPoints[2]) || triangle.CheckPointExist(mHelperPoints[3])) { std::list<CTriangle*>::iterator iter_nextTriangle = iter_triangle; iter_nextTriangle++; SAFE_DELETE(*iter_triangle); m_lstBowyerWatsonTriangleList.erase(iter_triangle); iter_triangle = iter_nextTriangle; } else{ iter_triangle++; } } } void CBowyerWatson::AddBowyerWatsonPoint(CPoint pt) { bool existflag = false; std::list<CPoint*>::iterator iter_point = m_lstBowyerWatsonPointList.begin(); for ( ;iter_point != m_lstBowyerWatsonPointList.end();iter_point++) { if (pt == (**iter_point)) { existflag = true; } } if (!existflag) { CPoint* newPoint = new CPoint(pt.x,pt.y); m_lstBowyerWatsonPointList.push_back(newPoint); } } void CBowyerWatson::AddBowyerWatsonLine(CLine line) { bool existflag = false; std::list<CLine*>::iterator iter_line = m_lstBowyerWatsonLineList.begin(); for ( ;iter_line != m_lstBowyerWatsonLineList.end();iter_line++) { if (line == (**iter_line)) { existflag = true; } } if (!existflag) { CLine* newLine = new CLine(line.p1,line.p2); m_lstBowyerWatsonLineList.push_back(newLine); } } void CBowyerWatson::DelBowyerWatsonLine(CLine line) { std::list<CLine*>::iterator iter_line = m_lstBowyerWatsonLineList.begin(); while (iter_line != m_lstBowyerWatsonLineList.end()) { if (line == (**iter_line)) { SAFE_DELETE(*iter_line); m_lstBowyerWatsonLineList.erase(iter_line); break; } else iter_line++; }//line std::list<CTriangle*>::iterator iter_Triangle = m_lstBowyerWatsonTriangleList.begin(); while (iter_Triangle != m_lstBowyerWatsonTriangleList.end()) { if ((*iter_Triangle)->l1 == line || (*iter_Triangle)->l2 == line || (*iter_Triangle)->l3 == line ) { SAFE_DELETE(*iter_Triangle); m_lstBowyerWatsonTriangleList.erase(iter_Triangle); break; } else iter_Triangle++; }//Triangle } void CBowyerWatson::AddBowyerWatsonTriangle(CTriangle triangle) { bool existflag = false; std::list<CTriangle*>::iterator iter_Triangle = m_lstBowyerWatsonTriangleList.begin(); for ( ;iter_Triangle != m_lstBowyerWatsonTriangleList.end();iter_Triangle++) { if (triangle == (**iter_Triangle)) { existflag = true; } } if (!existflag) { CTriangle* newTriangle = new CTriangle(triangle.p1,triangle.p2,triangle.p3); m_lstBowyerWatsonTriangleList.push_back(newTriangle); } } void CBowyerWatson::DelBowyerWatsonTriangle(CTriangle triangle) { std::list<CTriangle*>::iterator iter_Triangle = m_lstBowyerWatsonTriangleList.begin(); while (iter_Triangle != m_lstBowyerWatsonTriangleList.end()) { if (triangle == (**iter_Triangle)) { SAFE_DELETE(*iter_Triangle); m_lstBowyerWatsonTriangleList.erase(iter_Triangle); return; } else iter_Triangle++; }//line } void CBowyerWatson::ProcessNewPoint(CPoint pt) { std::list<CLine*> lineList ; std::list<CTriangle*> triangleList; std::vector<CTriangle*> commonTriangleVector; std::list<CLine*>::iterator iter_line = m_lstBowyerWatsonLineList.begin(); for(;iter_line != m_lstBowyerWatsonLineList.end();iter_line++) { CLine* newline = new CLine(); memcpy(newline, *iter_line, sizeof(CLine)); lineList.push_back(newline); } std::list<CTriangle*>::iterator iter_triangle = m_lstBowyerWatsonTriangleList.begin(); for(;iter_triangle != m_lstBowyerWatsonTriangleList.end();iter_triangle++) { CTriangle* newtriangle = new CTriangle(); memcpy(newtriangle, *iter_triangle, sizeof(CTriangle)); triangleList.push_back(newtriangle); } iter_triangle = triangleList.begin(); while (iter_triangle != triangleList.end()) { //是否存在三角形外接圆内 if ((*iter_triangle)->CheckInCircle(pt)) { commonTriangleVector.push_back(*iter_triangle); } iter_triangle++; }// triangle if (commonTriangleVector.size() == 1) { std::vector<CTriangle*>::iterator iter_v = commonTriangleVector.begin(); //////////////////////////////// //删除三角形 DelBowyerWatsonTriangle(**iter_v); ///////////////////////////////// //连接三角形三点 CLine line1 = CLine(pt,(*iter_v)->p1); CLine line2 = CLine(pt,(*iter_v)->p2); CLine line3 = CLine(pt,(*iter_v)->p3); AddBowyerWatsonLine(line1); AddBowyerWatsonLine(line2); AddBowyerWatsonLine(line3); //加入新三角形 if (CheckTriangleLinesExist(pt, (*iter_v)->p1, (*iter_v)->p2)) { CTriangle tg1 = CTriangle(pt,(*iter_v)->p1,(*iter_v)->p2); AddBowyerWatsonTriangle(tg1); } if (CheckTriangleLinesExist(pt, (*iter_v)->p2, (*iter_v)->p3)) { CTriangle tg2 = CTriangle(pt,(*iter_v)->p2,(*iter_v)->p3); AddBowyerWatsonTriangle(tg2); } if (CheckTriangleLinesExist(pt, (*iter_v)->p3, (*iter_v)->p1)) { CTriangle tg3 = CTriangle(pt,(*iter_v)->p3,(*iter_v)->p1); AddBowyerWatsonTriangle(tg3); } } if (commonTriangleVector.size() > 1) { for (int i = 0;i < (commonTriangleVector.size()-1);i++) { for (int j = i+1;j <commonTriangleVector.size();j++) { CTriangle* trg1 = *(commonTriangleVector.begin() + i); CTriangle* trg2 = *(commonTriangleVector.begin() +j); CLine* commonLine = trg1->FindCommonLine(*trg2); if (commonLine != NULL) { //////////////////////////////// //删除影响三角形 DelBowyerWatsonTriangle(*trg1); DelBowyerWatsonTriangle(*trg2); //删除公共边 DelBowyerWatsonLine(*commonLine); ///////////////////////////////// //连接三角形三点 CLine line1_1 = CLine(pt,trg1->p1); CLine line1_2 = CLine(pt,trg1->p2); CLine line1_3 = CLine(pt,trg1->p3); CLine line2_1 = CLine(pt,trg2->p1); CLine line2_2 = CLine(pt,trg2->p2); CLine line2_3 = CLine(pt,trg2->p3); AddBowyerWatsonLine(line1_1); AddBowyerWatsonLine(line1_2); AddBowyerWatsonLine(line1_3); AddBowyerWatsonLine(line2_1); AddBowyerWatsonLine(line2_2); AddBowyerWatsonLine(line2_3); //加入新三角形 if (CheckTriangleLinesExist(pt, trg1->p1, trg1->p2)) { CTriangle tg1 = CTriangle(pt, trg1->p1, trg1->p2); AddBowyerWatsonTriangle(tg1); } if (CheckTriangleLinesExist(pt, trg1->p2, trg1->p3)) { CTriangle tg2 = CTriangle(pt,trg1->p2,trg1->p3); AddBowyerWatsonTriangle(tg2); } if (CheckTriangleLinesExist(pt, trg1->p3, trg1->p1)) { CTriangle tg3 = CTriangle(pt, trg1->p3, trg1->p1); AddBowyerWatsonTriangle(tg3); } if (CheckTriangleLinesExist(pt, trg2->p1, trg2->p2)) { CTriangle tg1 = CTriangle(pt, trg2->p1, trg2->p2); AddBowyerWatsonTriangle(tg1); } if (CheckTriangleLinesExist(pt, trg2->p2, trg2->p3)) { CTriangle tg2 = CTriangle(pt,trg2->p2,trg2->p3); AddBowyerWatsonTriangle(tg2); } if (CheckTriangleLinesExist(pt, trg2->p3, trg2->p1)) { CTriangle tg3 = CTriangle(pt, trg2->p3, trg2->p1); AddBowyerWatsonTriangle(tg3); } } } } } AddBowyerWatsonPoint(pt); iter_line = lineList.begin(); while (iter_line != lineList.end()) { std::list<CLine*>::iterator iter_lineNext = iter_line; iter_lineNext++; SAFE_DELETE(*iter_line); lineList.erase(iter_line); iter_line = iter_lineNext; }//line iter_triangle = triangleList.begin(); while (iter_triangle != triangleList.end()) { std::list<CTriangle*>::iterator iter_triangleNext = iter_triangle; iter_triangleNext++; SAFE_DELETE(*iter_triangle); triangleList.erase(iter_triangle); iter_triangle = iter_triangleNext; }//Triangle } bool CBowyerWatson::CheckTriangleLinesExist(CPoint pt1, CPoint pt2, CPoint pt3) { bool exist_line1 = false; bool exist_line2 = false; bool exist_line3 = false; CLine line1 = CLine(pt1, pt2); CLine line2 = CLine(pt2, pt3); CLine line3 = CLine(pt3, pt1); std::list<CLine*>::iterator iter_line = m_lstBowyerWatsonLineList.begin(); for ( ;iter_line != m_lstBowyerWatsonLineList.end();iter_line++) { if (line1 == (**iter_line)) { exist_line1 = true; continue; } if (line2 == (**iter_line)) { exist_line2 = true; continue; } if (line3 == (**iter_line)) { exist_line3 = true; } } if (exist_line1 && exist_line2 && exist_line3) { return true; } return false; } void CBowyerWatson::DrawMesh() { std::list<CLine*>::iterator iter = m_lstBowyerWatsonLineList.begin(); for ( ;iter != m_lstBowyerWatsonLineList.end();iter++) { //(*iter)->p1.x, (*iter)->p1.y //(*iter)->p2.x, (*iter)->p2.y } } void CBowyerWatson::Update() { if (m_bUpdateDrawFlag) { DrawMesh(); } } ///D:/360极速浏览器下载/Bowyer_Watson/Bowyer_Watson/BowyerWatson.h #ifndef __CBOWYER_WATSON_H__ #define __CBOWYER_WATSON_H__ #include <list> #include <vector> class CPoint; class CLine; class CTriangle; class CBowyerWatson{ public: CBowyerWatson(); ~CBowyerWatson(); static CBowyerWatson* GetInstance(); void ClearBowyerWatson(); void CreateHelperPoint(CPoint pt1, CPoint pt2, CPoint pt3, CPoint pt4); void AddNewPoint(CPoint pt); void UpdateNewPoint(); void AddBowyerWatsonPoint(CPoint pt); void AddBowyerWatsonLine(CLine line); void DelBowyerWatsonLine(CLine line); void AddBowyerWatsonTriangle(CTriangle triangle); void DelBowyerWatsonTriangle(CTriangle triangle); void ProcessNewPoint(CPoint pt); bool CheckTriangleLinesExist(CPoint pt1, CPoint pt2, CPoint pt3); void DrawMesh(); void SetUpdateDrawFlag(bool flag){m_bUpdateDrawFlag = flag;}; void Update(); const std::list<CLine*>& GetBowyerWatsonLines(){return m_lstBowyerWatsonLineList;}; const std::list<CTriangle*>& GetBowyerWatsonTriangles(){return m_lstBowyerWatsonTriangleList;}; private: std::list<CPoint*> m_lstBowyerWatsonPointList; std::list<CLine*> m_lstBowyerWatsonLineList; std::list<CTriangle*> m_lstBowyerWatsonTriangleList; std::list<CPoint*> m_lstAddPointList; CPoint mHelperPoints[4]; static CBowyerWatson* m_pBowyerWatson; bool m_bUpdateDrawFlag; }; #endif ///D:/360极速浏览器下载/Bowyer_Watson/Bowyer_Watson/Line.cpp #include "Line.h" #include "Point.h" float CLine::Point2LineDistance(CPoint pt) { float a = p2.y - p1.y; float b = p1.x - p2.x; float c = p2.x*p1.y - p1.x*p2.y; float dis = fabs(a*pt.x + b*pt.y + c)/sqrt(a*a + b*b); return dis; } bool CLine::operator ==(const CLine& l) { if (l.p1.x == p1.x && l.p1.y == p1.y &&l.p2.x == p2.x && l.p2.y == p2.y) { return true; } if (l.p2.x == p1.x && l.p2.y == p1.y &&l.p1.x == p2.x && l.p1.y == p2.y) { return true; } return false; } CLine& CLine::operator =(const CLine& l) { p1 = l.p1; p2 = l.p2; return *this; } ///D:/360极速浏览器下载/Bowyer_Watson/Bowyer_Watson/Line.h #ifndef __CLINEH__ #define __CLINEH__ #include "Point.h" class CLine{ public: CPoint p1; CPoint p2; CLine() { }; CLine(CPoint pt1, CPoint pt2) { p1.x = pt1.x; p1.y = pt1.y; p2.x = pt2.x; p2.y = pt2.y; }; bool CheckPointExist(CPoint pt) { if (pt == p1 || pt == p2) { return true; } return false; }; float Point2LineDistance(CPoint pt); bool operator ==(const CLine& l); CLine& operator =(const CLine& l); }; #endif ///D:/360极速浏览器下载/Bowyer_Watson/Bowyer_Watson/Main.cpp 原版 #include<iostream> #include <map> #include "Line.h" #include "Point.h" #include "Triangle.h" #include "BowyerWatson.h" using namespace std; void main() { cout<<"********************* Bowyer_Watson_algorithm ****************** "<<endl; cout<<"********************* 本程序目标为实现Bowyer_Watson算法 ******************"<<endl; cout<<"********************* 如有遇到BUG请联系作者 ******************"<<endl; cout<<"********************* email: zzzzyu@sina.com ******************"<<endl; cout<<"********************* Blog: blog.csdn.net/zzzzyu ******************"<<endl; cout<<endl<<endl; CBowyerWatson::GetInstance()->ClearBowyerWatson(); CBowyerWatson::GetInstance()->CreateHelperPoint(CPoint(0,0),CPoint(0,100),CPoint(100,100),CPoint(100,0)); CBowyerWatson::GetInstance()->AddNewPoint(CPoint(25,25)); CBowyerWatson::GetInstance()->AddNewPoint(CPoint(35,50)); CBowyerWatson::GetInstance()->AddNewPoint(CPoint(40,48)); CBowyerWatson::GetInstance()->AddNewPoint(CPoint(50,25)); CBowyerWatson::GetInstance()->AddNewPoint(CPoint(50,40)); CBowyerWatson::GetInstance()->UpdateNewPoint(); const std::list<CLine*> lineList = CBowyerWatson::GetInstance()->GetBowyerWatsonLines(); std::list<CLine*>::const_iterator ite_line = lineList.begin(); for ( ;ite_line != lineList.end();ite_line++) { cout<<"line : ("<<(*ite_line)->p1.x<<" "<<(*ite_line)->p1.y<<") " <<"("<<(*ite_line)->p2.x<<" "<<(*ite_line)->p2.y<<")"<<endl; } cout<<endl<<endl; const std::list<CTriangle*> triangleList = CBowyerWatson::GetInstance()->GetBowyerWatsonTriangles(); std::list<CTriangle*>::const_iterator iter_triangle = triangleList.begin(); for ( ;iter_triangle != triangleList.end();iter_triangle++) { cout<<"Triangle : ("<<(*iter_triangle)->p1.x<<" "<<(*iter_triangle)->p1.y<<") " <<(*iter_triangle)->p2.x<<" "<<(*iter_triangle)->p2.y<<") " <<"("<<(*iter_triangle)->p3.x<<" "<<(*iter_triangle)->p3.y<<")"<<endl; } cout<<"Lines count : "<<lineList.size()<<endl; cout<<"Triangles count : "<<triangleList.size()<<endl; int ci; cin>>ci; return; } ///D:/360极速浏览器下载/Bowyer_Watson/Bowyer_Watson/Main.cpp 改良后 #include <cstdlib> #include <iostream> #include <cstring> #include <string> #include <fstream> #include <map> #include "Line.h" #include "Point.h" #include "Triangle.h" #include "BowyerWatson.h" using namespace std; void GetPoint(double &xx,double &yy,double &zz,string line)//从字符串line中解析出点的x,y,z坐标 { int flag=0; string tmp=""; char *cstr; /*这段似乎不能分析^num1, num2, num3$这种格式的输入 for (int i=(int)line.find(',')+1;i<(int)line.size();i++) { if (line[i]==',') { cstr=new char[tmp.size()+1]; strcpy(cstr,tmp.c_str()); if (flag==0) {xx=atof(cstr);tmp.resize(0);flag++;} else if (flag==1) {yy=atof(cstr);tmp.resize(0);flag++;} continue; } tmp=tmp+line[i]; } */ int xPos = 0, yPos = 0, zPos = 0; //记录逗号分隔符位置 xPos = line.find(','); tmp = line.substr(0, xPos); cstr=new char[tmp.size()+1]; strcpy(cstr,tmp.c_str()); xx=atof(cstr); tmp.resize(0); cstr = NULL; yPos = line.find(',', xPos+1); tmp = line.substr(xPos+1, (yPos-xPos-1)); cstr=new char[tmp.size()+1]; strcpy(cstr,tmp.c_str()); yy=atof(cstr); tmp.resize(0); cstr = NULL; if (fabs(xx)<1.0e-6) xx=0.0; if (fabs(yy)<1.0e-6) yy=0.0; if (fabs(zz)<1.0e-6) zz=0.0; } void main() { cout<<"********************* Bowyer_Watson_algorithm ****************** "<<endl; cout<<"********************* 本程序目标为实现Bowyer_Watson算法 ******************"<<endl; cout<<"********************* 如有遇到BUG请联系作者 ******************"<<endl; cout<<"********************* email: zzzzyu@sina.com ******************"<<endl; cout<<"********************* Blog: blog.csdn.net/zzzzyu ******************"<<endl; cout<<endl<<endl; CBowyerWatson::GetInstance()->ClearBowyerWatson(); CBowyerWatson::GetInstance()->CreateHelperPoint(CPoint(0,0),CPoint(1000,0),CPoint(1000,1000),CPoint(0, 1000)); //从文件中读取点 ifstream infile("input.txt");//打开"input.txt"文件 if (!infile)//判断文件是否正常打开 { cout<<"Unable to input nodes!"; exit(1); } string line; double xx,yy,zz; int nodeSize; cout<<"读取边界点:"<<endl; for (int i=0;i<4;i++)//读入4外边框点 { getline(infile,line); GetPoint(xx,yy,zz,line); cout<<"["<<xx<<", "<<yy<<"], "<<endl; } getline(infile,line);//读入节点数,用于后面循环 char *cstr; cstr=new char[line.size()+1]; strcpy(cstr,line.c_str()); nodeSize=atoi(cstr); cout<<"读取顶点数量:"<<nodeSize<<endl; cout<<"读取顶点:"<<endl; for (int i=0;i<nodeSize;i++)//读入每个节点的坐标 { getline(infile,line); GetPoint(xx,yy,zz,line); cout<<"["<<xx<<", "<<yy<<"],"; CBowyerWatson::GetInstance()->AddNewPoint(CPoint(xx,yy)); } infile.close(); /* CBowyerWatson::GetInstance()->AddNewPoint(CPoint(25,25)); CBowyerWatson::GetInstance()->AddNewPoint(CPoint(35,50)); CBowyerWatson::GetInstance()->AddNewPoint(CPoint(40,48)); CBowyerWatson::GetInstance()->AddNewPoint(CPoint(50,25)); CBowyerWatson::GetInstance()->AddNewPoint(CPoint(50,40)); */ CBowyerWatson::GetInstance()->UpdateNewPoint(); const std::list<CLine*> lineList = CBowyerWatson::GetInstance()->GetBowyerWatsonLines(); std::list<CLine*>::const_iterator ite_line = lineList.begin(); cout<<endl<<"line :"<<endl; for ( ;ite_line != lineList.end();ite_line++) { cout<<"[["<<(*ite_line)->p1.x<<", "<<(*ite_line)->p1.y<<"], " <<"["<<(*ite_line)->p2.x<<", "<<(*ite_line)->p2.y<<"]], "<<endl; } cout<<endl<<endl; const std::list<CTriangle*> triangleList = CBowyerWatson::GetInstance()->GetBowyerWatsonTriangles(); std::list<CTriangle*>::const_iterator iter_triangle = triangleList.begin(); cout<<"Triangle :"<<endl; for ( ;iter_triangle != triangleList.end();iter_triangle++) { cout<<"[["<<(*iter_triangle)->p1.x<<", "<<(*iter_triangle)->p1.y<<"], " <<"["<<(*iter_triangle)->p2.x<<", "<<(*iter_triangle)->p2.y<<"], " <<"["<<(*iter_triangle)->p3.x<<", "<<(*iter_triangle)->p3.y<<"]],"<<endl; } cout<<"Lines count : "<<lineList.size()<<endl; cout<<"Triangles count : "<<triangleList.size()<<endl; int ci; cout<<"输入任意数结束程序!"<<endl; cin>>ci; return; } ///D:/360极速浏览器下载/Bowyer_Watson/Bowyer_Watson/Point.cpp #include "Point.h" bool CPoint::operator ==(const CPoint& p) { if (p.x == x && p.y == y) { return true; } return false; } CPoint& CPoint::operator =(const CPoint& p) { x = p.x; y = p.y; return *this; } ///D:/360极速浏览器下载/Bowyer_Watson/Bowyer_Watson/Point.h #ifndef __CPOINTH__ #define __CPOINTH__ #define NULL 0 #define SAFE_DELETE(x) if( (x)!=NULL ) { delete (x); (x)=NULL; } #include <math.h> class CPoint{ public: float x; float y; CPoint() { x = 0; y = 0; }; static float distance(CPoint pt1 , CPoint pt2) { return sqrt((pt1.x-pt2.x)*(pt1.x-pt2.x) + (pt1.y-pt2.y)*(pt1.y-pt2.y)); }; CPoint(float fx, float fy) { x = fx; y = fy; }; bool operator ==(const CPoint& p); CPoint& operator =(const CPoint& p); }; #endif ///D:/360极速浏览器下载/Bowyer_Watson/Bowyer_Watson/Triangle.cpp #include "Triangle.h" #include <math.h> CTriangle::CTriangle(CPoint pt1, CPoint pt2, CPoint pt3) { p1 = pt1; p2 = pt2; p3 = pt3; l1 = CLine(p1,p2); l2 = CLine(p2,p3); l3 = CLine(p3,p1); float dis1 = CPoint::distance(p1,p2); float dis2 = CPoint::distance(p2,p3); float dis3 = CPoint::distance(p3,p1); radiu = dis1*dis2*dis3/TriangleArea()/4; float c1, c2; float xA, yA, xB, yB, xC, yC; xA = p1.x; yA = p1.y; xB = p2.x; yB = p2.y; xC = p3.x; yC = p3.y; c1 = (xA * xA + yA * yA - xB * xB - yB * yB) / 2; c2 = (xA * xA + yA * yA - xC * xC - yC * yC) / 2; center.x = (c1 * (yA - yC) - c2 * (yA - yB)) / ((xA - xB) * (yA - yC) - (xA - xC) * (yA - yB)); center.y = (c1 * (xA - xC) - c2 * (xA - xB)) / ((yA - yB) * (xA - xC) - (yA - yC) * (xA - xB)); } float CTriangle::TriangleArea() { return fabs(p1.x * p2.y + p2.x * p3.y + p3.x * p1.y - p2.x * p1.y - p3.x * p2.y - p1.x * p3.y) / 2; } bool CTriangle::CheckInCircle(CPoint pt) { if (CPoint::distance(center,pt) <= radiu) { return true; } return false; } CLine CTriangle::FindNearestLine(CPoint pt) { float dis1 = l1.Point2LineDistance(pt); float dis2 = l2.Point2LineDistance(pt); float dis3 = l3.Point2LineDistance(pt); if (dis1 <= dis2 && dis1 <= dis3) { return l1; } if (dis2 <= dis1 && dis2 <= dis3) { return l2; } return l3; } CLine* CTriangle::FindCommonLine(CTriangle tg) { if (this->l1 == tg.l1 || this->l1 == tg.l2 || this->l1 == tg.l3) { return &l1; } if (this->l2 == tg.l1 || this->l2 == tg.l2 || this->l2 == tg.l3) { return &l2; } if (this->l3 == tg.l1 || this->l3 == tg.l2 || this->l3 == tg.l3) { return &l3; } return NULL; } CPoint CTriangle::GetOtherPoint(CPoint pt1, CPoint pt2) { if (!(p1 == pt1) && !(p1 == pt2)) { return p1; } if (!(p2 == pt1) && !(p2 == pt2)) { return p2; } return p3; } bool CTriangle::CheckPointExist(CPoint pt) { if (pt == p1 || pt == p2 || pt == p3) { return true; } return false; } bool CTriangle::operator ==(const CTriangle& t) { if ((p1 == t.p1) && (p2 == t.p2) && (p3 == t.p3)) { return true; } if ((p1 == t.p1) && (p3 == t.p2) && (p2 == t.p3)) { return true; } if ((p2 == t.p1) && (p1 == t.p2) && (p3 == t.p3)) { return true; } if ((p2 == t.p1) && (p3 == t.p2) && (p1 == t.p3)) { return true; } if ((p3 == t.p1) && (p2 == t.p2) && (p1 == t.p3)) { return true; } if ((p3 == t.p1) && (p1 == t.p2) && (p2 == t.p3)) { return true; } return false; } ///D:/360极速浏览器下载/Bowyer_Watson/Bowyer_Watson/Triangle.h #ifndef __CTRIANGLEH__ #define __CTRIANGLEH__ #include "Point.h" #include "Line.h" class CTriangle{ public : CPoint p1; CPoint p2; CPoint p3; CLine l1; CLine l2; CLine l3; CPoint center; float radiu; CTriangle(){}; CTriangle(CPoint pt1, CPoint pt2, CPoint pt3); bool CheckInCircle(CPoint pt); float TriangleArea(); CLine FindNearestLine(CPoint pt); CLine* FindCommonLine(CTriangle tg); CPoint GetOtherPoint(CPoint pt1, CPoint pt2); bool CheckPointExist(CPoint pt); bool operator ==(const CTriangle& t); }; #endif </span>
阿伟念动咒语,生成了制造工艺流程:
<span style="font-size:18px;">#nmake /f winc.mak #源文件目录和编译输出目录 SRCPATH = DSTPATH = .\dst #编译器 CPP = cl RSC = rc LINK = link #编译选项 CPPFLAGS = /nologo /EHsc /W3 /O2 /D "WIN32" /D _X86_ /D "NDEBUG" /D "_MBCS" /c RSCFLAGS = LINKFALGS = /nologo #预定义链接库 LINKLIB = user32.lib kernel32.lib gdi32.lib #平台 PLATFORM = /machine:I386 /subsystem:console #目标文件名 #前缀加地址 $(DSTPATH)/ EXETARGET = $(DSTPATH)/Main.exe DLLTARGET = OBJTARGET = $(DSTPATH)/Point.obj $(DSTPATH)/Line.obj $(DSTPATH)/Triangle.obj $(DSTPATH)/BowyerWatson.obj $(DSTPATH)/Main.obj RESTARGET = #编译规则 all: create.dir $(EXETARGET) $(DLLTARGET) $(OBJTARGET) $(RESTARGET) !if "$(EXETARGET)" != "" $(EXETARGET): $(OBJTARGET) $(RESTARGET) $(LINK) $(LINKFLAGS) $(PLATFORM) $(LINKLIB) $(OBJTARGET) $(RESTARGET) /OUT:$(EXETARGET) !endif .c{$(DSTPATH)/}.obj: $(CPP) $(CPPFLAGS) /Fo$@ $< .cpp{$(DSTPATH)/}.obj: $(CPP) $(CPPFLAGS) /Fo$@ $< .rc{$(DSTPATH)/}.res: $(RSC) $(RSCFLAGS) /Fo$@ $< create.dir: -if not exist $(DSTPATH)\*.* mkdir $(DSTPATH) clean: -if exist $(DSTPATH)\*.obj erase $(DSTPATH)\*.obj -if exist $(DSTPATH)\*.res erase $(DSTPATH)\*.res</span>
神农看了半天,表示他不识数,只看得懂图。
图来:
阿伟和神农都没有说话,神农默默地掏出了第二张图纸:
<span style="font-size:18px;">///D:/360极速浏览器下载/delaunay/delaunay.cpp #include "delaunay.h" Delaunay::Delaunay(Point p1,Point p2,Point p3,Point p4) { //四个边框点为左上->右上->右下->左下的环形顺序 m_Pts.resize(4); m_Pts[0]=p1; m_Pts[1]=p2; m_Pts[2]=p3; m_Pts[3]=p4;//添加四个外边框点 m_Edges.resize(4); Edge l1={0,1,-1}; Edge l2={1,2,-1}; Edge l3={0,3,-1}; Edge l4={2,3,-1}; m_Edges[0]=l1; m_Edges[1]=l2; m_Edges[2]=l3; m_Edges[3]=l4;//添加四个外边框的边 MakeTriangle(0,1,2); MakeTriangle(0,2,3);//添加初始的两个三角形 } Delaunay::~Delaunay()//清空Delaunay类的数据成员 { m_Pts.resize(0); m_Edges.resize(0); m_Tris.resize(0); } void Delaunay::MakeTriangle(int n1,int n2,int n3) { double x_centre,y_centre,radius; Cal_Centre(x_centre,y_centre,radius,n1,n2,n3);//获得顶点为n1,n2,n3的三角形的外接圆圆心坐标和半径 Triangle newTriangle={{n1,n2,n3},{{n1,n2,1},{n2,n3,1},{n1,n3,1}},x_centre,y_centre,radius};//生成指定的三角形 m_Tris.push_back(newTriangle);//向m_Tris中添加新构造的三角形 int EdgeSzie=(int)m_Edges.size();//获得目前的边数 int flag; for (int i=0;i<3;i++) { flag=1; for(int j=0;j<EdgeSzie;j++)//通过循环判断新构造的三角形的各边是否已经存在于m_Edges中,如果存在则只增加该边的计数,否则添加新边 { if (newTriangle.s[i].left==m_Edges[j].left&&newTriangle.s[i].right==m_Edges[j].right&&m_Edges[j].count!=-1) {flag=0;m_Edges[j].count+=1;break;} else if(newTriangle.s[i].left==m_Edges[j].left&&newTriangle.s[i].right==m_Edges[j].right&&m_Edges[j].count==-1) {flag=0;break;} } if (flag==1) m_Edges.push_back(newTriangle.s[i]); } } void Delaunay::Cal_Centre(double &x_centre,double &y_centre,double &radius,int n1,int n2,int n3) { double x1,x2,x3,y1,y2,y3; x1=m_Pts[n1].x; y1=m_Pts[n1].y; x2=m_Pts[n2].x; y2=m_Pts[n2].y; x3=m_Pts[n3].x; y3=m_Pts[n3].y; x_centre=((y2-y1)*(y3*y3-y1*y1+x3*x3-x1*x1)-(y3-y1)*(y2*y2-y1*y1+x2*x2-x1*x1))/(2*(x3-x1)*(y2-y1)-2*((x2-x1)*(y3-y1)));//计算外接圆圆心的x坐标 y_centre=((x2-x1)*(x3*x3-x1*x1+y3*y3-y1*y1)-(x3-x1)*(x2*x2-x1*x1+y2*y2-y1*y1))/(2*(y3-y1)*(x2-x1)-2*((y2-y1)*(x3-x1)));//计算外接圆圆心的y坐标 radius= sqrt((x1 - x_centre)*(x1 - x_centre) + (y1 - y_centre)*(y1 - y_centre));//计算外接圆的半径 } bool Delaunay::AddPoint(double xx,double yy,double zz) { EdgeArray BoundEdges;//BoundEdges用于存储在删除三角形后留下的边框,用于构造新的三角形 Point newPoint={xx,yy,zz}; m_Pts.push_back(newPoint);//向m_Pts中添加新点 intArray badTriangle;//badTriangle用于存储不符合空圆规则的三角形的索引号 int TriSize=(int)m_Tris.size();//获得目前的三角形数 for (int i=0;i<TriSize;i++)//通过循环找到所有不符合空圆规则的三角形,并将其索引号存在badTriangle中 { if (inCircle(xx,yy,m_Tris[i])==true) badTriangle.push_back(i); } for (int i=0;i<(int)badTriangle.size();i++)//通过循环删除所有不符合空圆规则的三角形,同时保留边框 { DelTriangle(badTriangle[i],BoundEdges); for (int j=i+1;j<(int)badTriangle.size();j++) badTriangle[j]-=1; } int PtSize=(int)m_Pts.size();//获得目前的点数 for (int i=0;i<(int)BoundEdges.size();i++)//生成新的三角形 { if (PtSize-1<BoundEdges[i].left) MakeTriangle(PtSize-1,BoundEdges[i].left,BoundEdges[i].right); else if (PtSize-1>BoundEdges[i].left && PtSize-1<BoundEdges[i].right) MakeTriangle(BoundEdges[i].left,PtSize-1,BoundEdges[i].right); else MakeTriangle(BoundEdges[i].left,BoundEdges[i].right,PtSize-1); } return true; } bool Delaunay::inCircle(double xx,double yy,Triangle currentTris)//判断点是否在三角形的外接圆内 { double dis=sqrt((currentTris.xc-xx)*(currentTris.xc-xx)+(currentTris.yc-yy)*(currentTris.yc-yy)); if (dis>currentTris.r) return false; else return true; } void Delaunay::DelTriangle(int n,EdgeArray &BoundEdges) { for (int i=0;i<3;i++) { for (int j=0;j<(int)m_Edges.size();j++) { if (m_Edges[j].left==m_Tris[n].s[i].left&&m_Edges[j].right==m_Tris[n].s[i].right) { if (m_Edges[j].count==2)//若要删除三角形的一边的计数为2,则将其计数减1,并将其压入BoundEdges容器中 { m_Edges[j].count=1; BoundEdges.push_back(m_Edges[j]); } else if (m_Edges[j].count==-1) BoundEdges.push_back(m_Edges[j]);//如果是外边框,则直接压入BoundEdges容器中 else if (m_Edges[j].count==1)//如果删除三角形的一边的计数为1,则删除该边,同时查看BoundEdges中是否有此边,若有,则删除 { for (int k=0;k<(int)BoundEdges.size();k++) { if (BoundEdges[k].left==m_Edges[j].left&&BoundEdges[k].right==m_Edges[j].right) { BoundEdges.erase(BoundEdges.begin()+k); break; } } m_Edges.erase(m_Edges.begin()+j); j--; } break; } } } m_Tris.erase(m_Tris.begin()+n);//删除该三角形 } void Delaunay::output()//向“output.log"文件中写入ANSYS命令流 { ofstream outfile("output.log"); if (!outfile) { cout<<"Unable to output nodes!"; exit(1); } outfile<<"/PREP7"<<endl; for (int i=0;i<(int)m_Pts.size();i++) { outfile<<"K,"<<i+1<<","<<m_Pts[i].x<<","<<m_Pts[i].y<<","<<m_Pts[i].z<<endl; } for (int i=0;i<(int)m_Edges.size();i++) { outfile<<"L,"<<m_Edges[i].left+1<<","<<m_Edges[i].right+1<<endl; } outfile.close(); } /*原版 void GetPoint(double &xx,double &yy,double &zz,string line)//从字符串line中解析出点的x,y,z坐标 { int flag=0; string tmp=""; char *cstr; for (int i=(int)line.find(',')+1;i<(int)line.size();i++) { if (line[i]==',') { cstr=new char[tmp.size()+1]; strcpy(cstr,tmp.c_str()); if (flag==0) {xx=atof(cstr);tmp.resize(0);flag++;} else if (flag==1) {yy=atof(cstr);tmp.resize(0);flag++;} continue; } tmp=tmp+line[i]; } if (fabs(xx)<1.0e-6) xx=0.0; if (fabs(yy)<1.0e-6) yy=0.0; if (fabs(zz)<1.0e-6) zz=0.0; } */ //改良后 void GetPoint(double &xx,double &yy,double &zz,string line)//从字符串line中解析出点的x,y,z坐标 { int flag=0; string tmp=""; char *cstr; /*这段似乎不能分析^num1, num2, num3$这种格式的输入 for (int i=(int)line.find(',')+1;i<(int)line.size();i++) { if (line[i]==',') { cstr=new char[tmp.size()+1]; strcpy(cstr,tmp.c_str()); if (flag==0) {xx=atof(cstr);tmp.resize(0);flag++;} else if (flag==1) {yy=atof(cstr);tmp.resize(0);flag++;} continue; } tmp=tmp+line[i]; } */ int xPos = 0, yPos = 0, zPos = 0; //记录逗号分隔符位置 xPos = line.find(','); tmp = line.substr(0, xPos); cstr=new char[tmp.size()+1]; strcpy(cstr,tmp.c_str()); xx=atof(cstr); tmp.resize(0); cstr = NULL; yPos = line.find(',', xPos+1); tmp = line.substr(xPos+1, (yPos-xPos-1)); cstr=new char[tmp.size()+1]; strcpy(cstr,tmp.c_str()); yy=atof(cstr); tmp.resize(0); cstr = NULL; //不理会z值,需要时再扩展 zz = 0.0; if (fabs(xx)<1.0e-6) xx=0.0; if (fabs(yy)<1.0e-6) yy=0.0; if (fabs(zz)<1.0e-6) zz=0.0; } void Delaunay::Delete_Frame()//删除外边框 { EdgeArray BoundEdges; for (int i=0;i<4;i++) m_Pts.erase(m_Pts.begin()); for (int i=0;i<(int)m_Tris.size();i++) { if (m_Tris[i].v[0]==0||m_Tris[i].v[0]==1||m_Tris[i].v[0]==2||m_Tris[i].v[0]==3) { DelTriangle(i,BoundEdges); BoundEdges.resize(0); i--; } else { for (int j=0;j<3;j++) { m_Tris[i].v[j]-=4; m_Tris[i].s[j].left-=4; m_Tris[i].s[j].right-=4; } } } for (int i=0;i<4;i++) m_Edges.erase(m_Edges.begin()); for (int i=0;i<(int)m_Edges.size();i++) { m_Edges[i].left-=4; m_Edges[i].right-=4; } } void Delaunay::Boundary_Recover(int fromPoint,int toPoint)//恢复由指定点组成的边界 { EdgeArray BoundEdges; for (int i=0;i<(int)m_Tris.size();i++) { if (m_Tris[i].v[0]>=(fromPoint-1)&&m_Tris[i].v[2]<=(toPoint-1)) { DelTriangle(i,BoundEdges); BoundEdges.resize(0); i--; } } } ///D:/360极速浏览器下载/delaunay/delaunay.h #ifndef DELAUNAY_H_INCLUDED #define DELAUNAY_H_INCLUDED #include <cstdlib> #include <iostream> #include <cstring> #include <string> #include <fstream> #include <math.h> #include <vector> using namespace std; typedef struct { double x; double y; double z; }Point;//定义点类 typedef vector<Point> PointArray;//定义点类的vector容器 typedef struct { int left; int right; int count;//边的计数,如果计数为0,则删除此边 }Edge;//定义边类 typedef vector<Edge> EdgeArray;//定义边类的vector容器 typedef struct { int v[3];//三角形的三个顶点 Edge s[3];//三角形的三条边 double xc;//三角形外接圆圆心的x坐标 double yc;//三角形外接圆圆心的y坐标 double r;//三角形外接圆的半径 }Triangle;//定义三角形类 typedef vector<Triangle> TriangleArray;//定义三角形类的vector容器 typedef vector<int> intArray;//定义int类的vector容器 class Delaunay//定义Delaunay类 { public: Delaunay(Point p1,Point p2,Point p3,Point p4);//Delaunay类的构造函数,创建外边框 ~Delaunay();//Delaunay类的析构函数 bool AddPoint(double xx,double yy,double zz);//向已有剖分图形中加点的函数 void Delete_Frame();//删除外边框 void Boundary_Recover(int fromPoint,int toPoint);//边界恢复 void output();//输出ANSYS命令流文件 private: void Cal_Centre(double &x_centre,double &y_centre,double &radius,int n1,int n2,int n3);//计算三角形的外接圆圆心坐标和半径 void MakeTriangle(int n1,int n2,int n3);//生成指定顶点的三角形 bool inCircle(double xx,double yy,Triangle currentTris);//判断点是否在圆内 void DelTriangle(int n,EdgeArray &BoundEdges);//删除指定的三角形 PointArray m_Pts;//m_Pts用于存储所有点 EdgeArray m_Edges;//m_Edges用于存储所有边 TriangleArray m_Tris;//m_Tris用于存储所有三角形 }; void GetPoint(double &xx,double &yy,double &zz,string line);//解析从input文件中读取的每一行数据 #endif // DELAUNAY_H_INCLUDED ///D:/360极速浏览器下载/delaunay/main.cpp #include "delaunay.h" int main() { ifstream infile("input.txt");//打开"input.txt"文件 if (!infile)//判断文件是否正常打开 { cout<<"Unable to input nodes!"; exit(1); } string line; PointArray p; double xx,yy,zz; int nodeSize; for (int i=0;i<4;i++)//读入4外边框点 { getline(infile,line); GetPoint(xx,yy,zz,line); Point tmp={xx,yy,zz}; p.push_back(tmp); } Delaunay MyMesh(p[0],p[1],p[2],p[3]);//实例化Delaunay类 getline(infile,line);//读入节点数,用于后面循环 char *cstr; cstr=new char[line.size()+1]; strcpy(cstr,line.c_str()); nodeSize=atoi(cstr); for (int i=0;i<nodeSize;i++)//读入每个节点的坐标 { getline(infile,line); GetPoint(xx,yy,zz,line); MyMesh.AddPoint(xx,yy,zz); } infile.close(); MyMesh.Delete_Frame();//删除外边框 /* MyMesh.Boundary_Recover(203,466); MyMesh.Boundary_Recover(467,487); MyMesh.Boundary_Recover(488,511); MyMesh.Boundary_Recover(512,537);//以上都是恢复指定边界 */ MyMesh.output();//将相应ANSYS命令流输出 return 0; } </span>
<span style="font-size:18px;">///D:/360极速浏览器下载/delaunay/winc.mak #nmake /f winc.mak #源文件目录和编译输出目录 SRCPATH = DSTPATH = .\dst #编译器 CPP = cl RSC = rc LINK = link #编译选项 CPPFLAGS = /nologo /EHsc /W3 /O2 /D "WIN32" /D _X86_ /D "NDEBUG" /D "_MBCS" /c RSCFLAGS = LINKFALGS = /nologo #预定义链接库 LINKLIB = user32.lib kernel32.lib gdi32.lib #平台 PLATFORM = /machine:I386 /subsystem:console #目标文件名 #前缀加地址 $(DSTPATH)/ EXETARGET = $(DSTPATH)/main.exe DLLTARGET = OBJTARGET = $(DSTPATH)/delaunay.obj $(DSTPATH)/main.obj RESTARGET = #编译规则 all: create.dir $(EXETARGET) $(DLLTARGET) $(OBJTARGET) $(RESTARGET) !if "$(EXETARGET)" != "" $(EXETARGET): $(OBJTARGET) $(RESTARGET) $(LINK) $(LINKFLAGS) $(PLATFORM) $(LINKLIB) $(OBJTARGET) $(RESTARGET) /OUT:$(EXETARGET) !endif .c{$(DSTPATH)/}.obj: $(CPP) $(CPPFLAGS) /Fo$@ $< .cpp{$(DSTPATH)/}.obj: $(CPP) $(CPPFLAGS) /Fo$@ $< .rc{$(DSTPATH)/}.res: $(RSC) $(RSCFLAGS) /Fo$@ $< create.dir: -if not exist $(DSTPATH)\*.* mkdir $(DSTPATH) clean: -if exist $(DSTPATH)\*.obj erase $(DSTPATH)\*.obj -if exist $(DSTPATH)\*.res erase $(DSTPATH)\*.res</span>
这套生产线还只有一半。
神农告诉阿伟那另外半套生产线需要装一个相当大的程序,那个名字他听都没听说过。
嗯,天下数据一家亲,阿伟让神农不要着急。
<span style="font-size:18px;">#读取ANSYS命令流文件数据 def tmp2(): fin = open('input.txt', 'r'); fout = open('output.txt', 'w'); verts = []; edges = []; for line in fin.readlines(): if (line[0] == 'K'): line = line[:-1]; #去除行尾'\n' a = line.split(','); #暂时取第二项,即顶点序号,以及x, y坐标值 verts.append([float(a[2]), float(a[3])]); elif (line[0] == 'L'): line = line[:-1]; a = line.split(','); point_1 = verts[int(a[1])-1]; point_2 = verts[int(a[2])-1]; edges.append([point_1, point_2]); print('共有顶点{0}个,边{1}条'.format(len(verts), len(edges))); fout.write('$Verts = ['); s = ''; for i in range(len(verts)): s += str(verts[i])+','; fout.write(s+']\n'); fout.write('$Edges = ['); s = ''; for i in range(len(edges)): s += str(edges[i])+','; fout.write(s+']\n'); fin.close(); fout.close();</span>
一阵吱吱乱响,[机器小伟]继续出图:
费这么半天工夫,貌似结果一样啊。
阿伟不得不对神农说,你看,要早知的结果也就这样,那你还不如用我的那套设计图纸呢,虽然还有很多奇怪的地方,但总是要简单些啊。
<span style="font-size:18px;">import geo; ### # @usage Bowyer-Watson算法进行Delaunay三角剖分 # @author mw # @date 2016年07月15日 星期五 10:31:36 # @param # @return # ### class Delaunay(): #设置顶点 #vertices是[[x_0, y_0], [x_1, y_1], ...]顶点对格式 def setVertice(self, vertices): return vertices; def sortVerticebyX(self, vertices): v_x = sorted(vertices, key = lambda a : a[0]); return v_x; def sortVerticebyY(self, vertices): v_y = sorted(vertices, key = lambda a : a[1]); return v_y; #去除重复点 def removeDup(self, vertices): v_new = []; len_1 = len(vertices); len_2 = 0; for i in range(len_1): len_2 = len(v_new); if (len_2 < 1): v_new.append(vertices[i]); else: for j in range(len_2): if v_new[j] == vertices[i]: break; if (j >= len_2-1): v_new.append(vertices[i]); return v_new; #计算边界 def calcBound(self, vertices): len_ = len(vertices) v_x = self.sortVerticebyX(vertices); xMin = v_x[0][0]; xMax = v_x[len_-1][0]; v_y = self.sortVerticebyY(vertices); yMin = v_y[0][1]; yMax = v_y[len_-1][1]; return [xMin, xMax, yMin, yMax]; #超级三角形 def superTri(self, vertices): bound = self.calcBound(vertices); xMin = bound[0]-10; xMax = bound[1]+10; yMin = bound[2]-10; yMax = bound[3]+10; xCenter = (xMin+xMax)/2; yCenter = (yMin+yMax)/2; xR = (xMax-xMin)/2; yR = (yMax-yMin)/2; xMin_ = xCenter-2*xR; xMax_ = xCenter+2*xR; yMin_ = yMin; yMax_ = yMin + 4*yR; return [[xMin_, yMin_], [xMax_, yMin_], [xCenter, yMax_]]; #计算剖分三角形 def calcDelaunayTri(self, vertices, mode = 1): #移除重复点 vertices = self.removeDup(vertices); #按X坐标由小到大排序 vertices = self.sortVerticebyX(vertices); #顶点数量 vertNum = len(vertices); #临时三角形存放处 tempTriArray = []; #三角形存放处 triArray = []; #边存放处 edgeArray = []; supertri = self.superTri(vertices); tempTriArray.append(supertri); triArray.append(supertri); for i in range(vertNum): P0 = vertices[i]; tmpTriNum = len(tempTriArray); print('顶点{0} --> {1}个临时三角形'.format(i, tmpTriNum)); edgeArray = []; tmpTri = []; for j in range(tmpTriNum): P1, P2, P3 = tempTriArray[j][0], tempTriArray[j][1], tempTriArray[j][2]; #调用geo的circle方法 circleProp = geo.circle(P1, P2, P3); #取得圆心和半径 P_center, R = circleProp[0], circleProp[1]; #print(P_center, 'R = ', R); d = geo.distance2D(P0, P_center); if (P0[0] > P_center[0]+R): #对比点是在圆外右侧的三角形,已经得到晋级确认 #由于某些时候会多出一些冗余三角形,先加入一个判断试试能不能解决该问题 triArray.append([P1, P2, P3]); elif (d > R): #不确定的三角形,不理它 tmpTri.append([P1, P2, P3]); else: #对比点在圆内,这个三角形被淘汰 edgeArray.append([P1, P2]); edgeArray.append([P2, P3]); edgeArray.append([P3, P1]); edgeArray = self.removeDupEdge(edgeArray); edges = len(edgeArray); print('顶点{0} --> {1}条边'.format(i, edges)); for k in range(edges): P1, P2 = edgeArray[k][0], edgeArray[k][1]; if (geo.pointInLine(P1, P2, P0) == False): tmpTri.append([P0, P1, P2]); #临时数组已经重新安排 tempTriArray = []; tempTriArray = self.removeDupTri(tmpTri); triArray += tempTriArray; triArray = self.removeDupTri(triArray); if (mode == 0): return triArray; else: newTriArray = []; triNum = len(triArray); for i in range(triNum): tri_ = triArray[i]; relate = False; for j in range(3): if relate == True: break; for k in range(3): if tri_[j] == supertri[k]: relate = True; break; if relate == False: newTriArray.append(tri_); return newTriArray; #移除相同的三角形 def removeDupTri(self, triArray): newTriArray = []; for i in range(len(triArray)): len_ = len(newTriArray); if (len_ <= 0): newTriArray.append(triArray[i]); else: for j in range(len_): if self.judgeSameTri(newTriArray[j], triArray[i]) == True: break; if (j >= len_ -1): newTriArray.append(triArray[i]); return newTriArray; #判断两个三角形相同 #三角形格式[P1, P2, P3], P是顶点 def judgeSameTri(self, tri_1, tri_2): P_11, P_12, P_13, P_21, P_22, P_23 = tri_1[0], tri_1[1], tri_1[2], tri_2[0], tri_2[1], tri_2[2]; tri_1 = sorted(tri_1, key = lambda a:(a[0], a[1])); tri_2 = sorted(tri_2, key = lambda a:(a[0], a[1])); if (tri_1 == tri_2): return True; else: return False; #判断两个三角形有共同边 def judge2TriHaveSameEdge(self, tri_1, tri_2): pass; #移除相同的边,本算法的去重指的是要成对的却除相同的边 #而不是只允许出现一次那种 def removeDupEdge(self, edgeArray): newEdgeArray = []; ''' for i in range(len(edgeArray)): len_ = len(newEdgeArray); if (len_ <= 0): newEdgeArray.append(edgeArray[i]); else: for j in range(len_): if self.judgeSameEdge(newEdgeArray[j], edgeArray[i]) == True: newEdgeArray = newEdgeArray[:j]+newEdgeArray[j+1:]; break; if (j >= len_ -1): newEdgeArray.append(edgeArray[i]); return newEdgeArray; ''' len1 = len(edgeArray); ''' for i in range(len_): edgeArray[i] = sorted(edgeArray[i], key = lambda a:(a[0], a[1])); ''' for i in range(len(edgeArray)): len_ = len(newEdgeArray); if (len_ <= 0): newEdgeArray.append([edgeArray[i], 1]); else: for j in range(len_): if self.judgeSameEdge(newEdgeArray[j][0], edgeArray[i]) == True: newEdgeArray[j][1] += 1; break; if (j >= len_ -1): newEdgeArray.append([edgeArray[i], 1]); result = []; for i in range(len(newEdgeArray)): if (newEdgeArray[i][1] <= 1): result.append(newEdgeArray[i][0]); return result; #判断两条边相同 #边格式[P1, P2], P是顶点 def judgeSameEdge(self, edge_1, edge_2): P_11, P_12, P_21, P_22 = edge_1[0], edge_1[1], edge_2[0], edge_2[1]; if (P_11 == P_21 and P_12 == P_22) or (P_11 == P_22 and P_12 == P_21): return True; else: return False; def tmp1(): delaunay = Delaunay(); picDataArray = [[15, 7, 161, 311], [18, 7, 160, 369], [11, 8, 171, 239], [8, 10, 221, 170], [21, 10, 209, 435], [23, 13, 283, 463], [6, 14, 300, 142], [13, 14, 300, 278], [15, 14, 301, 319], [17, 15, 325, 354], [11, 16, 338, 245], [17, 17, 352, 363], [23, 17, 361, 479], [7, 18, 381, 159], [12, 18, 376, 265], [14, 18, 385, 293], [19, 18, 380, 377], [17, 19, 404, 347], [15, 20, 408, 309], [8, 21, 444, 175], [22, 21, 441, 450], [9, 24, 489, 203], [19, 24, 495, 397], [12, 26, 540, 257], [16, 26, 539, 329], ]; verts = []; mapWidth, mapHeight = 700/2, 600/2; for i in range(len(picDataArray)): x = picDataArray[i][2]; y = picDataArray[i][3]; if (abs(x-mapWidth)<=350 and abs(y-mapHeight)<=270): verts.append([x, y, 0]); print('顶点集:', verts); ''' if (len(verts) >= 3): a = delaunay.calcDelaunayTri(verts); print('写入文件开始。>>>'); fout = open('output.txt', 'w'); print('共有顶点{0}个,共有三角形{1}个'.format(len(verts), len(a))); s = '$Verts = '; s += str(verts); fout.write(s + '\n\n\n\n'); s = '$Triangles = '; s += str(a); fout.write(s+'\n'); fout.close(); print('写入文件完毕。'); ''' print('写入文件开始。>>>'); fout = open('output.txt', 'w'); bound = [[0, 0, 0], [1000, 0, 0], [1000, 1000, 0], [0, 1000, 0]]; len_ = len(bound); print(len_); for i in range(len_): s = str(bound[i]); fout.write(s+'\n'); fout.write(str(len(verts))+'\n'); for i in range(len(verts)): s = str(verts[i]); fout.write(s+'\n'); fout.close(); print('写入文件完毕。');</span>
然后,神农拿着这三套图纸,回去召集手下生产车辆去了。
本节到此结束,欲知后事如何,请看下回分解。
[从头读历史] 第307节 星球战争 BC2699 至 BC2600(公元前27世纪)
标签:
原文地址:http://blog.csdn.net/mwsister/article/details/51940617