Giter Site home page Giter Site logo

convexdecomposition's Introduction

ConvexDecomposition

What does this library do?

This is a header only C++ library, made for decomposing and slicing concave polygons into convex polygons. This library also allows for user defined polygon slicing (see usage).

The ConcavePolygon class uses a recursive data structure to either store 0 or 2 sub polygons. When a polygon is sliced, two sub polygons are generated split along a defined line segment.

Credits: The algorithm for decomposing concave polygons to convex can be found here: https://mpen.ca/406/bayazit (Mark Bayazit). Convex decomposition is achieved in O(n*r) time, where n is the number of polygon vertices, r is the number of reflex polygon vertices.

Installation

To install this library, simply copy ConcavePolygon.h into your project and #include "ConcavePolygon.h".

Usage

Example: Creating a concave polygon, decomposing, and acquiring convex subpolygons

#include "ConcavePolygon.h"

#include <vector>

int main()
{
    // Create a vector of vertices
    std::vector<cxd::Vertex > vertices =
    {
        cxd::Vec2({0.0f, 1.0f}),
        cxd::Vec2({-1.0f, 0.0f}),
        cxd::Vec2({0.0f, 0.5f}),
        cxd::Vec2({1.0f, 0.0f})
    };

    // Create polygon from these vertices
    cxd::ConcavePolygon concavePoly(vertices);

    // Perform convex decomposition on polygon
    concavePoly.convexDecomp();

    // Retrieve a decomposed convex subpolygon by index
    // We still use the concave poly type here
    cxd::ConcavePolygon subPolygon = concavePoly.getSubPolygon(0);

    // Retrieve vertices from the subpolygon (also applies to the
    // concave polygon we defined earlier)
    std::vector<cxd::Vertex > subPolyVerts = subPolygon.getVertices();

    // Create a vector and retrieve all convex subpolygons
    // as a single list
    std::vector<cxd::ConcavePolygon > subPolygonList;
    concavePoly.returnLowestLevelPolys(subPolygonList);


    return 0;
}

Example: Creating a polygon and slicing it along a defined line segment

#include "ConcavePolygon.h"

#include <vector>

int main()
{
    // Create a vector of vertices
    std::vector<cxd::Vertex > vertices =
    {
        cxd::Vec2({0.0f, 1.0f}),
        cxd::Vec2({-1.0f, 0.0f}),
        cxd::Vec2({0.0f, -1.0f}),
        cxd::Vec2({1.0f, 0.0f})
    };

    // Create polygon from these vertices
    cxd::ConcavePolygon concavePoly(vertices);

    // Create a valid line segment to slice the polygon.
    // Note: The line segment must pass through two polygon
    // edges in order to slice. Here we define the start
    // and end positions of the line segment.
    cxd::LineSegment line(cxd::Vec2({-2.0f, 0.0f}),
                          cxd::Vec2({ 2.0f, 0.0f}));

    // Slice the polygon along this line segment
    concavePoly.slicePolygon(line);

    // Retrieve a decomposed subpolygons by index
    // This works exactly the same when retrieving subpolygons
    // after convex decomposition
    cxd::ConcavePolygon subPolygon = concavePoly.getSubPolygon(0);

    // Retrieve vertices from the subpolygon (also applies to the
    // concave polygon we defined earlier)
    std::vector<cxd::Vertex > subPolyVerts = subPolygon.getVertices();

    // Create a vector and retrieve all convex subpolygons
    // as a single list
    std::vector<cxd::ConcavePolygon > subPolygonList;
    concavePoly.returnLowestLevelPolys(subPolygonList);

    return 0;
}

convexdecomposition's People

Contributors

mjjq avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

convexdecomposition's Issues

License?

Is it intentional that this code is released without a license - if no, any chance that you will release it under the MIT license or similar?

Incorrect decomposition result

I noticed the library seems to lose some points in the result with some inputs such as this one:

#include "ConcavePolygon.h"

int main() {
  std::vector<cxd::Vertex> verts({
      cxd::Vec2({5.729166, 0.000002}),
      cxd::Vec2({2.604166, 0.000002}),
      cxd::Vec2({-0.520836, 3.125002}),
      cxd::Vec2({-6.770838, 3.125002}),
      cxd::Vec2({-6.770838, -3.124998}),
      cxd::Vec2({5.729166, -3.124998}),
  });

  cxd::ConcavePolygon poly(std::move(verts));
  poly.convexDecomp();

  std::vector<cxd::ConcavePolygon> result;
  poly.returnLowestLevelPolys(result);

  int i = 0;
  for (const auto& p : result) {
    printf("--- polygon %d:\n", ++i);
    for (const auto& v : p.getVertices())
      printf("%f, %f\n", v.position.x, v.position.y);
  }
}

In this case the point (-0.520836, 3.125002) is missing from the output.

Some inputs causing infinite recursion

Hi, the following input causes an infinite recursion, resulting in a stack overflow:

#include "ConcavePolygon.h"

int main()
{
    std::vector<cxd::Vertex > vertices =
    {
        cxd::Vec2({0.500000000000, 0.500000000000}),
        cxd::Vec2({0.500000000000, -0.498161792755}),
        cxd::Vec2({-0.497167110443, -0.498161792755}),
        cxd::Vec2({-0.497167110443, 0.277573525906}),
        cxd::Vec2({-0.415014147758, 0.273897051811}),
        cxd::Vec2({-0.349858343601, 0.297794103622}),
        cxd::Vec2({-0.168555259705, 0.435661762953}),
        cxd::Vec2({-0.151558041573, 0.465073525906}),
        cxd::Vec2({-0.151558041573, 0.500000000000}),
        cxd::Vec2({-0.072237968445, 0.500000000000}),
        cxd::Vec2({-0.043909311295, 0.430147051811}),
        cxd::Vec2({-0.024079322815, 0.408088237047}),
        cxd::Vec2({0.038243621588, 0.376838237047}),
        cxd::Vec2({0.109065175056, 0.367647051811}),
        cxd::Vec2({0.160056650639, 0.369485288858}),
        cxd::Vec2({0.245042502880, 0.393382370472}),
        cxd::Vec2({0.301699697971, 0.441176474094}),
        cxd::Vec2({0.332861185074, 0.500000000000})
    };

    cxd::ConcavePolygon concavePoly(vertices);
    concavePoly.convexDecomp(0);

    std::vector<cxd::ConcavePolygon> subPolygonList;
    concavePoly.returnLowestLevelPolys(subPolygonList);

    std::cout << "Num Polys: " << subPolygonList.size() << std::endl;

    return 0;
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.