/*----------------------------------------------------------------------* | make a triangulization of a polygon (private) mwgee 10/05| *----------------------------------------------------------------------*/ bool MOERTEL::Overlap::Triangulation() { // we have a polygon that is in clockwise order at this moment // if more than 3 points, find a center point int np = SizePointPolygon(); if (np<3) { std::cout << "***ERR*** MOERTEL::Overlap::Triangulization:\n" << "***ERR*** # point in polygon < 3 ... very strange!!!\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; exit(EXIT_FAILURE); } if (np>3) // we have to add a center point { double xi[2]; std::vector<Teuchos::RCP<MOERTEL::Point> > points; PointView(points); #if 1 // compute center point xi as centroid Centroid(xi,points,np); //std::cout << "Centroid xi : " << xi[0] << " / " << xi[1] << endl; fflush(stdout); #endif #if 0 // compute center point as nodal avergage xi[0] = xi[1] = 0.0; for (int i=0; i<np; ++i) { const double* pxi = points[i]->Xi(); xi[0] += pxi[0]; xi[1] += pxi[1]; } xi[0] /= np; xi[1] /= np; //std::cout << "Nodal xi : " << xi[0] << " / " << xi[1] << endl << endl; fflush(stdout); #endif // create a point -1 as center point and add it to the polygon AddPointtoPolygon(-1,xi); points.clear(); } // if (np>3) np = SizePointPolygon(); std::vector<Teuchos::RCP<MOERTEL::Point> > points; PointView(points); // create a MOERTEL::Node for every point int dof[3]; dof[0] = dof[1] = dof[2] = -1; // find real world coords for all points // find real world normal for all points // note that the polygon is in slave segment parameter space and is // completely contained in the slave segment. we can therefore use // slave segment values to interpolate polgon point values for (int i=0; i<np; ++i) { double x[3]; x[0] = x[1] = x[2] = 0.0; double n[3]; n[0] = n[1] = n[2] = 0.0; double val[20]; sseg_.EvaluateFunction(0,points[i]->Xi(),val,sseg_.Nnode(),NULL); MOERTEL::Node** snodes = sseg_.Nodes(); for (int j=0; j<sseg_.Nnode(); ++j) for (int k=0; k<3; ++k) { x[k] += val[j]*snodes[j]->X()[k]; n[k] += val[j]*snodes[j]->N()[k]; } const double length = MOERTEL::length(n,3); for (int j=0; j<3; ++j) n[j] /= length; // create a node with this coords and normal; MOERTEL::Node* node = new MOERTEL::Node(points[i]->Id(),x,3,dof,false,OutLevel()); node->SetN(n); // set node in point points[i]->SetNode(node); #if 0 std::cout << *points[i]; #endif } // find projection values for all points in polygon on mseg { double mxi[2]; double gap; MOERTEL::Projector projector(inter_.IsOneDimensional(),OutLevel()); for (int i=0; i<np; ++i) { Teuchos::RCP<MOERTEL::Node> node = points[i]->Node(); projector.ProjectNodetoSegment_NodalNormal(*node,mseg_,mxi,gap); // create a projected node and set it in node MOERTEL::ProjectedNode* pnode = new MOERTEL::ProjectedNode(*node,mxi,&mseg_); node->SetProjectedNode(pnode); node->SetGap(gap); #if 0 std::cout << "-------------------------------------------------------\n"; if (mseg_.Nnode()==3) { if (mxi[0]<=1. && mxi[1]<=abs(1.-mxi[0]) && mxi[0]>=0. && mxi[1]>=0.) std::cout << "OVERLAP: point " << points[i]->Id() << " is in mseg, mxi " << mxi[0] << " / " << mxi[1] << endl; else std::cout << "OVERLAP: point " << points[i]->Id() << " is NOT in mseg, mxi " << mxi[0] << " / " << mxi[1] << endl; } else if (mseg_.Nnode()==4) { if (mxi[0]<=1.001 && mxi[0]>=-1.001 && mxi[1]<=1.001 && mxi[1]>=-1.001) std::cout << "OVERLAP: point " << points[i]->Id() << " is in mseg, mxi " << mxi[0] << " / " << mxi[1] << endl; else std::cout << "OVERLAP: point " << points[i]->Id() << " is NOT in mseg, mxi " << mxi[0] << " / " << mxi[1] << endl; } else { std::cout << "***ERR*** MOERTEL::Overlap::Triangulization:\n" << "***ERR*** # nodes " << mseg_.Nnode() << " of master segment is unknown\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; exit(EXIT_FAILURE); } std::cout << "-------------------------------------------------------\n"; #endif } } // if we plan to interpolate function values at the gaussian points we need the // function values at the points if (exactvalues_==false) { // every point has 3 values of the 3 shape functions of the elements: // max 4 values from function 0 from sseg // max 4 values from function 1 from sseg // max 4 values from function 0 from mseg for (int i=0; i<np; ++i) { double val[20]; int nmval = mseg_.Nnode(); int nsval = sseg_.Nnode(); // evaluate function 0 from sseg sseg_.EvaluateFunction(0,points[i]->Xi(),val,nsval,NULL); points[i]->StoreFunctionValues(0,val,nsval); // evaluate function 1 from sseg sseg_.EvaluateFunction(1,points[i]->Xi(),val,nsval,NULL); points[i]->StoreFunctionValues(1,val,nsval); // evaluate function 0 from mseg mseg_.EvaluateFunction(0,points[i]->Node()->GetProjectedNode()->Xi(),val,nmval,NULL); points[i]->StoreFunctionValues(2,val,nmval); } } // create the triangle elements from polygon with centerpoint // In case of np==3, there is no centerpoint if (np>3) { // the polygon is in clockwise order, center point is points[0] and has // id = -1 if (points[0]->Id() != -1) { std::cout << "***ERR*** MOERTEL::Overlap::Triangulization:\n" << "***ERR*** points[0]->Id() is not -1\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; exit(EXIT_FAILURE); } int nodeid[3]; MOERTEL::Segment_BiLinearTri* tmp; MOERTEL::Function_LinearTri* func = new Function_LinearTri(OutLevel()); for (int i=2; i<np; ++i) { // there are np-1 triangles // triangle ids go from 0 to np-2 // a triangle is defined by nodes 0, i, i-1 // *this class takes ownership of triangle nodeid[0] = points[0]->Id(); nodeid[1] = points[i]->Id(); nodeid[2] = points[i-1]->Id(); tmp = new MOERTEL::Segment_BiLinearTri(i-2,3,nodeid,OutLevel()); // set a linear shape function to this triangle tmp->SetFunction(0,func); // add triangle to the *this class AddSegment(tmp->Id(),tmp); } // add the last triangle defined by nodes 0, 1, np-1 separately // *this class takes ownership of triangle nodeid[0] = points[0]->Id(); nodeid[1] = points[1]->Id(); nodeid[2] = points[np-1]->Id(); tmp = new MOERTEL::Segment_BiLinearTri(np-2,3,nodeid,OutLevel()); // set a linear shape function to this triangle tmp->SetFunction(0,func); // add triangle to the *this class AddSegment(tmp->Id(),tmp); if (func) delete func; func = NULL; } else if (np==3) // single triangle without centerpoint { int nodeid[3]; MOERTEL::Segment_BiLinearTri* tmp; MOERTEL::Function_LinearTri* func = new Function_LinearTri(OutLevel()); nodeid[0] = points[0]->Id(); nodeid[1] = points[2]->Id(); nodeid[2] = points[1]->Id(); // *this class takes ownership of triangle tmp = new MOERTEL::Segment_BiLinearTri(0,3,nodeid,OutLevel()); // set a linear shape function to this triangle tmp->SetFunction(0,func); // add triangle the *this class AddSegment(tmp->Id(),tmp); if (func) delete func; func = NULL; } else { std::cout << "***ERR*** MOERTEL::Overlap::Triangulization:\n" << "***ERR*** # point in polygon < 3 ... very strange!!!\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; exit(EXIT_FAILURE); } // create ptr topology between triangle and nodes in points std::vector<MOERTEL::Node*> nodes(np); for (int i=0; i<np; ++i) nodes[i] = points[i]->Node().get(); // loop segments and set ptr to nodes in them std::map<int,Teuchos::RCP<MOERTEL::Segment> >::iterator curr; for (curr=s_.begin(); curr != s_.end(); ++curr) curr->second->GetPtrstoNodes(nodes); nodes.clear(); points.clear(); return true; }
/*----------------------------------------------------------------------* | perform clipping algorithm (private) mwgee 10/05| *----------------------------------------------------------------------*/ bool MOERTEL::Overlap::Clipelements() { if (!havemxi_ || !havesxi_ || !havelines_ || !havesxim_ || !havelinem_) { std::cout << "***ERR*** MOERTEL::Overlap::Clipelements:\n" << "***ERR*** initialization of Overlap class missing\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; exit(EXIT_FAILURE); } const int nmnode = mseg_.Nnode(); const int nsnode = sseg_.Nnode(); // put all mseg nodes in polygon for (int i=0; i<nmnode; ++i) AddPointtoPolygon(100+i,&mline_[i][0]); //for (int i=0; i<nmnode; ++i) // std::cout << "mline_[" << i << "][0] " << mline_[i][0] << " mline_[" << i << "][1] " << mline_[i][1] // << " mline_[" << i << "][2] " << mline_[i][2] << " mline_[" << i << "][3] " << mline_[i][3] << endl; //=========================================================================== // loop edges of slave segment and clip the master edges // add all intersection points that can be found for (int clipedge=0; clipedge<nsnode; ++clipedge) { // point on that clip edge (dim 2) double* PE = &sline_[clipedge][0]; // the outward normal to the clip edge (dim 2) double* N = &sn_[clipedge][0]; // loop edges of master segment and clip them against the clip edge // add all intersections for (int medge=0; medge<nmnode; ++medge) { bool ok; // start point of medge with id 100+medge double* P0 = &mline_[medge][0]; //int id0 = 100+medge; // end point of medge has id 100+(medge+1 < 3) double* P1 = &mline_[medge][2]; // find intersection between medge and clipedge // if there's an intersection, put it in the polygon // the id is 10*clipedge+medge double xi[2]; ok = Clip_Intersect(N,PE,P0,P1,xi); if (ok) { //std::cout << "OVERLAP Clipelements: adding intersection point " << 10*clipedge+medge << endl; AddPointtoPolygon(10*clipedge+medge,xi); } } // for (int medge=0; medge<3; ++medge) } // for (int clipedge=0; clipedge<3; ++clipedge) //=========================================================================== // loop all clipedges and clip all points incl intersections // that are in the polygon // throw away all points that are not inside { int np = SizePointPolygon(); std::vector<Teuchos::RCP<MOERTEL::Point> > point; PointView(point); int p; for (p=0; p<np; ++p) { bool ok = true; //std::cout << "OVERLAP Clipelements: now clipping point " << point[p]->Id() << endl; const double* P = point[p]->Xi(); for (int clipedge=0; clipedge<nsnode; ++clipedge) { // point on that clip edge (dim 2) double* PE = &sline_[clipedge][0]; // the outward normal to the clip edge (dim 2) double* N = &sn_[clipedge][0]; // clip point P against this edge ok = Clip_TestPoint(N,PE,P,1.0e-10); // leave point in if (ok) continue; // remove this point else { ok = false; break; } } // for (int clipedge=0; clipedge<3; ++clipedge) // if not found inside, remove point if (!ok) { //std::cout << "OVERLAP Clipelements: removing point " << point[p]->Id() << endl; RemovePointfromPolygon(point[p]->Id(),P); } } // for (int p=0; p<np; ++p) point.clear(); } //=========================================================================== // loop all slave nodes and clip against master element. // put those slave nodes that are inside master element into polygon // Note that this works in master segment coords and the node that is put in // is put in with slave segment coords as the polygon is completely in // slave segment coords // master point have ids 100,101,102 // slave points have ids 1000,1001,1002 // edge intersections have ids sedge*10+medge // try only to put slave points in if the polygon is not empty int np = SizePointPolygon(); if (np) { for (int i=0; i<nsnode; ++i) { bool ok = true; // get the slave point in master coords double* P = sxim_[i]; // loop master clip edges for (int clipedge=0; clipedge<nmnode; ++clipedge) { // point on master clipedge double* PE = &mlinem_[clipedge][0]; // the outward normal to the clip edge (dim 2) double* N = &mn_[clipedge][0]; // clip point P against this edge ok = Clip_TestPoint(N,PE,P,1.0e-5); // put point in if (ok) continue; else { ok = false; break; } } // for (int clipedge=0; clipedge<3; ++clipedge) // don't put point in if (!ok) continue; else { //std::cout << "OVERLAP Clipelements: inserting slave point " << 1000+i << " xi=" // << sxi_[i][0] << "/" << sxi_[i][1] << endl; AddPointtoPolygon(1000+i,sxi_[i]); } } // for (int i=0; i<3; ++i) } //=========================================================================== //=========================================================================== //=========================================================================== #if 0 // make printout of the polygon so far { int np = SizePointPolygon(); std::vector<Teuchos::RCP<MOERTEL::Point> > point; PointView(point); for (int p=0; p<np; ++p) { std::cout << "OVERLAP Clipelements: point " << setw(3) << point[p]->Id() << " xi " << point[p]->Xi()[0] << "/" << point[p]->Xi()[1] << endl; } point.clear(); } #endif //=========================================================================== // count how many corner nodes of mseg are in and how many // intersections there are np = SizePointPolygon(); //=========================================================================== // if there are no points, there is still the chance that all slave points // are inside the master element if (!np) { for (int i=0; i<3; ++i) { bool ok = true; // get the slave point in master coords double* P = sxim_[i]; for (int clipedge=0; clipedge<3; ++clipedge) { // point on master clipedge double* PE = &mlinem_[clipedge][0]; // the outward normal to the clip edge (dim 2) double* N = &mn_[clipedge][0]; // clip point P against this edge ok = Clip_TestPoint(N,PE,P,1.0e-5); // put point in if (ok) continue; else { ok = false; break; } } // for (int clipedge=0; clipedge<3; ++clipedge) // don't put point in if (!ok) continue; else { //std::cout << "OVERLAP Clipelements: inserting slave point " << 1000+i << " xi=" // << sxi_[i][0] << "/" << sxi_[i][1] << endl; AddPointtoPolygon(1000+i,sxi_[i]); } } // for (int i=0; i<3; ++i) //========================================================================= // check again how many points there are inside np = SizePointPolygon(); if (np>2); // all slave points are in master segment, just continue else if (np && np <= 2) { if (inter_.OutLevel()>8) std::cout << "MOERTEL: ***WRN*** MOERTEL::Overlap::Clipelements:\n" << "MOERTEL: ***WRN*** " << np << " slave nodes seem to be in master segment but no overlap detected\n" << "MOERTEL: ***WRN*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; return false; } else // with none or less then 3 points in we assume no overlap return false; } //=========================================================================== // maybe its a good idea to collapse intersections with nodes (that are in) // that are really close to each other if (p_.size()>3) CollapsePoints(p_,1.0e-5); #if 0 // make printout of the polygon so far { std::cout << "--------------------------------------------\n"; int np = SizePointPolygon(); std::vector<Teuchos::RCP<MOERTEL::Point> > point; PointView(point); for (int p=0; p<np; ++p) { std::cout << "OVERLAP Clipelements: point " << setw(3) << point[p]->Id() << " xi " << point[p]->Xi()[0] << "/" << point[p]->Xi()[1] << endl; } point.clear(); } #endif //=========================================================================== // check again np = SizePointPolygon(); if (np && np<3) { if (OutLevel()>8) std::cout << "MOERTEL: ***WRN*** MOERTEL::Overlap::Clipelements:\n" << "MOERTEL: ***WRN*** " << np << " nodes in polygon but could not detect overlap\n" << "MOERTEL: ***WRN*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; return false; } else if (!np) return false; //=========================================================================== // finish the polygon ConvexHull(p_); return true; }
bool MoertelT::MOERTEL_TEMPLATE_CLASS_1A(OverlapT, IFace)::CollapsePoints( std::map<int, Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(PointT)>>& p, const double eps) { // we don't want to collapse on a polygon that has just three or less points if (p.size() <= 3) return true; // # points int np = p.size(); // get a view of all points std::vector<Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(PointT)>> points; PointView(p, points); // create a new std::map for collapsed points std::map<int, Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(PointT)>> pnew; // create vector holding points to collapse std::vector<Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(PointT)>> collapse( points.size()); // loop points and compare coords for (int i = 0; i < np; ++i) { if (points[i] == Teuchos::null) continue; // put point i into vector with collapse points // std::cout << "Adding " << i << " to collapse\n"; collapse[0] = points[i]; int count = 1; for (int j = i + 1; j < np; ++j) { if (points[j] == Teuchos::null) continue; double xi1xi2[2]; xi1xi2[0] = points[j]->Xi()[0] - points[i]->Xi()[0]; xi1xi2[1] = points[j]->Xi()[1] - points[i]->Xi()[1]; double dist = MOERTEL::length(xi1xi2, 2); // std::cout << "distance between " << i << " and " << j << " : " << dist // << std::endl; if (dist < eps) { // std::cout << "Adding " << j << " to collapse\n"; // add point2 to collapse vector collapse[count] = points[j]; ++count; points[j] = Teuchos::null; } } // loop all nodes in the collapse vector and put in the one with an // id above 100 (if there is any) bool foundit = false; // if (count>1) // std::cout << "Collapsing " << count << " nodes\n"; for (int j = 0; j < count; ++j) { if (collapse[j]->Id() >= 100) { AddPointtoPolygon(pnew, collapse[j]->Id(), collapse[j]->Xi()); foundit = true; break; } } if (!foundit) // there is no point with id >= 100 { AddPointtoPolygon(pnew, collapse[0]->Id(), collapse[0]->Xi()); } } // for (int i=0; i<np; ++i) points.clear(); // the new polygon is supposed to have at least three points, otherwise its // no better than the old uncollapsed one and we'd rather keep the old one // ^^^ this comment is inaccurate ^^^ // soon after this method is called, there is a check for a degenerate overlap // by asking how many things are in p. If p is less than three, the overlap // is skipped, otherwise the computation continues. After that, an area // weighted sum is computed on the polygon. If the area is 0, this generates // NaNs. By commenting out this if block, the check for degeneracy will work // as claimed in the comments. /* */ if (pnew.size() < 3) { pnew.clear(); collapse.clear(); return true; } /* */ p.clear(); CopyPointPolygon(pnew, p); pnew.clear(); return true; }
bool MOERTEL::Overlap::ClipelementsSH() { if (!havemxi_ || !havesxi_ || !havelines_ || !havesxim_ || !havelinem_){ std::stringstream oss; oss << "***ERR*** MOERTEL::Overlap::Clipelements:\n" << "***ERR*** initialization of Overlap class missing\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw ReportError(oss); } const int nmnode = mseg_.Nnode(); const int nsnode = sseg_.Nnode(); bool ok = true; double eps = 1.0e-10; // GAH EPSILON // I am reading http://cs.fit.edu/~wds/classes/graphics/Clip/clip/clip.html and // http://en.wikipedia.org/wiki/Sutherland–Hodgman_algorithm as I write this code. // I assume that the master segment is convex. It should be if this is a mesh. Secondly, the // slave segment is a square in its parametric space -1 <= \xi <= 1 and -1 <= \eta <= 1. It need // only be convex. // For the Sutherland-Hodgman algorithm, the slave segment is used for the clip polygon. // Start with an input list of polygon vertices, in the slave coordinate system. Note that these points // are ordered around the polygon, as i is the line number of the boundaries of the master seg. std::vector<double> s_poly_xi, s_poly_eta, t_poly_xi, t_poly_eta; // Put all the corners of the master segment into the polygon for (int i=0; i<nmnode; ++i) { // loop over the corners of the master seg s_poly_xi.push_back(mline_[i][0]); s_poly_eta.push_back(mline_[i][1]); } // Clip that poly against the slave poly one edge at a time for (int clipedge = 0; clipedge < nsnode; ++clipedge) { // point on that clip edge (dim 2) double* PE = &sline_[clipedge][0]; // the outward normal to the clip edge (dim 2) double* N = &sn_[clipedge][0]; ok = buildPoly(s_poly_xi, s_poly_eta, t_poly_xi, t_poly_eta, PE, N); if(!ok){ // there is no intersection between polys. However, it is possible that the // slave poly is completely contained within the master break; } // The target vectors now become the source vectors s_poly_xi = t_poly_xi; s_poly_eta = t_poly_eta; } // for (int clipedge=0; clipedge<3; ++clipedge) if(ok){ // We have a target polygon double xi[2]; // Compress the polygon by removing adjacent points less than epsilon apart for(unsigned int p = t_poly_xi.size() - 1; p >= 1; p--){ xi[0] = t_poly_xi[p] - t_poly_xi[p - 1]; xi[1] = t_poly_eta[p] - t_poly_eta[p - 1]; double dist = MOERTEL::length(xi, 2); if(dist <= eps){ // remove the point p t_poly_xi.erase(t_poly_xi.begin() + p); t_poly_eta.erase(t_poly_eta.begin() + p); } } // Check the last point too if(t_poly_xi.size() >= 2){ xi[0] = t_poly_xi[t_poly_xi.size() - 1] - t_poly_xi[0]; xi[1] = t_poly_eta[t_poly_xi.size() - 1] - t_poly_eta[0]; double dist = MOERTEL::length(xi, 2); if(dist <= eps){ // remove the point p t_poly_xi.erase(t_poly_xi.end() - 1); t_poly_eta.erase(t_poly_eta.end() - 1); } } // Do we still have a polygon? If not, just move on if(t_poly_xi.size() < 3){ return false; } // Store it in the polygon for (unsigned int p = 0; p < t_poly_xi.size(); ++p) { xi[0] = t_poly_xi[p]; xi[1] = t_poly_eta[p]; AddPointtoPolygon(p, xi); } #if 0 // make printout of the polygon so far { int np = SizePointPolygon(); std::vector<Teuchos::RCP<MOERTEL::Point> > point; PointView(point); std::cout << "Master is in slave" << std::endl; for (int p=0; p<np; ++p) { std::cout << "OVERLAP Clipelements: point " << std::setw(3) << point[p]->Id() << " xi " << point[p]->Xi()[0] << "/" << point[p]->Xi()[1] << std::endl; } point.clear(); } #endif return true; } //=========================================================================== // We come down here if there is no polygon from the above. This could mean that the slave segment is // completely inside the master segment. std::vector<int> s_node_id; for (int i=0; i<nsnode; ++i) { bool ok = true; // get the slave point in master coords double* P = sxim_[i]; // loop master clip edges for (int clipedge=0; clipedge<nmnode; ++clipedge) { // point on master clipedge double* PE = &mlinem_[clipedge][0]; // the outward normal to the clip edge (dim 2) double* N = &mn_[clipedge][0]; // clip point P against this edge // GAH - EPSILON clip test point ok = Clip_TestPoint(N,PE,P,1.0e-5); // put point in if (ok) continue; else { ok = false; break; } } // for (int clipedge=0; clipedge<3; ++clipedge) // We will be here, with ok == true only if the point is inside ALL clip edges // don't put point in if (!ok) continue; else { // Point is inside ALL clip edges s_node_id.push_back(i); } } // for (int i=0; i<3; ++i) if(s_node_id.size() < static_cast<unsigned int>(nsnode)){ // Slave poly does not lie within master either. // There is no overlap. Move on. /* The reasoning here is that zero of the master polygon was found in the slave (no nodes). If the slave is completely * within the master, then all 4 nodes need to cleanly show up inside the master. If they do not, chances are only * a corner or edge of the master is touched. */ return false; } // Slave is completely in master. Put the slave in the polygon for(unsigned int i = 0; i < s_node_id.size(); i++){ //std::cout << "OVERLAP Clipelements: inserting slave point " << 1000+i << " xi=" // << sxi_[i][0] << "/" << sxi_[i][1] << endl; AddPointtoPolygon(i,sxi_[i]); } #if 0 // make printout of the polygon so far { int np = SizePointPolygon(); std::vector<Teuchos::RCP<MOERTEL::Point> > point; PointView(point); std::cout << "Slave is in master" << std::endl; for (int p=0; p<np; ++p) { std::cout << "OVERLAP Clipelements: point " << std::setw(3) << point[p]->Id() << " xi " << point[p]->Xi()[0] << "/" << point[p]->Xi()[1] << std::endl; } point.clear(); } #endif return true; }
bool MoertelT::MOERTEL_TEMPLATE_CLASS_1A(OverlapT, IFace)::ConvexHull( std::map<int, Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(PointT)>>& p) { // # points int np = p.size(); // sort points by xi[0] coordinate std::vector<Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(PointT)>> points; PointView(p, points); std::vector<double> dlistx(np); std::vector<double> dlisty(np); std::vector<int> list2(np); for (int i = 0; i < np; ++i) { dlistx[i] = points[i]->Xi()[0]; list2[i] = i; } MOERTEL::sort(&dlistx[0], np, &list2[0]); // get assoc. y-list for (int i = 0; i < np; ++i) dlisty[i] = points[list2[i]]->Xi()[1]; // sort list again for those points where x is identical for (int i = 0; i < np - 1; ++i) if (dlistx[i] == dlistx[i + 1]) if (dlisty[i] > dlisty[i + 1]) { MOERTEL::swap(dlistx[i], dlistx[i + 1]); MOERTEL::swap(dlisty[i], dlisty[i + 1]); MOERTEL::swap(list2[i], list2[i + 1]); } // create a new polygon and put points in in sorted order std::map<int, Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(PointT)>> newp; for (int i = 0; i < np; ++i) { Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(PointT)> tmp = Teuchos::rcp(new MoertelT::MOERTEL_TEMPLATE_CLASS(PointT)( i, points[list2[i]]->Xi(), OutLevel())); newp.insert( std::pair<int, Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(PointT)>>( i, tmp)); } // delete the old one p.clear(); // copy new one over CopyPointPolygon(newp, p); // destroy the new one newp.clear(); points.clear(); std::map<int, Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(PointT)>>:: iterator pcurr; #if 0 // printout the polygon std::cout << "Input polygon:\n"; for (pcurr=p.begin(); pcurr != p.end(); ++pcurr) if (pcurr->second != Teuchos::null) std::cout << *(pcurr->second); #endif //=========================================================================== // build the upper hull std::map<int, Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(PointT)>> upper; PointView(p, points); // put in the first 2 points AddPointtoPolygon(upper, 0, points[0]->Xi()); // std::cout << *points[0]; AddPointtoPolygon(upper, 1, points[1]->Xi()); // std::cout << *points[1]; //--------------------------------------------------------------------------- for (int i = 2; i < np; ++i) { // add point[i] to upper AddPointtoPolygon(upper, i, points[i]->Xi()); // std::cout << *points[i]; // find whether we still have a convex hull while (upper.size() > 2 && !MakeRightTurnUpper(i, upper)) RemovePointBefore(i, upper); #if 0 // printout the current upper hull std::map<int,MoertelT::MOERTEL_TEMPLATE_CLASS(PointT)*>::iterator pcurr; for (pcurr=upper.begin(); pcurr != upper.end(); ++pcurr) if (pcurr->second) std::cout << *(pcurr->second); #endif } // for (int i=2; i<np; ++i) //=========================================================================== // build the lower hull std::map<int, Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(PointT)>> lower; // put in the first 2 points AddPointtoPolygon( lower, np - 1, points[np - 1]->Xi()); // std::cout << *points[np-1]; AddPointtoPolygon( lower, np - 2, points[np - 2]->Xi()); // std::cout << *points[np-2]; //--------------------------------------------------------------------------- for (int i = np - 3; i >= 0; --i) { // add point[i] to lower AddPointtoPolygon(lower, i, points[i]->Xi()); // std::cout << *points[i]; // find whether we still have a convex hull while (lower.size() > 2 && !MakeRightTurnLower(i, lower)) RemovePointAfter(i, lower); #if 0 // printout the current lower hull std::map<int,Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(PointT) > >::iterator pcurr; for (pcurr=lower.begin(); pcurr != lower.end(); ++pcurr) if (pcurr->second) std::cout << *(pcurr->second); #endif } // for (int i=np-3; i>=0; --i) //=========================================================================== points.clear(); //=========================================================================== // join upper and lower hull // note not to put in duplicate start and end point std::map<int, Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(PointT)>> finalp; // put upper hull in int i = 0; for (pcurr = upper.begin(); pcurr != upper.end(); ++pcurr) { // std::cout << *(pcurr->second); AddPointtoPolygon(finalp, i, pcurr->second->Xi()); ++i; } // put lower hull in, skip first and last point pcurr = lower.end(); --pcurr; --pcurr; for (; pcurr != lower.begin(); --pcurr) { // std::cout << *(pcurr->second); AddPointtoPolygon(finalp, i, pcurr->second->Xi()); ++i; } #if 0 // printout the polygon std::cout << "--------------------------------------------\n"; std::cout << "Final polygon:\n"; for (pcurr=finalp.begin(); pcurr != finalp.end(); ++pcurr) if (pcurr->second != Teuchos::null) std::cout << *(pcurr->second); #endif // compare size of convex hull polygon newp to size of p, all // nodes must be part of the convex hull if (finalp.size() != p.size()) { if (OutLevel() > 8) std::cout << "MOERTEL: ***WRN*** MOERTEL::Overlap::ConvexHull:\n" << "MOERTEL: ***WRN*** size of convex hull " << finalp.size() << " not # nodes " << p.size() << std::endl << "MOERTEL: ***WRN*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; } // copy the polygon over to the input map p p.clear(); upper.clear(); lower.clear(); CopyPointPolygon(finalp, p); finalp.clear(); return true; }