Commit c68f72f6 authored by Deepak Rangarajan's avatar Deepak Rangarajan Committed by Mark Meredith
Browse files

Resolve "polygon signed distance instead of bool inside"

parent b73fc9ed
Loading
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
#include "csg_cgal_helper.hpp"

#include <limits>

namespace {
typedef CGAL::Point_2<cgal_helper::CK> Point;
typedef cgal_helper::CK::Segment_2 Segment;
} // namespace

namespace cgal_helper {
@@ -31,4 +34,19 @@ bool inside(const Polygon &polygon, double xx, double yy) {
  return polygon.has_on_bounded_side(Point(xx, yy));
}

double abs_max_distance(const Polygon &polygon, double xx, double yy,
                        bool inside) {
  double dist = -std::numeric_limits<double>::max();
  auto m = Point(xx, yy);

  double sign = inside ? -1.0 : 1.0;

  for (auto e = polygon.edges_begin(); e != polygon.edges_end(); ++e) {
    auto d = sign * CGAL::squared_distance(*e, m);
    dist = std::max(dist, d);
  }

  return std::fabs(dist);
}

} // namespace cgal_helper
+6 −2
Original line number Diff line number Diff line
@@ -89,8 +89,12 @@ double signed_distance_2d(const Circle &cir, double xx, double yy) {

double signed_distance_2d(const Polygon &polygon, double xx, double yy) {

  // TODO: support signed distance instead of -1.0/1.0
  return cgal_helper::inside(polygon.cgal_polygon(), xx, yy) ? 1.0 : -1.0;
  bool inside = cgal_helper::inside(polygon.cgal_polygon(), xx, yy);
  double sign = inside ? -1.0 : 1.0;
  double dist =
      cgal_helper::abs_max_distance(polygon.cgal_polygon(), xx, yy, inside);

  return EXTERNAL_FLOW * sign * dist;
}

double signed_distance_2d(const Type2D &obj, double xx, double yy) {
+80 −8
Original line number Diff line number Diff line
@@ -10,7 +10,7 @@ TEST_CASE("linear", "[Levelset Extrude]") {
  double height = 100, radius = 10;
  auto my_lin_ext = csg::LinearExtrude{
      .height = 100, .center = false, .scale = {1, 1}, .group = csg::Union2D()};
  csg::Circle my_cir{.name = std::nullopt, .radius = 10};
  csg::Circle my_cir{.name = std::nullopt, .radius = radius};

  SECTION("Not centered") {
    my_lin_ext.center = false;
@@ -21,15 +21,37 @@ TEST_CASE("linear", "[Levelset Extrude]") {

    SECTION("Outside") {
      CHECK_FALSE(0 < my_levelset(0, radius * 0.99, -0.01 * height));
      CHECK(Approx(-0.01 * height) ==
            my_levelset(0, radius * 0.99, -0.01 * height));

      CHECK_FALSE(0 < my_levelset(0, radius * 1.01, 0.01 * height));
      CHECK(Approx((radius) * (radius) - (1.01 * radius) * (1.01 * radius)) ==
            my_levelset(0, radius * 1.01, 0.01 * height));

      CHECK_FALSE(0 < my_levelset(0, radius * 0.99, 1.01 * height));
      CHECK(Approx(-0.01 * height) ==
            my_levelset(0, radius * 0.99, 1.01 * height));

      CHECK_FALSE(0 < my_levelset(radius * 0.99, 0, 1.01 * height));
      CHECK(Approx(-0.01 * height) ==
            my_levelset(radius * 0.99, 0, 1.01 * height));
    }
    SECTION("Inside") {
      CHECK(0 < my_levelset(0, radius * 0.99, 0.01 * height));
      CHECK(Approx(0.01 * height) ==
            my_levelset(0, radius * 0.99, 0.01 * height));

      CHECK(0 < my_levelset(radius * 0.99, 0, 0.01 * height));
      CHECK(0 < my_levelset(0, radius * 0.99, 0.99 * height));
      CHECK(0 < my_levelset(radius * 0.99, 0, 0.99 * height));
      CHECK(Approx(0.01 * height) ==
            my_levelset(radius * 0.99, 0, 0.01 * height));

      CHECK(0 < my_levelset(0, radius * 0.99, 0.9 * height));
      CHECK(Approx((radius) * (radius) - (0.99 * radius) * (0.99 * radius)) ==
            my_levelset(0, radius * 0.99, 0.9 * height));

      CHECK(0 < my_levelset(radius * 0.99, 0, 0.9 * height));
      CHECK(Approx((radius) * (radius) - (0.99 * radius) * (0.99 * radius)) ==
            my_levelset(radius * 0.99, 0, 0.9 * height));
    }
  }

@@ -42,15 +64,37 @@ TEST_CASE("linear", "[Levelset Extrude]") {

    SECTION("Outside") {
      CHECK_FALSE(0 < my_levelset(0, radius * 0.99, -1.01 * height / 2));
      CHECK(Approx(-0.01 * height / 2) ==
            my_levelset(0, radius * 0.99, -1.01 * height / 2));

      CHECK_FALSE(0 < my_levelset(0, radius * 1.01, 0.01 * height));
      CHECK(Approx((radius) * (radius) - (1.01 * radius) * (1.01 * radius)) ==
            my_levelset(0, radius * 1.01, 0.01 * height));

      CHECK_FALSE(0 < my_levelset(0, radius * 0.99, 1.01 * height / 2));
      CHECK(Approx(-0.01 * height / 2) ==
            my_levelset(0, radius * 0.99, 1.01 * height / 2));

      CHECK_FALSE(0 < my_levelset(radius * 0.99, 0, 1.01 * height / 2));
      CHECK(Approx(-0.01 * height / 2) ==
            my_levelset(radius * 0.99, 0, 1.01 * height / 2));
    }
    SECTION("Inside") {
      CHECK(0 < my_levelset(0, radius * 0.99, -0.99 * height / 2));
      CHECK(Approx(0.01 * height / 2) ==
            my_levelset(0, radius * 0.99, -0.99 * height / 2));

      CHECK(0 < my_levelset(radius * 0.99, 0, 0.01 * height / 2));
      CHECK(Approx((radius) * (radius) - (0.99 * radius) * (0.99 * radius)) ==
            my_levelset(radius * 0.99, 0, 0.01 * height / 2));

      CHECK(0 < my_levelset(0, radius * 0.99, 0.99 * height / 2));
      CHECK(0 < my_levelset(radius * 0.99, 0, 0.99 * height / 2));
      CHECK(Approx(0.01 * height / 2) ==
            my_levelset(0, radius * 0.99, 0.99 * height / 2));

      CHECK(0 < my_levelset(radius * 0.99, 0, 0.9 * height / 2));
      CHECK(Approx((radius) * (radius) - (0.99 * radius) * (0.99 * radius)) ==
            my_levelset(radius * 0.99, 0, 0.9 * height / 2));
    }
  }
}
@@ -157,19 +201,47 @@ TEST_CASE("Linear extrude of a triangle with hole", "[Levelset Primitives]") {

  SECTION("Outside") {
    CHECK_FALSE(0 < my_levelset(0.5 * thick, 0.5 * thick, 1.01 * (ht / 2)));
    CHECK(Approx(-0.01 * ht / 2) ==
          my_levelset(0.5 * thick, 0.5 * thick, 1.01 * (ht / 2)));

    CHECK_FALSE(0 < my_levelset(0.5 * thick, 0.5 * thick, -1.01 * (ht / 2)));
    CHECK_FALSE(0 < my_levelset(2 * thick, 2 * thick, 0.0));
    CHECK_FALSE(0 < my_levelset(4 * thick, 2 * thick, 0.0));
    CHECK(Approx(-0.01 * ht / 2) ==
          my_levelset(0.5 * thick, 0.5 * thick, -1.01 * (ht / 2)));

    CHECK_FALSE(0 < my_levelset(1.5 * thick, 1.5 * thick, 0.0));
    CHECK(Approx(-(0.5 * thick) * (0.5 * thick)) ==
          my_levelset(1.5 * thick, 1.5 * thick, 0.0));

    CHECK_FALSE(0 < my_levelset(1.01 * outer, 0.5 * thick, 0.0));
    CHECK(Approx(-(1.01 * outer) * (1.01 * outer)) ==
          my_levelset(1.01 * outer, 0.5 * thick, 0.0));

    CHECK_FALSE(0 < my_levelset(0.5 * thick, 1.01 * outer, 0.0));
    CHECK(Approx(-(1.01 * outer) * (1.01 * outer)) ==
          my_levelset(0.5 * thick, 1.01 * outer, 0.0));

    CHECK_FALSE(0 < my_levelset(inner, inner, 0.0));
    CHECK(Approx(-inner * inner) == my_levelset(inner, inner, 0.0));
  }
  SECTION("Inside") {
    CHECK(0 < my_levelset(0.5 * thick, 0.5 * thick, 0.99 * (ht / 2)));
    CHECK(Approx(0.01 * ht / 2) ==
          my_levelset(0.5 * thick, 0.5 * thick, 0.99 * (ht / 2)));

    CHECK(0 < my_levelset(0.5 * thick, 0.5 * thick, -0.99 * (ht / 2)));
    CHECK(0 < my_levelset(0.5 * thick, 0.5 * thick, 0.0));
    CHECK(0 < my_levelset(0.7 * outer, 0.5 * thick, 0.0));
    CHECK(Approx(0.01 * ht / 2) ==
          my_levelset(0.5 * thick, 0.5 * thick, -0.99 * (ht / 2)));

    CHECK(0 < my_levelset(0.1 * thick, 0.5 * thick, 0.0));
    CHECK(Approx((0.1 * thick) * (0.1 * thick)) ==
          my_levelset(0.1 * thick, 0.5 * thick, 0.0));

    CHECK(0 < my_levelset(0.7 * outer, 0.1 * thick, 0.0));
    CHECK(Approx((0.1 * thick) * (0.1 * thick)) ==
          my_levelset(0.7 * outer, 0.1 * thick, 0.0));

    CHECK(0 < my_levelset(0.5 * thick, 0.7 * outer, 0.0));
    CHECK(Approx(ht / 2) == my_levelset(0.5 * thick, 0.7 * outer, 0.0));
  }
}

+1 −1
Original line number Diff line number Diff line
@@ -3,8 +3,8 @@
#include "catch2/catch.hpp"

#include <csg.hpp>
#include <csg_types.hpp>
#include <csg_matrix_functions.hpp>
#include <csg_types.hpp>

namespace {

+3 −0
Original line number Diff line number Diff line
@@ -23,6 +23,9 @@ bool inside(const Polyhedron &polyhedron, double xx, double yy, double zz);

bool inside(const Polygon &polygon, double xx, double yy);

double abs_max_distance(const Polygon &ploygon, double xx, double yy,
                        bool inside);

} // namespace cgal_helper

#endif
Loading