double rand_o0o1(void *d) { if( d == NULL ) { return dsfmt_genrand_open_open(&dsfmt_global_data); } else { dsfmt_t *p = (dsfmt_t*) d; return dsfmt_genrand_open_open(p); } }
void TreeNode::draw_region(cairo_t *cr) const { if (region.size() >= 3) { if (this->name) { Polygon_2::Vertex_circulator vcir, vend; vcir = vend = region.vertices_circulator(); Bbox_2 bbox = region.bbox(); cairo_pattern_t *fill = cairo_pattern_create_linear(bbox.xmin(), bbox.ymin(), bbox.xmax(), bbox.ymax()); cairo_pattern_add_color_stop_rgb(fill, 0.0, 1.0, 1.0, 1.0); /* L*a*b* 色空間 { double r, g, b; cl2pix(&r, &g, &b, dsfmt_genrand_open_open(&dsfmt), dsfmt_genrand_open_open(&dsfmt)); cairo_pattern_add_color_stop_rgb(fill, 1.0, r, g, b); } */ // 単なるRGB cairo_pattern_add_color_stop_rgb(fill, 1.0, dsfmt_genrand_open_open(&dsfmt), dsfmt_genrand_open_open(&dsfmt), dsfmt_genrand_open_open(&dsfmt)); cairo_move_to(cr, CGAL::to_double(vcir->x()), CGAL::to_double(vcir->y())); ++vcir; do { cairo_line_to(cr, CGAL::to_double(vcir->x()), CGAL::to_double(vcir->y())); ++vcir; } while (vcir != vend); cairo_line_to(cr, CGAL::to_double(vend->x()), CGAL::to_double(vend->y())); cairo_set_source(cr, fill); cairo_fill_preserve(cr); cairo_set_source_rgb(cr, 0.0, 0.0, 0.0); cairo_stroke(cr); cairo_pattern_destroy(fill); } } std::list<TreeNode>::const_iterator tit; for (tit = children.begin(); tit != children.end(); ++tit) { tit->draw_region(cr); } }
// TODO: 入れ違いにする。つまり、x/yそれぞれがuniqueとなるようにする。 void random_points_in_polygon(TreeNode &tn, NT local_epsilon) { Bbox_2 bbox = tn.region.bbox(); NT width = bbox.xmax() - bbox.xmin(); NT height = bbox.ymax() - bbox.ymin(); std::set<Point_2> pts; unsigned int i; do { Point_2 p(NT(dsfmt_genrand_open_open(&dsfmt)) * width + bbox.xmin(), NT(dsfmt_genrand_open_open(&dsfmt)) * height + bbox.ymin()); if (tn.region.bounded_side(p) == CGAL::ON_BOUNDED_SIDE) { pts.insert(p); } } while (pts.size() < tn.children.size()); bool loop; do { std::set<Point_2>::iterator pit; std::list<TreeNode>::iterator tit; loop = false; for (pit = pts.begin(), tit = tn.children.begin(); pit != pts.end() && tit != tn.children.end(); ++pit, ++tit) { tit->p = Weighted_point_2(*pit, 1.0); // weightの初期値は1 tit->adesired = tit->given_area / tn.children_sum_given_areas; // epsilon未満の領域は削除 if (tit->adesired < local_epsilon) { std::cout << "removed node: " << *tit << std::endl; tn.children_sum_given_areas -= tit->given_area; tn.children.erase(tit); // 削除したら、すべての点のadesiredは計算しなおし loop = true; break; } } } while (loop); }
/* generates a random number on (0,1) with 53-bit resolution */ inline static double randu (dsfmt_t *dsfmt) { return dsfmt_genrand_open_open(dsfmt); }