Ported encloses_point() to XS and renamed to contains_point()

This commit is contained in:
Alessandro Ranellucci 2013-11-21 16:21:42 +01:00
parent a225a8b2ef
commit 5f81292f3f
22 changed files with 81 additions and 76 deletions

View file

@ -62,7 +62,7 @@ ExPolygon::is_valid() const
}
bool
ExPolygon::contains_line(Line* line) const
ExPolygon::contains_line(const Line* line) const
{
Polylines pl(1);
pl.push_back(*line);
@ -72,6 +72,16 @@ ExPolygon::contains_line(Line* line) const
return pl_out.empty();
}
bool
ExPolygon::contains_point(const Point* point) const
{
if (!this->contour.contains_point(point)) return false;
for (Polygons::const_iterator it = this->holes.begin(); it != this->holes.end(); ++it) {
if (it->contains_point(point)) return false;
}
return true;
}
#ifdef SLIC3RXS
SV*
ExPolygon::to_AV() {

View file

@ -17,7 +17,8 @@ class ExPolygon
void rotate(double angle, Point* center);
double area() const;
bool is_valid() const;
bool contains_line(Line* line) const;
bool contains_line(const Line* line) const;
bool contains_point(const Point* point) const;
#ifdef SLIC3RXS
void from_SV(SV* poly_sv);

View file

@ -110,6 +110,21 @@ Polygon::is_valid() const
return this->points.size() >= 3;
}
bool
Polygon::contains_point(const Point* point) const
{
// http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
bool result;
Points::const_iterator i = this->points.begin();
Points::const_iterator j = this->points.end() - 1;
for (; i != this->points.end(); j = i++) {
if ( ((i->y > point->y) != (j->y > point->y))
&& (point->x < (j->x - i->x) * (point->y - i->y) / (j->y - i->y) + i->x) )
result = !result;
}
return result;
}
#ifdef SLIC3RXS
SV*
Polygon::to_SV_ref() {

View file

@ -23,6 +23,7 @@ class Polygon : public MultiPoint {
bool make_counter_clockwise();
bool make_clockwise();
bool is_valid() const;
bool contains_point(const Point* point) const;
#ifdef SLIC3RXS
SV* to_SV_ref();

View file

@ -49,6 +49,7 @@ PolylineCollection::leftmost_point() const
if (p == NULL || it->points.front().x < p->x)
p = &(it->points.front());
}
if (p == NULL) return NULL;
return new Point (*p);
}

View file

@ -4,7 +4,7 @@ use strict;
use warnings;
use Slic3r::XS;
use Test::More tests => 14;
use Test::More tests => 17;
my $square = [ # ccw
[100, 100],
@ -14,6 +14,9 @@ my $square = [ # ccw
];
my $polygon = Slic3r::Polygon->new(@$square);
my $cw_polygon = $polygon->clone;
$cw_polygon->reverse;
ok $polygon->is_valid, 'is_valid';
is_deeply $polygon->pp, $square, 'polygon roundtrip';
@ -34,6 +37,7 @@ is_deeply $polygon->split_at(Slic3r::Point->new(@{$square->[2]}))->pp, [ @$squar
is $polygon->area, 100*100, 'area';
ok $polygon->is_counter_clockwise, 'is_counter_clockwise';
ok !$cw_polygon->is_counter_clockwise, 'is_counter_clockwise';
{
my $clone = $polygon->clone;
$clone->reverse;
@ -46,6 +50,9 @@ ok $polygon->is_counter_clockwise, 'is_counter_clockwise';
ok ref($polygon->first_point) eq 'Slic3r::Point', 'first_point';
ok $polygon->contains_point(Slic3r::Point->new(150,150)), 'ccw contains_point';
ok $cw_polygon->contains_point(Slic3r::Point->new(150,150)), 'cw contains_point';
# this is not a test: this just demonstrates bad usage, where $polygon->clone gets
# DESTROY'ed before the derived object ($point), causing bad memory access
if (0) {

View file

@ -22,6 +22,7 @@
double area();
bool is_valid();
bool contains_line(Line* line);
bool contains_point(Point* point);
%{
ExPolygon*

View file

@ -33,6 +33,7 @@
bool is_valid();
Point* first_point()
%code{% const char* CLASS = "Slic3r::Point"; RETVAL = THIS->first_point(); %};
bool contains_point(Point* point);
%{
Polygon*