50 lines
1 KiB
C++
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;
|
|
}
|
|
|
|
}
|