Ported point_along_segment(), Polyline::length(), Polyline::clip_end() to XS

This commit is contained in:
Alessandro Ranellucci 2013-10-27 22:57:25 +01:00
parent 26a18a2a52
commit 29b83517cb
12 changed files with 64 additions and 57 deletions

View file

@ -42,6 +42,18 @@ Line::midpoint() const
return new Point ((this->a.x + this->b.x) / 2.0, (this->a.y + this->b.y) / 2.0);
}
Point*
Line::point_at(double distance) const
{
double len = this->length();
Point* p = new Point(this->a);
if (this->a.x != this->b.x)
p->x = this->a.x + (this->b.x - this->a.x) * distance / len;
if (this->a.y != this->b.y)
p->y = this->a.y + (this->b.y - this->a.y) * distance / len;
return p;
}
#ifdef SLIC3RXS
void
Line::from_SV(SV* line_sv)

View file

@ -19,6 +19,7 @@ class Line
void reverse();
double length() const;
Point* midpoint() const;
Point* point_at(double distance) const;
#ifdef SLIC3RXS
void from_SV(SV* line_sv);

View file

@ -38,6 +38,17 @@ MultiPoint::first_point() const
return new Point(this->points.front());
}
double
MultiPoint::length() const
{
Lines lines = this->lines();
double len = 0;
for (Lines::iterator it = lines.begin(); it != lines.end(); ++it) {
len += it->length();
}
return len;
}
#ifdef SLIC3RXS
void
MultiPoint::from_SV(SV* poly_sv)

View file

@ -1,6 +1,7 @@
#ifndef slic3r_MultiPoint_hpp_
#define slic3r_MultiPoint_hpp_
#include "Line.hpp"
#include "Point.hpp"
#include <algorithm>
#include <vector>
@ -17,6 +18,8 @@ class MultiPoint
void reverse();
Point* first_point() const;
virtual Point* last_point() const = 0;
virtual Lines lines() const = 0;
double length() const;
#ifdef SLIC3RXS
void from_SV(SV* poly_sv);

View file

@ -19,6 +19,27 @@ Polyline::lines() const
return lines;
}
// removes the given distance from the end of the polyline
void
Polyline::clip_end(double distance)
{
while (distance > 0) {
Point last_point = *this->last_point();
this->points.pop_back();
if (this->points.empty()) break;
double last_segment_length = last_point.distance_to(this->last_point());
if (last_segment_length <= distance) {
distance -= last_segment_length;
continue;
}
Line segment(last_point, *this->last_point());
this->points.push_back(*segment.point_at(distance));
distance = 0;
}
}
#ifdef SLIC3RXS
SV*
Polyline::to_SV_ref()

View file

@ -10,6 +10,7 @@ class Polyline : public MultiPoint {
public:
Point* last_point() const;
Lines lines() const;
void clip_end(double distance);
#ifdef SLIC3RXS
SV* to_SV_ref();

View file

@ -4,7 +4,7 @@ use strict;
use warnings;
use Slic3r::XS;
use Test::More tests => 5;
use Test::More tests => 6;
my $points = [
[100, 100],
@ -28,4 +28,10 @@ is_deeply [ map $_->pp, @$lines ], [
$polyline->append_polyline($polyline->clone);
is_deeply $polyline->pp, [ @$points, @$points ], 'append_polyline';
{
my $len = $polyline->length;
$polyline->clip_end($len/3);
ok abs($polyline->length - ($len-($len/3))) < 1, 'clip_end';
}
__END__

View file

@ -23,6 +23,8 @@
double length();
Point* midpoint()
%code{% const char* CLASS = "Slic3r::Point"; RETVAL = THIS->midpoint(); %};
Point* point_at(double distance)
%code{% const char* CLASS = "Slic3r::Point"; RETVAL = THIS->point_at(distance); %};
%{
Line*

View file

@ -23,6 +23,7 @@
%code{% const char* CLASS = "Slic3r::Polyline"; RETVAL = THIS->split_at_index(index); %};
Polyline* split_at_first_point()
%code{% const char* CLASS = "Slic3r::Polyline"; RETVAL = THIS->split_at_first_point(); %};
double length();
double area();
bool is_counter_clockwise();
bool is_clockwise();

View file

@ -23,6 +23,8 @@
%code{% const char* CLASS = "Slic3r::Point"; RETVAL = THIS->first_point(); %};
Point* last_point()
%code{% const char* CLASS = "Slic3r::Point"; RETVAL = THIS->last_point(); %};
double length();
void clip_end(double distance);
%{
Polyline*