Boost.Voronoi генерирует неправильные ячейки Вороного с вводом с плавающей запятой в C++C++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Boost.Voronoi генерирует неправильные ячейки Вороного с вводом с плавающей запятой в C++

Сообщение Anonymous »

Я работаю с экспериментальными данными, показывающими положение головы пешеходов в метрах в помещении. Моя цель — сгенерировать на C++ ячейки Вороного, окружающие каждого пешехода, что позволит мне вычислить площади этих ячеек. Однако после создания ячеек Вороного с помощью Boost.Voroni и их построения я обнаружил, что ячейки нарисованы неправильноточки не разделены должным образом на отдельные ячейки, как ожидалось.
В документации Boost.Voronoi я наткнулся на примечание о том, что входные координаты по умолчанию должны быть целыми числами. Для работы с реальными координатами я определил собственный тип точки, который позволяет использовать значения с плавающей запятой.
Ниже приведен код, который я использовал для создания диаграммы Вороного и вывода данных. в текстовой форме. Этот код компилируется с помощью g++-13, но clang-tidy выдает ошибку при построении сегментов:

Код: Выделить всё

#include 
#include 
#include 

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

struct Position
{
using coordinate_type = double;

coordinate_type x, y;
};

using coordinate_type = Position::coordinate_type;
using segment_type = boost::polygon::segment_data;
using VoronoiDiagram = boost::polygon::voronoi_diagram;

/// settings necessarily for boost to be able to use Position as points:
template 
struct boost::polygon::geometry_concept { typedef point_concept type; };

template 
struct boost::polygon::point_traits
{
using coordinate_type = ::coordinate_type;

static inline coordinate_type get(const Position& point, boost::polygon::orientation_2d orient)
{
return (orient == boost::polygon::HORIZONTAL) ? point.x : point.y;
}
};
using polygonF = boost::geometry::model::polygon;

/// settings required to use boost::geometry::area(polygonF):
namespace boost { namespace geometry { namespace traits {

template 
struct tag {
using type = point_tag;
};

template 
struct coordinate_type {
using type = Position::coordinate_type;
};

template 
struct coordinate_system {
using type = cs::cartesian;
};

template 
struct dimension : boost::mpl::int_ {};

template 
struct access {
static double get(const Position& p) { return p.x; }
static void set(Position& p, const double& value) { p.x = value; }
};

template 
struct access {
static double get(const Position& p) { return p.y; }
static void set(Position& p, const double& value) { p.y = value; }
};
}}} // namespace boost::geometry::traits

polygonF verticesOfCell(const VoronoiDiagram::cell_type& voronoiCell)
{
polygonF polygon;

const auto* edge = voronoiCell.incident_edge();
do {
if (!edge)
{
break;
}

if (edge->is_primary())
{
if (edge->is_finite())
{
auto v0 = edge->vertex0();
auto v1 = edge->vertex1();
polygon.outer().emplace_back(v0->x(), v0->y());
polygon.outer().emplace_back(v1->x(), v1->y());
}
}
edge = edge->next();
} while (edge != voronoiCell.incident_edge());

return polygon;
}

int main(int argc, char *argv[])
{
//////////////// configuration points and segments:
std::vector  positions
= {Position{0.476191, -0.952381},  Position{-0, -0.952381},
Position{-0.476191, -0.952381}, Position{-0.476191, -1.42857},
Position{-0.952381, -1.42857},  Position{-1.90476, -0.952381},
Position{-1.42857, -1.42857},   Position{-1.90476, -1.42857},
Position{-2.38095, -1.90476},   Position{-1.42857, -2.38095},
Position{-1.42857, -1.90476},   Position{-0.952381, -2.85714},
Position{-0.952381, -3.33333},  Position{-0, -3.80952},
Position{0.952381, -4.28571},   Position{0.476191, -4.28571},
Position{0.476191, -3.80952},   Position{0.952381, -3.33333},
Position{0.476191, -3.33333},   Position{-0, -2.38095},
Position{0.476191, -2.38095},   Position{0.952381, -1.90476},
Position{0.476191, -1.90476},   Position{-0, -1.90476},
Position{0.476191, -0.476191},  Position{-0.952381, -0.952381},
Position{0.476191, -1.42857},   Position{-0.476191, -2.38095},
Position{-0.952381, -2.38095},  Position{-2.38095, -2.85714},
Position{-1.90476, -3.33333},   Position{-1.42857, -3.33333},
Position{-0, -2.85714},         Position{-0.476191, -2.85714},
Position{-0, -3.33333},         Position{-0, -4.76191},
Position{0.952381, -2.38095},   Position{0.952381, -2.85714},
Position{0.476191, -2.85714},   Position{-0.476191, -1.90476},
Position{0.952381, -3.80952},   Position{1.42857, -2.85714},
Position{1.90476, -2.38095},    Position{0.952381, -4.76191},
Position{-0.476191, -5.2381},   Position{0.476191, -5.2381},
Position{1.90476, -3.33333},    Position{-2.85714, -2.38095},
Position{-2.38095, -1.42857},   Position{-2.38095, -0.952381},
Position{-1.42857, -2.85714},   Position{-1.90476, -1.90476},
Position{1.42857, -1.90476},    Position{2.38095, -2.85714},
Position{2.38095, -1.42857},    Position{2.38095, -0.952381},
Position{1.90476, -1.42857},    Position{2.38095, -1.90476},
Position{-1.90476, -2.38095},   Position{0.952381, -0.952381},
Position{-3.33333, -3.33333},   Position{-3.80952, -2.38095},
Position{-3.80952, -1.42857},   Position{-3.33333, -1.90476},
Position{-3.33333, -0.952381},  Position{-0.476191, -4.28571},
Position{-0, -1.42857},         Position{-0.952381, -1.90476}};

std::vector segments;
segments.emplace_back(Position(-6.5, -5.5), Position(3.5, -5.5)); // for clang can be compile error, for g++ compiles
segments.emplace_back(Position(3.5, -5.5), Position(3.5, 3));
segments.emplace_back(Position(3.5, 3), Position(-6.5, 3));
segments.emplace_back(Position(-6.5, 3), Position(-6.5, -5.5));

//////////////// construction of Voronoi diagram + printing cells
VoronoiDiagram vd;
boost::polygon::construct_voronoi(begin(positions), end(positions), begin(segments), end(segments), &vd);

unsigned int cell_index = 0;
for (auto it = vd.cells().begin(); it != vd.cells().end(); ++it) {
if (it->contains_point()) {
switch (it->source_category())
{
case boost::polygon::SOURCE_CATEGORY_SINGLE_POINT:
{
std::size_t index = it->source_index();
auto p = positions[index];
cout 

Подробнее здесь: [url]https://stackoverflow.com/questions/79038897/boost-voronoi-generates-incorrect-voronoi-cells-with-floating-point-input-in-c[/url]
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C++»