Ported regular_points() to XS and renamed it to equally_spaced_points()
This commit is contained in:
parent
6bb425e88d
commit
885ab5844e
8 changed files with 45 additions and 34 deletions
|
@ -80,37 +80,4 @@ sub align_to_origin {
|
||||||
return $self->translate(-$bb->x_min, -$bb->y_min);
|
return $self->translate(-$bb->x_min, -$bb->y_min);
|
||||||
}
|
}
|
||||||
|
|
||||||
# this method returns a collection of points picked on the polygon contour
|
|
||||||
# so that they are evenly spaced according to the input distance
|
|
||||||
# (find a better name!)
|
|
||||||
sub regular_points {
|
|
||||||
my $self = shift;
|
|
||||||
my ($distance) = @_;
|
|
||||||
|
|
||||||
my @my_points = @$self;
|
|
||||||
my @points = ($my_points[0]->clone);
|
|
||||||
my $len = 0;
|
|
||||||
|
|
||||||
for (my $i = 1; $i <= $#my_points; $i++) {
|
|
||||||
my $point = $my_points[$i];
|
|
||||||
my $segment_length = $point->distance_to($my_points[$i-1]);
|
|
||||||
$len += $segment_length;
|
|
||||||
next if $len < $distance;
|
|
||||||
|
|
||||||
if ($len == $distance) {
|
|
||||||
push @points, $point;
|
|
||||||
$len = 0;
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
my $take = $segment_length - ($len - $distance); # how much we take of this segment
|
|
||||||
my $new_point = Slic3r::Geometry::point_along_segment($my_points[$i-1], $point, $take);
|
|
||||||
push @points, Slic3r::Point->new(@$new_point);
|
|
||||||
$i--;
|
|
||||||
$len = -$take;
|
|
||||||
}
|
|
||||||
|
|
||||||
return @points;
|
|
||||||
}
|
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
|
@ -451,7 +451,7 @@ sub generate_toolpaths {
|
||||||
}
|
}
|
||||||
|
|
||||||
# apply a pattern to the loop
|
# apply a pattern to the loop
|
||||||
my @positions = map Slic3r::Polygon->new(@$_)->split_at_first_point->regular_points($circle_distance), @external_loops;
|
my @positions = map @{Slic3r::Polygon->new(@$_)->equally_spaced_points($circle_distance)}, @external_loops;
|
||||||
@loops0 = @{diff(
|
@loops0 = @{diff(
|
||||||
[ @external_loops ],
|
[ @external_loops ],
|
||||||
[ map { my $c = $circle->clone; $c->translate(@$_); $c } @positions ],
|
[ map { my $c = $circle->clone; $c->translate(@$_); $c } @positions ],
|
||||||
|
|
|
@ -53,6 +53,15 @@ Polygon::split_at_first_point() const
|
||||||
return this->split_at_index(0);
|
return this->split_at_index(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Points
|
||||||
|
Polygon::equally_spaced_points(double distance) const
|
||||||
|
{
|
||||||
|
Polyline* polyline = this->split_at_first_point();
|
||||||
|
Points pts = polyline->equally_spaced_points(distance);
|
||||||
|
delete polyline;
|
||||||
|
return pts;
|
||||||
|
}
|
||||||
|
|
||||||
double
|
double
|
||||||
Polygon::area() const
|
Polygon::area() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,6 +16,7 @@ class Polygon : public MultiPoint {
|
||||||
Polyline* split_at(const Point* point) const;
|
Polyline* split_at(const Point* point) const;
|
||||||
Polyline* split_at_index(int index) const;
|
Polyline* split_at_index(int index) const;
|
||||||
Polyline* split_at_first_point() const;
|
Polyline* split_at_first_point() const;
|
||||||
|
Points equally_spaced_points(double distance) const;
|
||||||
double area() const;
|
double area() const;
|
||||||
bool is_counter_clockwise() const;
|
bool is_counter_clockwise() const;
|
||||||
bool is_clockwise() const;
|
bool is_clockwise() const;
|
||||||
|
|
|
@ -49,6 +49,37 @@ Polyline::clip_start(double distance)
|
||||||
if (this->points.size() >= 2) this->reverse();
|
if (this->points.size() >= 2) this->reverse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* this method returns a collection of points picked on the polygon contour
|
||||||
|
so that they are evenly spaced according to the input distance */
|
||||||
|
Points
|
||||||
|
Polyline::equally_spaced_points(double distance) const
|
||||||
|
{
|
||||||
|
Points pts;
|
||||||
|
pts.push_back(*this->first_point());
|
||||||
|
double len = 0;
|
||||||
|
|
||||||
|
for (Points::const_iterator it = this->points.begin() + 1; it != this->points.end(); ++it) {
|
||||||
|
double segment_length = it->distance_to(&*(it-1));
|
||||||
|
len += segment_length;
|
||||||
|
if (len < distance) continue;
|
||||||
|
|
||||||
|
if (len == distance) {
|
||||||
|
pts.push_back(*it);
|
||||||
|
len = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
double take = segment_length - (len - distance); // how much we take of this segment
|
||||||
|
Line segment(*(it-1), *it);
|
||||||
|
pts.push_back(*segment.point_at(take));
|
||||||
|
it--;
|
||||||
|
len = -take;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pts;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef SLIC3RXS
|
#ifdef SLIC3RXS
|
||||||
SV*
|
SV*
|
||||||
Polyline::to_SV_ref()
|
Polyline::to_SV_ref()
|
||||||
|
|
|
@ -12,6 +12,7 @@ class Polyline : public MultiPoint {
|
||||||
Lines lines() const;
|
Lines lines() const;
|
||||||
void clip_end(double distance);
|
void clip_end(double distance);
|
||||||
void clip_start(double distance);
|
void clip_start(double distance);
|
||||||
|
Points equally_spaced_points(double distance) const;
|
||||||
|
|
||||||
#ifdef SLIC3RXS
|
#ifdef SLIC3RXS
|
||||||
SV* to_SV_ref();
|
SV* to_SV_ref();
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
%code{% const char* CLASS = "Slic3r::Polyline"; RETVAL = THIS->split_at_index(index); %};
|
%code{% const char* CLASS = "Slic3r::Polyline"; RETVAL = THIS->split_at_index(index); %};
|
||||||
Polyline* split_at_first_point()
|
Polyline* split_at_first_point()
|
||||||
%code{% const char* CLASS = "Slic3r::Polyline"; RETVAL = THIS->split_at_first_point(); %};
|
%code{% const char* CLASS = "Slic3r::Polyline"; RETVAL = THIS->split_at_first_point(); %};
|
||||||
|
Points equally_spaced_points(double distance);
|
||||||
double length();
|
double length();
|
||||||
double area();
|
double area();
|
||||||
bool is_counter_clockwise();
|
bool is_counter_clockwise();
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
%code{% const char* CLASS = "Slic3r::Point"; RETVAL = THIS->first_point(); %};
|
%code{% const char* CLASS = "Slic3r::Point"; RETVAL = THIS->first_point(); %};
|
||||||
Point* last_point()
|
Point* last_point()
|
||||||
%code{% const char* CLASS = "Slic3r::Point"; RETVAL = THIS->last_point(); %};
|
%code{% const char* CLASS = "Slic3r::Point"; RETVAL = THIS->last_point(); %};
|
||||||
|
Points equally_spaced_points(double distance);
|
||||||
double length();
|
double length();
|
||||||
bool is_valid();
|
bool is_valid();
|
||||||
void clip_end(double distance);
|
void clip_end(double distance);
|
||||||
|
|
Loading…
Reference in a new issue