mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-04 06:01:17 +08:00
Node data constructor deosnt have own logic
Calculation of Parabola length by sum of line segments
This commit is contained in:
parent
dd505eab82
commit
18d58da6ea
@ -52,19 +52,20 @@ public:
|
|||||||
VoronoiGraph::ExPath & result,
|
VoronoiGraph::ExPath & result,
|
||||||
const VoronoiGraph::Node *node,
|
const VoronoiGraph::Node *node,
|
||||||
double distance_to_node,
|
double distance_to_node,
|
||||||
const VoronoiGraph::Path &prev_path)
|
VoronoiGraph::Path &&act_path,
|
||||||
|
std::set<const VoronoiGraph::Node *> &&skip_nodes
|
||||||
|
)
|
||||||
: result(result)
|
: result(result)
|
||||||
, node(node)
|
, node(node)
|
||||||
, distance_to_node(distance_to_node)
|
, distance_to_node(distance_to_node)
|
||||||
|
, act_path(std::move(act_path)) // copy prev and append actual node
|
||||||
|
, skip_nodes(std::move(skip_nodes))
|
||||||
{
|
{
|
||||||
// TODO: process it before constructor or in factory
|
//prev_path.extend(node, distance_to_node)
|
||||||
const VoronoiGraph::Node *prev_node = (prev_path.path.size() >= 1) ?
|
//const VoronoiGraph::Node *prev_node = (prev_path.nodes.size() >= 1) ?
|
||||||
prev_path.path.back() :
|
// prev_path.nodes.back() :
|
||||||
nullptr;
|
// nullptr;
|
||||||
skip_nodes = {prev_node};
|
//skip_nodes = {prev_node};
|
||||||
// append actual node
|
|
||||||
act_path = prev_path; // copy
|
|
||||||
act_path.append(node, distance_to_node); // increase path
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -7,11 +7,11 @@ using namespace Slic3r::sla;
|
|||||||
void PostProcessNeighbor::process()
|
void PostProcessNeighbor::process()
|
||||||
{
|
{
|
||||||
bool is_circle_neighbor = false;
|
bool is_circle_neighbor = false;
|
||||||
if (neighbor_path.path.empty()) { // neighbor node is on circle
|
if (neighbor_path.nodes.empty()) { // neighbor node is on circle
|
||||||
for (VoronoiGraph::Circle &circle : neighbor_path.circles) {
|
for (VoronoiGraph::Circle &circle : neighbor_path.circles) {
|
||||||
const auto &circle_item = std::find(circle.path.begin(),
|
const auto &circle_item = std::find(circle.nodes.begin(),
|
||||||
circle.path.end(), data.node);
|
circle.nodes.end(), data.node);
|
||||||
if (circle_item == circle.path.end())
|
if (circle_item == circle.nodes.end())
|
||||||
continue; // node is NOT on circle
|
continue; // node is NOT on circle
|
||||||
|
|
||||||
size_t next_circle_index = &circle -
|
size_t next_circle_index = &circle -
|
||||||
@ -21,7 +21,7 @@ void PostProcessNeighbor::process()
|
|||||||
data.circle_indexes.push_back(circle_index);
|
data.circle_indexes.push_back(circle_index);
|
||||||
|
|
||||||
// check if this node is end of circle
|
// check if this node is end of circle
|
||||||
if (circle_item == circle.path.begin()) {
|
if (circle_item == circle.nodes.begin()) {
|
||||||
data.end_circle_indexes.push_back(circle_index);
|
data.end_circle_indexes.push_back(circle_index);
|
||||||
|
|
||||||
// !! this FIX circle lenght because at detection of
|
// !! this FIX circle lenght because at detection of
|
||||||
@ -29,7 +29,7 @@ void PostProcessNeighbor::process()
|
|||||||
circle.length -= data.act_path.length;
|
circle.length -= data.act_path.length;
|
||||||
|
|
||||||
// skip twice checking of circle
|
// skip twice checking of circle
|
||||||
data.skip_nodes.insert(circle.path.back());
|
data.skip_nodes.insert(circle.nodes.back());
|
||||||
}
|
}
|
||||||
is_circle_neighbor = true;
|
is_circle_neighbor = true;
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ void PostProcessNeighbors::process()
|
|||||||
if (!side_branches.empty()) {
|
if (!side_branches.empty()) {
|
||||||
result.side_branches[node] = side_branches;
|
result.side_branches[node] = side_branches;
|
||||||
}
|
}
|
||||||
longest_path.path.insert(longest_path.path.begin(), node);
|
longest_path.nodes.insert(longest_path.nodes.begin(), node);
|
||||||
result.path = std::move(longest_path.path);
|
result.nodes = std::move(longest_path.nodes);
|
||||||
result.length = distance_to_node + longest_path.length;
|
result.length = distance_to_node + longest_path.length;
|
||||||
}
|
}
|
@ -19,7 +19,11 @@ public:
|
|||||||
const VoronoiGraph::Path &prev_path =
|
const VoronoiGraph::Path &prev_path =
|
||||||
VoronoiGraph::Path({}, 0.) // make copy
|
VoronoiGraph::Path({}, 0.) // make copy
|
||||||
)
|
)
|
||||||
: NodeDataWithResult(result, node, distance_to_node, prev_path)
|
: NodeDataWithResult(
|
||||||
|
result, node, distance_to_node,
|
||||||
|
prev_path.extend(node, distance_to_node),
|
||||||
|
prepare_skip_nodes(prev_path)
|
||||||
|
)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual void process([[maybe_unused]] CallStack &call_stack)
|
virtual void process([[maybe_unused]] CallStack &call_stack)
|
||||||
@ -28,6 +32,14 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static std::set<const VoronoiGraph::Node *> prepare_skip_nodes(
|
||||||
|
const VoronoiGraph::Path &prev_path)
|
||||||
|
{
|
||||||
|
if (prev_path.nodes.empty()) return {};
|
||||||
|
const VoronoiGraph::Node *prev_node = prev_path.nodes.back();
|
||||||
|
return {prev_node};
|
||||||
|
}
|
||||||
|
|
||||||
void process();
|
void process();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -71,25 +71,31 @@ public:
|
|||||||
struct VoronoiGraph::Path
|
struct VoronoiGraph::Path
|
||||||
{
|
{
|
||||||
// row of neighbor Nodes
|
// row of neighbor Nodes
|
||||||
VoronoiGraph::Nodes path; // TODO: rename to nodes
|
VoronoiGraph::Nodes nodes;
|
||||||
|
|
||||||
// length of path
|
// length of path
|
||||||
// when circle contain length from back to front;
|
// when circle contain length from back to front;
|
||||||
double length;
|
double length;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Path() : path(), length(0.) {}
|
Path() : nodes(), length(0.) {}
|
||||||
Path(const VoronoiGraph::Node *node) : path({node}), length(0.) {}
|
Path(const VoronoiGraph::Node *node) : nodes({node}), length(0.) {}
|
||||||
Path(VoronoiGraph::Nodes nodes, double length)
|
Path(VoronoiGraph::Nodes nodes, double length)
|
||||||
: path(std::move(nodes)), length(length)
|
: nodes(std::move(nodes)), length(length)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void append(const VoronoiGraph::Node *node, double length)
|
void append(const VoronoiGraph::Node *node, double length)
|
||||||
{
|
{
|
||||||
path.push_back(node);
|
nodes.push_back(node);
|
||||||
this->length += length;
|
this->length += length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Path extend(const VoronoiGraph::Node *node, double length) const {
|
||||||
|
Path result(*this); // make copy
|
||||||
|
result.append(node, length);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
struct OrderLengthFromShortest{
|
struct OrderLengthFromShortest{
|
||||||
bool operator()(const VoronoiGraph::Path &path1,
|
bool operator()(const VoronoiGraph::Path &path1,
|
||||||
const VoronoiGraph::Path &path2){
|
const VoronoiGraph::Path &path2){
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
#include "IStackFunction.hpp"
|
#include "IStackFunction.hpp"
|
||||||
#include "EvaluateNeighbor.hpp"
|
#include "EvaluateNeighbor.hpp"
|
||||||
|
|
||||||
|
#include <libslic3r/VoronoiVisualUtils.hpp>
|
||||||
|
|
||||||
using namespace Slic3r::sla;
|
using namespace Slic3r::sla;
|
||||||
|
|
||||||
VoronoiGraph::Node *VoronoiGraphUtils::getNode(VoronoiGraph & graph,
|
VoronoiGraph::Node *VoronoiGraphUtils::getNode(VoronoiGraph & graph,
|
||||||
@ -32,11 +34,45 @@ VoronoiGraph::Node *VoronoiGraphUtils::getNode(VoronoiGraph & graph,
|
|||||||
return &iterator->second;
|
return &iterator->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double VoronoiGraphUtils::calculate_length_of_parabola(
|
||||||
|
const VD::edge_type & edge,
|
||||||
|
const std::vector<Voronoi::Internal::segment_type> &segments)
|
||||||
|
{
|
||||||
|
// TODO: len by param not sampling of parabola
|
||||||
|
|
||||||
|
double discretization_step = 0.0002 * 1e7;
|
||||||
|
Points points; // voronoi created by line segments only
|
||||||
|
|
||||||
|
std::vector<Voronoi::Internal::point_type> samples;
|
||||||
|
samples.push_back(Voronoi::Internal::point_type(edge.vertex0()->x(),
|
||||||
|
edge.vertex0()->y()));
|
||||||
|
samples.push_back(Voronoi::Internal::point_type(edge.vertex1()->x(),
|
||||||
|
edge.vertex1()->y()));
|
||||||
|
Voronoi::Internal::sample_curved_edge(points, segments, edge, samples,
|
||||||
|
discretization_step);
|
||||||
|
|
||||||
|
double sumLength = 0;
|
||||||
|
for (size_t index = 1; index < samples.size(); ++index) {
|
||||||
|
double diffX = samples[index - 1].x() - samples[index].x();
|
||||||
|
double diffY = samples[index - 1].y() - samples[index].y();
|
||||||
|
double length = sqrt(diffX * diffX + diffY * diffY);
|
||||||
|
sumLength += length;
|
||||||
|
}
|
||||||
|
return sumLength;
|
||||||
|
}
|
||||||
|
|
||||||
VoronoiGraph VoronoiGraphUtils::getSkeleton(const VD &vd, const Lines &lines)
|
VoronoiGraph VoronoiGraphUtils::getSkeleton(const VD &vd, const Lines &lines)
|
||||||
{
|
{
|
||||||
// vd should be annotated.
|
// vd should be annotated.
|
||||||
// assert(Voronoi::debug::verify_inside_outside_annotations(vd));
|
// assert(Voronoi::debug::verify_inside_outside_annotations(vd));
|
||||||
|
|
||||||
|
std::vector<Voronoi::Internal::segment_type> segments;
|
||||||
|
for (Lines::const_iterator it = lines.begin(); it != lines.end(); ++it)
|
||||||
|
segments.push_back(Voronoi::Internal::segment_type(
|
||||||
|
Voronoi::Internal::point_type(double(it->a(0)), double(it->a(1))),
|
||||||
|
Voronoi::Internal::point_type(double(it->b(0)),
|
||||||
|
double(it->b(1)))));
|
||||||
|
|
||||||
VoronoiGraph skeleton;
|
VoronoiGraph skeleton;
|
||||||
const VD::edge_type *first_edge = &vd.edges().front();
|
const VD::edge_type *first_edge = &vd.edges().front();
|
||||||
for (const VD::edge_type &edge : vd.edges()) {
|
for (const VD::edge_type &edge : vd.edges()) {
|
||||||
@ -72,8 +108,8 @@ VoronoiGraph VoronoiGraphUtils::getSkeleton(const VD &vd, const Lines &lines)
|
|||||||
double diffY = v0->y() - v1->y();
|
double diffY = v0->y() - v1->y();
|
||||||
length = sqrt(diffX * diffX + diffY * diffY);
|
length = sqrt(diffX * diffX + diffY * diffY);
|
||||||
} else { // if (edge.is_curved())
|
} else { // if (edge.is_curved())
|
||||||
// TODO: len of parabola
|
assert(edge.is_curved());
|
||||||
length = 1.0;
|
length = calculate_length_of_parabola(edge, segments);
|
||||||
}
|
}
|
||||||
|
|
||||||
VoronoiGraph::Node *node0 = getNode(skeleton, v0, &edge, lines);
|
VoronoiGraph::Node *node0 = getNode(skeleton, v0, &edge, lines);
|
||||||
@ -139,7 +175,7 @@ VoronoiGraph::Path VoronoiGraphUtils::find_longest_path_on_circle(
|
|||||||
bool is_short_revers_direction = false;
|
bool is_short_revers_direction = false;
|
||||||
// find longest side branch
|
// find longest side branch
|
||||||
const VoronoiGraph::Node *prev_circle_node = nullptr;
|
const VoronoiGraph::Node *prev_circle_node = nullptr;
|
||||||
for (const VoronoiGraph::Node *circle_node : circle.path) {
|
for (const VoronoiGraph::Node *circle_node : circle.nodes) {
|
||||||
if (prev_circle_node != nullptr)
|
if (prev_circle_node != nullptr)
|
||||||
distance_on_circle += get_neighbor_distance(circle_node,
|
distance_on_circle += get_neighbor_distance(circle_node,
|
||||||
prev_circle_node);
|
prev_circle_node);
|
||||||
@ -172,20 +208,20 @@ VoronoiGraph::Path VoronoiGraphUtils::find_longest_path_on_circle(
|
|||||||
// circle.path.front()); assert(distance_on_circle == circle.length);
|
// circle.path.front()); assert(distance_on_circle == circle.length);
|
||||||
|
|
||||||
// circlePath
|
// circlePath
|
||||||
auto circle_iterator = std::find(circle.path.begin(), circle.path.end(),
|
auto circle_iterator = std::find(circle.nodes.begin(), circle.nodes.end(),
|
||||||
longest_circle_node);
|
longest_circle_node);
|
||||||
VoronoiGraph::Nodes circle_path;
|
VoronoiGraph::Nodes circle_path;
|
||||||
if (is_longest_revers_direction) {
|
if (is_longest_revers_direction) {
|
||||||
circle_path = VoronoiGraph::Nodes(circle_iterator, circle.path.end());
|
circle_path = VoronoiGraph::Nodes(circle_iterator, circle.nodes.end());
|
||||||
std::reverse(circle_path.begin(), circle_path.end());
|
std::reverse(circle_path.begin(), circle_path.end());
|
||||||
} else {
|
} else {
|
||||||
if (longest_circle_node != circle.path.front())
|
if (longest_circle_node != circle.nodes.front())
|
||||||
circle_path = VoronoiGraph::Nodes(circle.path.begin() + 1,
|
circle_path = VoronoiGraph::Nodes(circle.nodes.begin() + 1,
|
||||||
circle_iterator + 1);
|
circle_iterator + 1);
|
||||||
}
|
}
|
||||||
// append longest side branch
|
// append longest side branch
|
||||||
circle_path.insert(circle_path.end(), longest_circle_branch->path.begin(),
|
circle_path.insert(circle_path.end(), longest_circle_branch->nodes.begin(),
|
||||||
longest_circle_branch->path.end());
|
longest_circle_branch->nodes.end());
|
||||||
return {circle_path, longest_branch_length};
|
return {circle_path, longest_branch_length};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,10 +246,10 @@ VoronoiGraph::Path VoronoiGraphUtils::find_longest_path_on_circles(
|
|||||||
|
|
||||||
// collect all circle ndoes
|
// collect all circle ndoes
|
||||||
std::set<const VoronoiGraph::Node *> nodes;
|
std::set<const VoronoiGraph::Node *> nodes;
|
||||||
nodes.insert(circle.path.begin(), circle.path.end());
|
nodes.insert(circle.nodes.begin(), circle.nodes.end());
|
||||||
for (size_t circle_index : connected_circles) {
|
for (size_t circle_index : connected_circles) {
|
||||||
const auto &circle = circles[circle_index];
|
const auto &circle = circles[circle_index];
|
||||||
nodes.insert(circle.path.begin(), circle.path.end());
|
nodes.insert(circle.nodes.begin(), circle.nodes.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
// nodes are path throw circles
|
// nodes are path throw circles
|
||||||
@ -233,7 +269,7 @@ VoronoiGraph::Path VoronoiGraphUtils::find_longest_path_on_circles(
|
|||||||
// shortest path from input_node
|
// shortest path from input_node
|
||||||
VoronoiGraph::Path path(std::move(search_queue.top()));
|
VoronoiGraph::Path path(std::move(search_queue.top()));
|
||||||
search_queue.pop();
|
search_queue.pop();
|
||||||
const VoronoiGraph::Node &node = *path.path.back();
|
const VoronoiGraph::Node &node = *path.nodes.back();
|
||||||
if (done.find(&node) != done.end()) { // already checked
|
if (done.find(&node) != done.end()) { // already checked
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -254,24 +290,24 @@ VoronoiGraph::Path VoronoiGraphUtils::find_longest_path_on_circles(
|
|||||||
double length = longest_branch.length + neighbor_path.length;
|
double length = longest_branch.length + neighbor_path.length;
|
||||||
if (longest_path.length < length) {
|
if (longest_path.length < length) {
|
||||||
longest_path.length = length;
|
longest_path.length = length;
|
||||||
longest_path.path = neighbor_path.path; // copy path
|
longest_path.nodes = neighbor_path.nodes; // copy path
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// create result path
|
// create result path
|
||||||
assert(!longest_path.path.empty());
|
assert(!longest_path.nodes.empty());
|
||||||
longest_path.path.erase(longest_path.path.begin()); // remove input_node
|
longest_path.nodes.erase(longest_path.nodes.begin()); // remove input_node
|
||||||
assert(!longest_path.path.empty());
|
assert(!longest_path.nodes.empty());
|
||||||
auto branches_item = ex_path.side_branches.find(longest_path.path.back());
|
auto branches_item = ex_path.side_branches.find(longest_path.nodes.back());
|
||||||
if (branches_item == ex_path.side_branches.end()) {
|
if (branches_item == ex_path.side_branches.end()) {
|
||||||
// longest path ends on circle
|
// longest path ends on circle
|
||||||
return longest_path;
|
return longest_path;
|
||||||
}
|
}
|
||||||
const VoronoiGraph::Path &longest_branch = branches_item->second.top();
|
const VoronoiGraph::Path &longest_branch = branches_item->second.top();
|
||||||
longest_path.path.insert(longest_path.path.end(),
|
longest_path.nodes.insert(longest_path.nodes.end(),
|
||||||
longest_branch.path.begin(),
|
longest_branch.nodes.begin(),
|
||||||
longest_branch.path.end());
|
longest_branch.nodes.end());
|
||||||
return longest_path;
|
return longest_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,7 +315,7 @@ std::optional<VoronoiGraph::Circle> VoronoiGraphUtils::create_circle(
|
|||||||
const VoronoiGraph::Path & path,
|
const VoronoiGraph::Path & path,
|
||||||
const VoronoiGraph::Node::Neighbor &neighbor)
|
const VoronoiGraph::Node::Neighbor &neighbor)
|
||||||
{
|
{
|
||||||
VoronoiGraph::Nodes passed_nodes = path.path;
|
VoronoiGraph::Nodes passed_nodes = path.nodes;
|
||||||
// detection of circle
|
// detection of circle
|
||||||
// not neccesary to check last one in path
|
// not neccesary to check last one in path
|
||||||
auto end_find = passed_nodes.end() - 1;
|
auto end_find = passed_nodes.end() - 1;
|
||||||
@ -350,11 +386,11 @@ void VoronoiGraphUtils::append_neighbor_branch(
|
|||||||
|
|
||||||
void VoronoiGraphUtils::reshape_longest_path(VoronoiGraph::ExPath &path)
|
void VoronoiGraphUtils::reshape_longest_path(VoronoiGraph::ExPath &path)
|
||||||
{
|
{
|
||||||
assert(path.path.size() >= 1);
|
assert(path.nodes.size() >= 1);
|
||||||
|
|
||||||
double actual_length = 0.;
|
double actual_length = 0.;
|
||||||
const VoronoiGraph::Node *prev_node = nullptr;
|
const VoronoiGraph::Node *prev_node = nullptr;
|
||||||
VoronoiGraph::Nodes origin_path = path.path; // make copy
|
VoronoiGraph::Nodes origin_path = path.nodes; // make copy
|
||||||
// index to path
|
// index to path
|
||||||
size_t path_index = 0;
|
size_t path_index = 0;
|
||||||
for (const VoronoiGraph::Node *node : origin_path) {
|
for (const VoronoiGraph::Node *node : origin_path) {
|
||||||
@ -373,24 +409,24 @@ void VoronoiGraphUtils::reshape_longest_path(VoronoiGraph::ExPath &path)
|
|||||||
if (actual_length >= branches.top().length)
|
if (actual_length >= branches.top().length)
|
||||||
continue; // no longer branch
|
continue; // no longer branch
|
||||||
|
|
||||||
auto end_path = path.path.begin() + path_index;
|
auto end_path = path.nodes.begin() + path_index;
|
||||||
VoronoiGraph::Path side_branch({path.path.begin(), end_path},
|
VoronoiGraph::Path side_branch({path.nodes.begin(), end_path},
|
||||||
actual_length);
|
actual_length);
|
||||||
std::reverse(side_branch.path.begin(), side_branch.path.end());
|
std::reverse(side_branch.nodes.begin(), side_branch.nodes.end());
|
||||||
VoronoiGraph::Path new_main_branch(std::move(branches.top()));
|
VoronoiGraph::Path new_main_branch(std::move(branches.top()));
|
||||||
branches.pop();
|
branches.pop();
|
||||||
std::reverse(new_main_branch.path.begin(), new_main_branch.path.end());
|
std::reverse(new_main_branch.nodes.begin(), new_main_branch.nodes.end());
|
||||||
// add old main path store into side branches - may be it is not neccessary
|
// add old main path store into side branches - may be it is not neccessary
|
||||||
branches.push(std::move(side_branch));
|
branches.push(std::move(side_branch));
|
||||||
|
|
||||||
// swap side branch with main branch
|
// swap side branch with main branch
|
||||||
path.path.erase(path.path.begin(), end_path);
|
path.nodes.erase(path.nodes.begin(), end_path);
|
||||||
path.path.insert(path.path.begin(), new_main_branch.path.begin(),
|
path.nodes.insert(path.nodes.begin(), new_main_branch.nodes.begin(),
|
||||||
new_main_branch.path.end());
|
new_main_branch.nodes.end());
|
||||||
|
|
||||||
path.length += new_main_branch.length;
|
path.length += new_main_branch.length;
|
||||||
path.length -= actual_length;
|
path.length -= actual_length;
|
||||||
path_index = new_main_branch.path.size();
|
path_index = new_main_branch.nodes.size();
|
||||||
actual_length = new_main_branch.length;
|
actual_length = new_main_branch.length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -492,7 +528,7 @@ std::vector<Slic3r::Point> VoronoiGraphUtils::sample_voronoi_graph(
|
|||||||
config.max_length_for_one_support_point) { // create only one
|
config.max_length_for_one_support_point) { // create only one
|
||||||
// point in center
|
// point in center
|
||||||
// sample in center of voronoi
|
// sample in center of voronoi
|
||||||
return {get_center_of_path(longest_path.path, longest_path.length)};
|
return {get_center_of_path(longest_path.nodes, longest_path.length)};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Point> points;
|
std::vector<Point> points;
|
||||||
@ -554,14 +590,14 @@ void VoronoiGraphUtils::draw(SVG & svg,
|
|||||||
const char *mainPathColor = "red";
|
const char *mainPathColor = "red";
|
||||||
|
|
||||||
for (auto &circle : path.circles) {
|
for (auto &circle : path.circles) {
|
||||||
draw(svg, circle.path, width, circlePathColor, true);
|
draw(svg, circle.nodes, width, circlePathColor, true);
|
||||||
Point center(0, 0);
|
Point center(0, 0);
|
||||||
for (auto p : circle.path) {
|
for (auto p : circle.nodes) {
|
||||||
center.x() += p->vertex->x();
|
center.x() += p->vertex->x();
|
||||||
center.y() += p->vertex->y();
|
center.y() += p->vertex->y();
|
||||||
}
|
}
|
||||||
center.x() /= circle.path.size();
|
center.x() /= circle.nodes.size();
|
||||||
center.y() /= circle.path.size();
|
center.y() /= circle.nodes.size();
|
||||||
|
|
||||||
svg.draw_text(center,
|
svg.draw_text(center,
|
||||||
("C" + std::to_string(&circle - &path.circles.front()))
|
("C" + std::to_string(&circle - &path.circles.front()))
|
||||||
@ -573,12 +609,12 @@ void VoronoiGraphUtils::draw(SVG & svg,
|
|||||||
auto tmp = branches.second; // copy
|
auto tmp = branches.second; // copy
|
||||||
while (!tmp.empty()) {
|
while (!tmp.empty()) {
|
||||||
const auto &branch = tmp.top();
|
const auto &branch = tmp.top();
|
||||||
auto path = branch.path;
|
auto path = branch.nodes;
|
||||||
path.insert(path.begin(), branches.first);
|
path.insert(path.begin(), branches.first);
|
||||||
draw(svg, path, width, sideBranchesColor);
|
draw(svg, path, width, sideBranchesColor);
|
||||||
tmp.pop();
|
tmp.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
draw(svg, path.path, width, mainPathColor);
|
draw(svg, path.nodes, width, mainPathColor);
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,14 @@ public:
|
|||||||
const Lines & lines
|
const Lines & lines
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calculate length
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="edge">curved edge</param>
|
||||||
|
/// <returns>edge length</returns>
|
||||||
|
static double calculate_length_of_parabola(const VD::edge_type &edge,
|
||||||
|
const std::vector<VD::segment_type> &segments);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// calculate distances to border of island and length on skeleton
|
/// calculate distances to border of island and length on skeleton
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -191,7 +191,7 @@ ExPolygons createTestIslands(double size)
|
|||||||
{4 * size5, size5},
|
{4 * size5, size5},
|
||||||
{3 * size5, size5}}};
|
{3 * size5, size5}}};
|
||||||
|
|
||||||
size_t count_cirlce_lines = 1000; // test stack overfrow
|
size_t count_cirlce_lines = 16; // test stack overfrow
|
||||||
double r_CCW = size / 2;
|
double r_CCW = size / 2;
|
||||||
double r_CW = r_CCW - size / 6;
|
double r_CW = r_CCW - size / 6;
|
||||||
// CCW: couter clock wise, CW: clock wise
|
// CCW: couter clock wise, CW: clock wise
|
||||||
|
Loading…
x
Reference in New Issue
Block a user