Example #1
0
void find_next_edge(Segment s, std::vector<Segment>& segments,
        std::set<int>& unusedIndexes, std::vector<Polygon_2>& rings) {
    if (unusedIndexes.empty()
            || prev_size == unusedIndexes.size()) {
        return;
    }

    prev_size = unusedIndexes.size();

    Point start = s.source();
    Point end = s.target();
    rings.back().push_back(end);

    std::vector<int> nextIndexes;
    for (unsigned int i = 0; i < segments.size(); i++) {
        if (unusedIndexes.find(i) != unusedIndexes.end()) {
            Point source = segments.at(i).source();
            if (source == end) {
                nextIndexes.push_back(i);
            }
        }
    }
    if (nextIndexes.size() == 1) {
        int i = nextIndexes.at(0);
        unusedIndexes.erase(i);
        find_next_edge(segments.at(i), segments, unusedIndexes, rings);
    } else if (nextIndexes.size() > 1) {
        std::vector< std::pair<double, int> > nextAngles;
        for (unsigned int i = 0; i < nextIndexes.size(); i++) {
            int j = nextIndexes.at(i);
            Point target = segments.at(j).target();
            double angle = get_angle(start, end, target);
            nextAngles.push_back(std::pair<double, int>(angle, j));
        }
        std::sort(nextAngles.begin(), nextAngles.end());
        int i = nextAngles.begin()->second;
        unusedIndexes.erase(i);
        find_next_edge(segments.at(i), segments, unusedIndexes, rings);
    }

    if (!unusedIndexes.empty()) {
        for (unsigned int i = 0; i < segments.size(); i++) {
            if (unusedIndexes.find(i) != unusedIndexes.end()) {
                Polygon_2 ring;
                ring.push_back(segments.at(i).source());
                rings.push_back(ring);
                unusedIndexes.erase(i);
                find_next_edge(segments.at(i), segments, unusedIndexes, rings);
            }
        }
    }
}
Example #2
0
int alpha_shape(vertex_t *vertices, size_t count, double alpha,
                vertex_t **res, size_t *res_count, char **err_msg)
{
    try {
  std::list<Point> points;

  {
    std::vector<Point> pv;

    for (std::size_t j = 0; j < count; ++j) {
        Point p(vertices[j].x, vertices[j].y);
        pv.push_back(p);
    }

    std::sort(pv.begin(), pv.end(),
        [](const Point &e1, const Point &e2)->bool {
        return e2.y() < e1.y();
        });
    std::stable_sort(pv.begin(), pv.end(),
        [](const Point &e1, const Point &e2)->bool {
        return e2.x() < e1.x();
        });
    pv.erase(std::unique(pv.begin(), pv.end()), pv.end());
    if (pv.size() != count &&  pv.size() < 3) {
        *err_msg = strdup("After eliminating duplicated points, less than 3 points remain!!. Alpha shape calculation needs at least 3 vertices.");
        return -1;
    }
    points.insert(points.begin(), pv.begin(), pv.end());
  }

  Alpha_shape_2 A(points.begin(), points.end(),
                  coord_type(10000),
                  Alpha_shape_2::REGULARIZED);
  
  std::vector<Segment> segments;
//  std::vector<Segment> result;

//  Alpha_shape_2::Alpha_shape_vertices_iterator vit;
//  Alpha_shape_2::Vertex_handle vertex;
//  Alpha_shape_2::Alpha_shape_edges_iterator eit;
//  Alpha_shape_2::Edge edge;
//  Alpha_shape_2::Face_iterator fit;
//  Alpha_shape_2::Face_handle face;
  
  if (alpha <= 0.0)
  {
    alpha = *A.find_optimal_alpha(1);
  }
  A.set_alpha(alpha);

  alpha_edges( A, std::back_inserter(segments));

//  Segment s = segments.at(0);
//  find_next_edge(s, segments, result);
  if (segments.empty())
  {
    *res = NULL;
    *res_count = 0;
  }
  else
  {
    std::set<int> unusedIndexes;
    for (unsigned int i = 0; i < segments.size(); i++)
    {
      unusedIndexes.insert(i);
    }
    
    std::vector<Polygon_2> rings;
    Polygon_2 ring;
    ring.push_back(segments.at(0).source());
    rings.push_back(ring);
    unusedIndexes.erase(0);
    find_next_edge(segments.at(0), segments, unusedIndexes, rings);

    size_t result_count = 0;
    for (unsigned int i = 0; i < rings.size(); i++)
    {
      Polygon_2 ring = rings.at(i);
      result_count += ring.size();
    }
    result_count += rings.size() - 1;
    *res = (vertex_t *) malloc(sizeof(vertex_t) * result_count);
    *res_count = result_count;

    int idx = 0;
    for (unsigned int i = 0; i < rings.size(); i++)
    {
      if (i > 0)
      {
        (*res)[idx].x = DBL_MAX;
        (*res)[idx].y = DBL_MAX;
        idx++;
      }
      Polygon_2 ring = rings.at(i);
      for(unsigned int j = 0; j < ring.size(); j++)
      {
        Point point = ring.vertex(j);
        (*res)[idx].x = point.x();
        (*res)[idx].y = point.y();
        idx++;
      }
    }
  }
  *err_msg = NULL;

  return EXIT_SUCCESS;
    } catch ( ... ) {
        *err_msg = strdup("Caught unknown expection!");
    }
        return -1;

}