/** * Calculates the points where the meshes merge. * @param MeshList * meshList The list of meshes whose points must be calculated. */ void Polyhedron::getPoints(MeshList * meshList) { MeshList::iterator i1, i2, i3; PointList vert; /* Set a Vertices list. */ PointList::iterator vit; Point * temp; /* Going through the list of meshes and calculating the vertices of the polyhedron. */ for (i1 = meshList->begin(); i1 != meshList->end(); i1++) { vert.clear(); for (i2 = meshList->begin(); i2 != meshList->end(); i2++) { for (i3 = meshList->begin(); i3 != meshList->end(); i3++) { /* Getting the vertices of the face only if all the meshes are different. */ if (i1 != i2 && i1 != i3 && i2 != i3) { temp = Mesh::intersection(*(*i1), *(*i2), *(*i3)); if (temp != NULL) { vert.push_back(temp); vertices.push_back(temp); } } } } faces.push_back(new Face(&vertices, &(*i1)->normal)); } getOrigin(); }
void Init() { gInterList.clear(); GenerateConvex(gN,200,Point2D(200,200),gP); GenerateConvex(gM,200,Point2D(350,200),gQ); Point2D point; int i, j; for( i = 0 ; i < gN ; i++ ) for( j = 0 ; j < gM ; j++ ) { if( SegInterSeg(gP[i],gP[Next(i,gN)],gQ[j],gQ[Next(j,gM)],point) ) printf("(%d,%d)\n",i,j); } ConvexInterConvex(gP,gN,gQ,gM,gInterList); printf("%d\n",gInterList.size()); }
bool BoundBox::CheckPoint(float* P) { if(P[0]<bounds[0]) return false; if(P[0]>=bounds[3]) return false; if(P[1]<bounds[1]) return false; if(P[1]>=bounds[4]) return false; if(P[2]<bounds[2]) return false; if(P[2]>=bounds[5]) return false; p.limit = limit; if(!splitted) { p.add(P); count++; if(count < limit) return true; Split(); for(int i=0;i<count;i++) { float* _P = p[i]; for(int j=0;j<NODECOUNT;j++) { if(b[j].CheckPoint(_P)) break; }; }; p.clear(); return true; }; for(int i=0;i<NODECOUNT;i++) { if(b[i].CheckPoint(P)) break; }; return true; };
// clip the convex hull 'in' to plane to generate a clipped convex hull 'out' // return true if points remain after clipping. unsigned int clip(const Plane& plane,const PointList& in, PointList& out,unsigned int planeMask) { std::vector<float> distance; distance.reserve(in.size()); for(PointList::const_iterator itr=in.begin(); itr!=in.end(); ++itr) { distance.push_back(plane.distance(itr->second)); } out.clear(); for(unsigned int i=0;i<in.size();++i) { unsigned int i_1 = (i+1)%in.size(); // do the mod to wrap the index round back to the start. if (distance[i]>=0.0f) { out.push_back(in[i]); if (distance[i_1]<0.0f) { unsigned int mask = (in[i].first & in[i_1].first) | planeMask; float r = distance[i_1]/(distance[i_1]-distance[i]); out.push_back(Point(mask,in[i].second*r+in[i_1].second*(1.0f-r))); } } else if (distance[i_1]>0.0f) { unsigned int mask = (in[i].first & in[i_1].first) | planeMask; float r = distance[i_1]/(distance[i_1]-distance[i]); out.push_back(Point(mask,in[i].second*r+in[i_1].second*(1.0f-r))); } } return out.size(); }
PointList buildPolygon(Site_2 site, std::vector<PointList>& polylines) { // A list for the resulting points. PointList points; // We build this list from the polylines collected before. // One of the problems solved here is that we actually don't know // whether the polylines we get are in order or reversed because of the // way we obtained them via Hyperbola_2.generate_points which makes no // guarantees about the order of produces points. So we check at each // step whether a consecutive polyline has to be added in-order or // reversed by inspecting the first and last points respectively. A // special case is the first polyline, where we don't have a previous // polyline to perform this check for, which is why we make a more // extensive checking when adding the second polyline which also takes // care about the first. std::cerr << "# polylines: " << polylines.size() << std::endl; // the first polyline will just be added as it is if (polylines.size() > 0) { PointList seg = polylines.front(); points.insert(points.end(), seg.begin(), seg.end()); } // handle consecutive polylines if (polylines.size() > 1) { // check wheter we can use the second segment this way or whether we // have to reverse the first polyline. Use distance comparism to pick // the best fit (so that we don't need exact equivalence of endpoints) PointList seg = polylines.at(1); double d1 = CGAL::squared_distance(points.front(), seg.front()); double d2 = CGAL::squared_distance(points.front(), seg.back()); double d3 = CGAL::squared_distance(points.back(), seg.front()); double d4 = CGAL::squared_distance(points.back(), seg.back()); // if the first point of the first polyline fits both endpoints of the // second polyline better thant the last point of the first polyline, // then we reverse the order of the first polyline. if ((d1 < d3 && d1 < d4) || (d2 < d3 && d2 < d4)) { std::reverse(points.begin(), points.end()); } // for each consecutive polyline for (int i = 1; i < polylines.size(); i++) { // check which endpoint of this polyline is nearest to the last // point in our list of points. Point_2 lastPoint = points.back(); PointList seg = polylines.at(i); double d1 = CGAL::squared_distance(lastPoint, seg.front()); double d2 = CGAL::squared_distance(lastPoint, seg.back()); if (d1 <= d2) { // first point fits better, take polyline in default order points.insert(points.end(), ++seg.begin(), seg.end()); } else { // last point fits better, take polyline in reverse order points.insert(points.end(), ++seg.rbegin(), seg.rend()); } } } std::cerr << "# points: " << points.size() << std::endl; // close polygon if necessary if (points.size() > 0){ Point_2 start = points.front(); Point_2 end = points.back(); if (start != end) { points.push_back(start); } } if (points.size() > 0 && points.size() < 4) { std::cerr << "invalid polygon: >0 but <4 points" << std::endl; points.clear(); } return points; }