psemek/libs/cg/include/psemek/cg/dual.hpp

50 lines
1 KiB
C++

#pragma once
#include <psemek/cg/dcel.hpp>
namespace psemek::cg
{
template <typename Point, typename Edge, typename Face, typename Index>
dcel<Face, Edge, Point, Index> dual(dcel<Point, Edge, Face, Index> const & d)
{
dcel<Face, Edge, Point, Index> result;
result.edges.reserve(d.edges.size());
for (auto const & e : d.edges)
{
result.push_edge(e.data());
auto & n = result.edges.back();
n.twin = e.twin;
n.face = e.origin;
n.origin = d.edges[e.twin].face;
}
for (Index e = 0; e < result.edges.size(); ++e)
{
auto next = [&](auto i){ return d.edges[d.edges[i].twin].next; };
Index i = e, n = next(i);
for (; n != e; i = n, n = next(n));
result.edges[e].next = i;
}
result.points.reserve(d.faces.size());
for (auto const & f : d.faces)
{
result.push_point(f.data());
result.points.back().edge = d.edges[f.edge].twin;
}
result.faces.reserve(d.points.size());
for (auto const & p : d.points)
{
result.push_face(p.data());
result.faces.back().edge = p.edge;
}
return result;
}
}