std::string pp(const Segment_2& segment) { std::stringstream out; out << std::setprecision(pp_precision); out << "[" << pp(segment.source()) << ", " << pp(segment.target()) << "]"; return out.str(); }
CONTOURTILER_BEGIN_NAMESPACE Segment_2 lexicographically_ordered(const Segment_2& s) { if (CGAL::lexicographically_xy_smaller(s.source(), s.target())) return s; return s.opposite(); }
void handleDual(Segment_2 s, std::vector<PointList>& polylines) { Point_2 ss = s.source(); Point_2 st = s.target(); PointList points; points.push_back(ss); points.push_back(st); polylines.push_back(points); }
std::string pp_id(const Segment_2& segment) { std::stringstream out; size_t a = segment.source().id(); size_t b = segment.target().id(); if (a > b) swap(a, b); out << a << "--" << b; return out.str(); }
void handleDual(Segment_2 s, std::vector<PointList>& polylines) { Point_2 ss = s.source(); Point_2 st = s.target(); std::cerr << "segment " << ss << " " << st << std::endl; // str << s; PointList points; points.push_back(ss); points.push_back(st); polylines.push_back(points); }
/// Returns true if the segment crosses a boundary line of the polygon. /// It is not enough for the segment to simply intersect the boundary /// line -- it must cross it such that the segment extends to both inside /// and outside of the boundary of the polygon. bool intersects_proper(const Segment_2& segment, const Polygon_2& polygon) { static log4cplus::Logger logger = log4cplus::Logger::getInstance("tiler.intersects_proper"); Point_2 seg_pts[] = { segment.source(), segment.target() }; // Get intersection points between segment and polygon LOG4CPLUS_TRACE(logger, "Doing a line sweep: " << pp(segment)); list<Segment_2> segments(polygon.edges_begin(), polygon.edges_end()); segments.push_back(segment); list<Point_2> points; get_intersection_points(segments.begin(), segments.end(), back_inserter(points), true, false); CGAL::Bounded_side side1 = polygon.bounded_side(seg_pts[0]); CGAL::Bounded_side side2 = polygon.bounded_side(seg_pts[1]); LOG4CPLUS_TRACE(logger, "Checking with cross checker"); if (points.size() == 0) return false; Cross_checker checker; checker.add(side1); checker.add(side2); if (checker.crosses()) return true; if (points.size() == 1) return false; points.push_back(seg_pts[0]); points.push_back(seg_pts[1]); points.sort(); list<Point_2>::iterator it0 = points.begin(); list<Point_2>::iterator it1 = it0; ++it1; while (it1 != points.end()) { const Point_2& p0 = *it0; const Point_2& p1 = *it1; // find an intermediate point and test for where it is Point_2 midpoint((p0.x()+p1.x())/2.0, (p0.y()+p1.y())/2.0); checker.add(polygon.bounded_side(midpoint)); if (checker.crosses()) return true; ++it0; ++it1; } return false; }
QList<Vector2D> Voronoi_Diagram::calculate(QList<Vector2D> in_points) { //consider some points std::vector<Point_2> points; for(int i=0;i<in_points.size();i++) { points.push_back(Point_2(in_points.at(i).x,in_points.at(i).y)); } Delaunay_triangulation_2 dt2; //insert points into the triangulation dt2.insert(points.begin(),points.end()); //construct a rectangle Iso_rectangle_2 bbox(Field::MinX,Field::MinY,Field::MaxX,Field::MaxY); Cropped_voronoi_from_delaunay vor(bbox); //extract the cropped Voronoi diagram dt2.draw_dual(vor); //print the cropped Voronoi diagram as segments std::stringstream ss; QList<Vector2D> out; wm->voronoi.clear(); for(int i=0;i<vor.m_cropped_vd.size();i++) { Segment_2 tmp = vor.m_cropped_vd.at(i); Point_2 start = tmp.vertex(0) , end = tmp.vertex(1); Vector2D first(floor(start.x()),floor(start.y())) , second(floor(end.x()),floor(end.y())); if( !out.contains(first) ) { if( wm->kn->IsInsideField(first) ) out.append(first); } if( !out.contains(second) ) { if( wm->kn->IsInsideField(second) ) out.append(second); } Segment2D seg(first,second); wm->voronoi.append(seg); } return out; }
void handleDual(Ray_2 r, Iso_rectangle_2 crect, std::vector<PointList>& polylines) { Object_2 o = CGAL::intersection(crect, r); Segment_2 seg; Point_2 pnt; if (assign(seg, o)) { Point_2 ss = seg.source(); Point_2 st = seg.target(); PointList points; points.push_back(ss); points.push_back(st); polylines.push_back(points); } else if (assign(pnt, o)){ // no use for points } }
// 2D voronoi cell area double CGAL_Delaunay2_cell_area(Delaunay2* obj, Del2D_Vertex_handle v) { Delaunay2::Edge_circulator ec=obj->incident_edges(v),done(ec); if (ec != 0) { double area=0,tmp=0; Point_2 p=v->point(); Segment_2 segment; do { CGAL::Object o = obj->dual(ec); if(CGAL::assign(segment,o)) { tmp = (CGAL::area(p,segment.source(),segment.target())); //printf("area tmp=%lf\n",tmp); area += tmp; } //else return -1; } while(++ec != done); return area; } return -1; }
void handleDual(Line_2 l, Iso_rectangle_2 crect, std::vector<PointList>& polylines) { std::cerr << "line" << std::endl; //str << l; Object_2 o = CGAL::intersection(l, crect); Segment_2 seg; Point_2 pnt; if (assign(seg, o)) { std::cerr << "line -> segment" << std::endl; Point_2 ss = seg.source(); Point_2 st = seg.target(); PointList points; points.push_back(ss); points.push_back(st); polylines.push_back(points); } else if (assign(pnt, o)){ std::cerr << "line -> point" << std::endl; // no use for points } }
std::pair<Point_2, Point_2> CPPolygon::either_side(const Point_2& p) const { // Find the edge Segment_2 s; for (Polygon_2::Edge_const_iterator it = _p.edges_begin(); it != _p.edges_end(); ++it) { if (CGAL::squared_distance(p, *it) < TOL_SQ) { s = *it; } } // Don't travel more than 2*TOL on either side const Vector_2 v = normalized(s.to_vector()); const Point_2 p0 = p + 2*TOL * v; const Point_2 p1 = p - 2*TOL * v; return make_pair(p0, p1); // const double slen = sqrt(s.squared_length()); // const double t = sqrt(Segment_2(s.source(), p).squared_length()) / slen; // const Point_2 p0 = p + t * v; // const Point_2 p1 = p - t * v; // return make_pair(p0, p1); }
bool operator<(const Segment_2& a, const Segment_2& b) { if (a.source() == b.source()) { return a.target() < b.target(); } return a.source() < b.source(); }
void handleDual(Ray_2 r, Iso_rectangle_2 crect, std::vector<PointList>& polylines) { std::cerr << "ray" << std::endl; // str << r; Object_2 o = CGAL::intersection(crect, r); Segment_2 seg; Point_2 pnt; if (assign(seg, o)) { std::cerr << "ray -> segment" << std::endl; Point_2 ss = seg.source(); Point_2 st = seg.target(); PointList points; points.push_back(ss); points.push_back(st); polylines.push_back(points); } else if (assign(pnt, o)){ std::cerr << "ray -> point" << std::endl; // no use for points } else { std::cerr << "ray -> ?" << std::endl; std::cerr << r.source() << " " << r.point(1) << std::endl; } }
int voronoi_tessellation(TreeNode &tn) { assert(tn.region.is_convex()); // tn.regionは凸であることを前提 assert(tn.children.size() >= 2); PD2 pd2; std::list<TreeNode>::iterator cit; for (cit = tn.children.begin(); cit != tn.children.end(); ++cit) { cit->face = pd2.insert(cit->p); cit->region = Polygon_2(); // 全部初期化しておく } assert( pd2.is_valid() ); PD2::Delaunay_graph dg = pd2.dual(); PD2::Delaunay_graph::Finite_vertices_iterator vit; for (vit = dg.finite_vertices_begin(); vit != dg.finite_vertices_end(); ++vit) { // tn.regionとintersectする。Ray/Lineは切り取られてSegmentとなる。 PD2::Delaunay_graph::Edge_circulator eci = dg.incident_edges(vit); PD2::Delaunay_graph::Edge_circulator ece = eci; std::set<Point_2> point_set; if (eci != NULL) { Polygon_2::Vertex_iterator pvit; do { Line_2 l; Ray_2 r; Segment_2 s; if (!dg.is_infinite(eci)) { CGAL::Object o = dg.dual(eci); if (CGAL::assign(s, o)) { // std::cout << "Segment: (" << s.source().x() << ", " << s.source().y() << ") (" << s.target().x() << ", " << s.target().y() << ")" << std::endl; if (tn.region.bounded_side(s.source()) != CGAL::ON_UNBOUNDED_SIDE) { point_set.insert(s.source()); } if (tn.region.bounded_side(s.target()) != CGAL::ON_UNBOUNDED_SIDE) { point_set.insert(s.target()); } Polygon_2::Edge_const_iterator eit; for (eit = tn.region.edges_begin(); eit != tn.region.edges_end(); ++eit) { CGAL::Object obj = CGAL::intersection(*eit, s); Point_2 p; Segment_2 seg; if (CGAL::assign(p, obj)) { point_set.insert(p); } else if (CGAL::assign(seg, obj)) { assert(false); } } } if (CGAL::assign(r, o)) { // std::cout << "Ray: (" << r.source().x() << ", " << r.source().y() << ") " << r << std::endl; if (tn.region.bounded_side(r.source()) != CGAL::ON_UNBOUNDED_SIDE) { point_set.insert(r.source()); } Polygon_2::Edge_const_iterator eit; for (eit = tn.region.edges_begin(); eit != tn.region.edges_end(); ++eit) { CGAL::Object obj = CGAL::intersection(*eit, r); Point_2 p; Segment_2 seg; if (CGAL::assign(p, obj)) { point_set.insert(p); } else if (CGAL::assign(seg, obj)) { assert(false); } } } if (CGAL::assign(l, o)) { // std::cout << "Line: (" << l.point(0).x() << ", " << l.point(0).y() << ") (" << l.direction().dx() << ", " << l.direction().dy() << ")" << std::endl; Polygon_2::Edge_const_iterator eit; for (eit = tn.region.edges_begin(); eit != tn.region.edges_end(); ++eit) { CGAL::Object obj = CGAL::intersection(*eit, l); Point_2 p; Segment_2 seg; if (CGAL::assign(p, obj)) { point_set.insert(p); } else if (CGAL::assign(seg, obj)) { assert(false); } } } } // infinite } while (++eci != ece); // tn.regionのpolygon中の点で、領域内のものをぜんぶ入れる for (pvit = tn.region.vertices_begin(); pvit != tn.region.vertices_end(); ++pvit) { /* // NOTE: locateはちょっとバグってるみたい。 // 代わりに、距離が最短な点を探す。 // NOTE: バグってないかも。代替ロジックでも問題が出た。 PD2::Locate_result lr = pd2.locate(*pvit); if (PD2::Vertex_handle *v = boost::get<PD2::Vertex_handle>(&lr)) { // 交わってるはず assert(false); } elsentersection if (PD2::Halfedge_handle *e = boost::get<Halfedge_handle>(&lr)) { // 交わってるはず assert(false); } else if (PD2::Face_handle *f = boost::get<Face_handle>(&lr)) { // 今対象としている点の領域だったら、追加 if ((*f)->dual()->point() == vit->point()) { point_set.insert(*pvit); } } */ // tn.regionの頂点と子供の頂点とのpower distanceを // すべて計算し、着目している子供に属するかを調べる cit = tn.children.begin(); Weighted_point_2 cp = cit->p; ++cit; for (; cit != tn.children.end(); ++cit) { if (CGAL::compare_power_distance(cp, cit->p, *pvit) == CGAL::LARGER) { cp = cit->p; } } if (cp == vit->point()) { // std::cout << "RegionPoint: (" << pvit->x() << ", " << pvit->y() << ")" << std::endl; point_set.insert(*pvit); } } assert(point_set.size() != 1 && point_set.size() != 2); } // 対応する子供を見つける for (cit = tn.children.begin(); cit != tn.children.end(); ++cit) { if (vit->point() == cit->p) { // 自前でのソートが面倒なのでconvex hullを求めてPolygonを作る。 CGAL::ch_graham_andrew(point_set.begin(), point_set.end(), std::inserter(cit->region, cit->region.vertices_begin())); assert(point_set.size() == 0 || cit->region.size() > 0); assert(point_set.size() == cit->region.size()); // 頂点の数あってるはず assert(cit->region.area() <= tn.region.area()); } } } return 0; }
Segment_3 project_3(const Segment_2& s) { return Segment_3(s.source().point_3(), s.target().point_3()); }
Segment_2 sorted(const Segment_2& s) { if (s.source() > s.target()) { return s.opposite(); } return s; }