Beispiel #1
0
Polygon2D halfBanana(std::vector<Line2D>& lines) {
    int n = (int)lines.size() + 4;
    int l, r;
    std::vector<Line2D> deq(n);
    // infinite square boundary
    lines.push_back(Line2D(Vector2D(-INF, -INF), Vector2D( 1,  0)));
    lines.push_back(Line2D(Vector2D( INF, -INF), Vector2D( 0,  1)));
    lines.push_back(Line2D(Vector2D( INF,  INF), Vector2D(-1,  0)));
    lines.push_back(Line2D(Vector2D(-INF,  INF), Vector2D( 0, -1)));
    // sort
    std::sort(lines.begin(), lines.end(), cmpBySlope);
    // find intersection result
    l = 0;
    r = -1;
#define deqSize (r-l+1)
    for(int i=0; i<n; ++i) {
        if(deqSize > 0 && lines[i].parallel(deq[r])) {
            if(lines[i].side(deq[r].p0) >= 0) continue;
            if(deqSize == 1) {
                deq[r] = Line2D(lines[i]);
                continue;
            }
        }
        while(deqSize > 1 && lines[i].side(deq[r].intersect(deq[r-1])) <= 0) r--;
        while(deqSize > 1 && lines[i].side(deq[l].intersect(deq[l+1])) <= 0) l++;
        if(deqSize == 1 && deq[r].ang() + M_PI < lines[i].ang()) return Polygon2D();
        deq[++r] = Line2D(lines[i]);
    }
    while(deqSize > 1 && deq[l].side(deq[r].intersect(deq[r-1])) <= 0) r--;
    if(deqSize < 3) return Polygon2D();
    // generate polygon
    Polygon2D ret;
    for(int i=l; i<r; ++i) ret.push(deq[i].intersect(deq[i+1]));
    ret.push(deq[l].intersect(deq[r]));
    return ret;
}
Beispiel #2
0
/*
std::vector<Polygon> DecomposePolygonToConvexhulls(const Polygon& polygon) {
  using VHACD::IVHACD;

  TriangleMesh mesh = TriangulatePolygon(polygon);
  std::vector<float> points;
  points.reserve(2 * mesh.vertices.size());
  for (auto& vertex : mesh.vertices) {
    points.emplace_back(vertex(0));
    points.emplace_back(vertex(1));
  }

  std::vector<int> triangle_indices;
  triangle_indices.reserve(mesh.faces.size() * 3);
  for (auto& tr_idx : mesh.faces) {
    triangle_indices.emplace_back(tr_idx[0]);
    triangle_indices.emplace_back(tr_idx[1]);
    triangle_indices.emplace_back(tr_idx[2]);
  }

  IVHACD::Parameters params;
  //
  // params.m_maxNumVerticesPerCH = 8;
  params.m_oclAcceleration = false;
  IVHACD* vhacd_interface = VHACD::CreateVHACD();
  bool res = vhacd_interface->Compute(points.data(), 2, mesh.vertices.size(),
                                      triangle_indices.data(), 3,
                                      mesh.faces.size(), params);
  std::vector<Polygon> polygons;
  if (res) {
    size_t num_hulls = vhacd_interface->GetNConvexHulls();
    IVHACD::ConvexHull hull;
    for (size_t p = 0; p < num_hulls; ++p) {
      vhacd_interface->GetConvexHull(p, hull);
      for (size_t v = 0; v < hull.m_nPoints; ++v) {
        std::cout << p << " ";
        std::cout << hull.m_points[3 * v + 0] << " ";
        std::cout << hull.m_points[3 * v + 1] << " ";
        std::cout << hull.m_points[3 * v + 2] << "\n";
      }
    }
  } else {
    std::cerr << "convex hull decomposition not successfull! fall back to "
                 "triangulation!\n";
  }

  vhacd_interface->Clean();
  vhacd_interface->Release();
  exit(0);
  return polygons;
}
*/
std::vector<Polygon2D> ResolveIntersections(const Polygon2D& polygon) {
  // the polygon boundary maybe splitted during this process
  // auto paths = ResolveIntersectionsClosedPath(polygon.path);
  // auto holes = ResolveIntersectionsClosedPaths(polygon.holes);

  ClipperLib::Clipper clipper;
  ClipperLib::Path scaled_path = UScalePathDiaToClipper(polygon.path);
  clipper.AddPath(scaled_path, ClipperLib::ptSubject, true);

  /*
  for (auto& path : paths) {
    ClipperLib::Path scaled_path = UScalePathDiaToClipper(path);
    clipper.AddPath(scaled_path, ClipperLib::ptSubject, true);
  }*/

  for (auto& hole : polygon.holes) {
    ClipperLib::Path scaled_hole = UScalePathDiaToClipper(hole);
    clipper.AddPath(scaled_hole, ClipperLib::ptClip, true);
  }

  ClipperLib::PolyTree path_tree;
  clipper.StrictlySimple(true);
  clipper.Execute(ClipperLib::ctDifference, path_tree, ClipperLib::pftNonZero,
                  ClipperLib::pftNonZero);

  // iterating into the tree
  std::vector<Polygon2D> polygons;
  // only store the pointer to outer polygons
  std::unordered_map<ClipperLib::PolyNode*, size_t> polynode_map;
  for (ClipperLib::PolyNode* node_ptr = path_tree.GetFirst(); node_ptr;
       node_ptr = node_ptr->GetNext()) {
    ClipperLib::PolyNode* poly_ptr = node_ptr;
    while (poly_ptr && poly_ptr->IsHole()) {
      poly_ptr = poly_ptr->Parent;
    }
    if (polynode_map.find(poly_ptr) == polynode_map.end()) {
      polygons.emplace_back(Polygon2D());
      polygons.back().path = DScalePathClipperToDia(poly_ptr->Contour);
      polynode_map[poly_ptr] = polygons.size() - 1;
    } else {
      polygons[polynode_map[poly_ptr]].holes.emplace_back(
          DScalePathClipperToDia(node_ptr->Contour));
    }
  }
  return polygons;
}
Beispiel #3
0
/*!

 */
Polygon2D
ConvexHull::toPolygon() const
{
    return Polygon2D( M_vertices );
}