Ejemplo n.º 1
0
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;
        }
}
Ejemplo n.º 2
0
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;
}