mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	Fix overflow in distance_to(Line*). It was affecting Douglas-Peucker causing massive loss of geometry. Includes regression test and a couple wkt() implementations
This commit is contained in:
		
							parent
							
								
									3a3e53b59b
								
							
						
					
					
						commit
						0d7f0705f0
					
				
					 6 changed files with 35 additions and 3 deletions
				
			
		|  | @ -1,9 +1,19 @@ | |||
| #include "Line.hpp" | ||||
| #include "Polyline.hpp" | ||||
| #include <algorithm> | ||||
| #include <sstream> | ||||
| 
 | ||||
| namespace Slic3r { | ||||
| 
 | ||||
| std::string | ||||
| Line::wkt() const | ||||
| { | ||||
|     std::ostringstream ss; | ||||
|     ss << "LINESTRING(" << this->a.x << " " << this->a.y << "," | ||||
|         << this->b.x << " " << this->b.y << ")"; | ||||
|     return ss.str(); | ||||
| } | ||||
| 
 | ||||
| Line::operator Polyline() const | ||||
| { | ||||
|     Polyline pl; | ||||
|  |  | |||
|  | @ -16,6 +16,7 @@ class Line | |||
|     Point b; | ||||
|     Line() {}; | ||||
|     explicit Line(Point _a, Point _b): a(_a), b(_b) {}; | ||||
|     std::string wkt() const; | ||||
|     operator Polyline() const; | ||||
|     void scale(double factor); | ||||
|     void translate(double x, double y); | ||||
|  |  | |||
|  | @ -1,9 +1,18 @@ | |||
| #include "Point.hpp" | ||||
| #include "Line.hpp" | ||||
| #include <cmath> | ||||
| #include <sstream> | ||||
| 
 | ||||
| namespace Slic3r { | ||||
| 
 | ||||
| std::string | ||||
| Point::wkt() const | ||||
| { | ||||
|     std::ostringstream ss; | ||||
|     ss << "POINT(" << this->x << " " << this->y << ")"; | ||||
|     return ss.str(); | ||||
| } | ||||
| 
 | ||||
| void | ||||
| Point::scale(double factor) | ||||
| { | ||||
|  | @ -100,8 +109,8 @@ Point::distance_to(const Line &line) const | |||
| { | ||||
|     if (line.a.coincides_with(&line.b)) return this->distance_to(&line.a); | ||||
|      | ||||
|     double n = (line.b.x - line.a.x) * (line.a.y - this->y) | ||||
|         - (line.a.x - this->x) * (line.b.y - line.a.y); | ||||
|     double n = (double)(line.b.x - line.a.x) * (double)(line.a.y - this->y) | ||||
|         - (double)(line.a.x - this->x) * (double)(line.b.y - line.a.y); | ||||
|      | ||||
|     return std::abs(n) / line.length(); | ||||
| } | ||||
|  |  | |||
|  | @ -4,6 +4,7 @@ | |||
| #include <myinit.h> | ||||
| #include <vector> | ||||
| #include <math.h> | ||||
| #include <string> | ||||
| 
 | ||||
| namespace Slic3r { | ||||
| 
 | ||||
|  | @ -20,6 +21,7 @@ class Point | |||
|     coord_t x; | ||||
|     coord_t y; | ||||
|     explicit Point(coord_t _x = 0, coord_t _y = 0): x(_x), y(_y) {}; | ||||
|     std::string wkt() const; | ||||
|     void scale(double factor); | ||||
|     void translate(double x, double y); | ||||
|     void rotate(double angle, Point* center); | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ use strict; | |||
| use warnings; | ||||
| 
 | ||||
| use Slic3r::XS; | ||||
| use Test::More tests => 8; | ||||
| use Test::More tests => 9; | ||||
| 
 | ||||
| my $point = Slic3r::Point->new(10, 15); | ||||
| is_deeply [ @$point ], [10, 15], 'point roundtrip'; | ||||
|  | @ -30,4 +30,13 @@ ok !$point->coincides_with($point2), 'coincides_with'; | |||
|     ok $nearest->coincides_with($point2), 'nearest_point'; | ||||
| } | ||||
| 
 | ||||
| { | ||||
|     my $line = Slic3r::Line->new( | ||||
|         [18335846,18335845], | ||||
|         [18335846,1664160], | ||||
|     ); | ||||
|     $point = Slic3r::Point->new(1664161,18335848); | ||||
|     is $point->distance_to_line($line), 16671685, 'distance_to_line() does not overflow'; | ||||
| } | ||||
| 
 | ||||
| __END__ | ||||
|  |  | |||
|  | @ -24,6 +24,7 @@ | |||
|     Point* nearest_point(Points points) | ||||
|         %code{% const char* CLASS = "Slic3r::Point"; RETVAL = new Point(*(THIS->nearest_point(points))); %}; | ||||
|     double distance_to(Point* point); | ||||
|     %name{distance_to_line} double distance_to(Line* line); | ||||
| 
 | ||||
| %{ | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Alessandro Ranellucci
						Alessandro Ranellucci