3 #include <vtestbed/config/real_type.hh>     4 #include <vtestbed/geometry/inertia_tensor.hh>     5 #include <vtestbed/geometry/line_segment.hh>     6 #include <vtestbed/geometry/math.hh>     7 #include <vtestbed/geometry/polygon.hh>     8 #include <vtestbed/geometry/polyline.hh>    12     template <
class T, 
int N>
    19         return (lhs.contains(rhs.front(), eps) && lhs.contains(rhs.back(), eps));
    24 template <
class T, 
int N>
    28     auto& segments = *
this;
    29     auto n = segments.size();
    31     for (size_type i=0; i<n; ++i) {
    32         for (size_type j=i+1; j<n; ++j) {
    33             const auto& s1 = segments[i];
    34             const auto& s2 = segments[j];
    37             if (near(s1,s2,eps) || near(s1,s3,eps) 
    39                 mask[i] = 
true, mask[j] = 
true;
    43     for (size_type i=n; i>0; --i) {
    46             segments.erase(segments.begin()+j);
    51 template <
class T, 
int N>
    55     auto& segments = *
this;
    56     auto n = segments.size();
    58     for (size_type i=0; i<n; ++i) {
    59         for (size_type j=0; j<n; ++j) {
    60             if (i == j) { 
continue; }
    61             auto& s1 = segments[i];
    62             const auto& s2 = segments[j];
    63             if (near(s1.back(), s2.front(), eps) &&
    64                 Line_segment<T,N>(s1.front(), s2.back()).contains(s1.back(), eps)) {
    65                 s1.back() = s2.back();
    66                 segments.erase(segments.begin()+j);
    74 template <
class T, 
int N>
    78     auto& segments = *
this;
    79     auto n = segments.size();
    80     if (n <= 3) { 
return; }
    82     auto p0 = std::max_element(
    83         segments.begin(), segments.end(),
    84         [] (const_reference lhs, const_reference rhs) {
    86             return cmp(lhs.front(), rhs.front());
    90     for (
const auto& s : segments) {
    91         std::clog << 
"near(s.front(), s.back(), eps)=" << near(s.front(), s.back(), eps) << std::endl;
    95         value_type candidate, orig;
    98         std::clog << 
"convex_hull.size()=" << convex_hull.size() << std::endl;
    99         for (size_type i=0; i<n; ++i) {
   100             const auto& s = segments[i];
   101             if (near(p0, s.front(), eps)) {
   109                     Vertex<T,N> v1 = s.back() - p0;
   110                     Vertex<T,N> v2 = candidate.back() - p0;
   115                     auto x1 = s.back()(0);
   116                     auto y1 = s.back()(1);
   117                     auto x2 = candidate.back()(0);
   118                     auto y2 = candidate.back()(1);
   119                     auto x3 = orig.back()(0);
   120                     auto y3 = orig.back()(1);
   121                     auto lhs = x2*y0 + x0*y1 + x1*y2;
   122                     auto rhs = x1*y0 + x2*y1 + x0*y2;
   123                     auto lhs2 = x3*y0 + x0*y1 + x1*y3;
   124                     auto rhs2 = x1*y0 + x3*y1 + x0*y3;
   125                     std::clog << 
"(lhs-rhs)=" << (lhs-rhs) << std::endl;
   126                     std::clog << 
"(lhs2-rhs2)=" << (lhs2-rhs2) << std::endl;
   127                     if (lhs2-rhs2 > diff) {
   135         std::clog << 
"candidate=" << candidate << std::endl;
   136         convex_hull.emplace_back(candidate);
   137         segments.erase(segments.begin()+idx);
   138         p0 = candidate.back();
   139     } 
while (!segments.empty() &&
   140             !near(convex_hull.front().front(), convex_hull.back().back(), eps));
   141     segments = std::move(convex_hull);
   147     using T = VTB_REAL_TYPE;
   148     Vertex<T,2> origin{T{}};
   149     for (
const auto& segment : *
this) {
   150         origin += segment[0];
   151         origin += segment[1];
   153     origin /= 2*this->size();
   154     for (
auto& segment : *
this) {
   155         auto d = det(origin, segment[0], segment[1]);
   156         if (d < 0) { segment.flip(); }
   160 template <
class T, 
int N>
   163     auto& segments = *
this;
   164     const auto n = segments.size();
   165     if (n <= 1) { 
return; }
   166     for (
size_t i=0; i<n; ++i) {
   167         const auto& back = segments[i].back();
   168         for (
size_t j=i+1; j<n; ++j) {
   169             const auto& front = segments[j].front();
   170             if (all(front == back)) {
   171                 if (j != i+1) { std::swap(segments[i+1], segments[j]); }
   178 template <
class T, 
int N>
   182     for (
const auto& segment : *
this) {
   183         result.emplace_back(segment.front());
   188 template <
class T, 
int N>
   191     for (
const auto& segment : *
this) { segment.gnuplot(out); out << 
"\n\n"; }
   194 template <
class T, 
int N>
   197     static const T mult[6] = {
   199         T{1}/T{6}, T{1}/T{6},
   200         T{1}/T{12}, T{1}/T{12},
   204     for (
const auto& segment : polyline) {
   205         const auto& v0 = segment.front();
   206         const auto& v1 = segment.back();
   207         auto x0 = v0(0), y0 = v0(1), x1 = v1(0), y1 = v1(1);
   208         auto x0y1 = x0*y1, y0x1 = y0*x1;
   209         auto cp = x0y1 - y0x1;
   211         intg[1] += cp*(x0 + x1);
   212         intg[2] += cp*(y0 + y1);
   213         intg[3] += cp*(y0*y0 + y0*y1 + y1*y1);
   214         intg[4] += cp*(x0*x0 + x0*x1 + x1*x1);
   215         intg[5] += cp*(x0y1 + 2*x0*y0 + 2*x1*y1 + y0x1);
   217     for (
int i=0; i<6; ++i) { intg[i] *= mult[i]; }
   220     m.centre(0) = intg[1], m.centre(1) = intg[2];
   221     if (m.mass != 0) { m.centre /= m.mass; }
   223     m.inertia.xx = intg[3] - m.mass*cm(0)*cm(0);
   224     m.inertia.yy = intg[4] - m.mass*cm(1)*cm(1);
   225     m.inertia.xy = intg[5] - m.mass*cm(0)*cm(1);
 Mass_moments< T, N > mass_moments(const Polyline< T, N > &polyline)
Calculate area, centroid and inertia tensor.
 
A polygon composed of line segments.
 
void gift_wrap()
Convex hull.