Prusa Slicer 2.6.0
Loading...
Searching...
No Matches
Slic3r::Arachne::LinearAlg2D Namespace Reference

Functions

static bool isInsideCorner (const Point &a, const Point &b, const Point &c, const Vec2i64 &query_point)
 
static int64_t pointIsLeftOfLine (const Point &p, const Point &a, const Point &b)
 
static float getAngleLeft (const Point &a, const Point &b, const Point &c)
 

Function Documentation

◆ getAngleLeft()

static float Slic3r::Arachne::LinearAlg2D::getAngleLeft ( const Point a,
const Point b,
const Point c 
)
inlinestatic

Compute the angle between two consecutive line segments.

The angle is computed from the left side of b when looking from a.

c \ . \ b angle| | a

Parameters
astart of first line segment
bend of first segment and start of second line segment
cend of second line segment
Returns
the angle in radians between 0 and 2 * pi of the corner in b
99{
100 const Vec2i64 ba = (a - b).cast<int64_t>();
101 const Vec2i64 bc = (c - b).cast<int64_t>();
102 const int64_t dott = ba.dot(bc); // dot product
103 const int64_t det = cross2(ba, bc); // determinant
104 if (det == 0) {
105 if ((ba.x() != 0 && (ba.x() > 0) == (bc.x() > 0)) || (ba.x() == 0 && (ba.y() > 0) == (bc.y() > 0)))
106 return 0; // pointy bit
107 else
108 return float(M_PI); // straight bit
109 }
110 const float angle = -atan2(double(det), double(dott)); // from -pi to pi
111 if (angle >= 0)
112 return angle;
113 else
114 return M_PI * 2 + angle;
115}
#define M_PI
Definition ExtrusionSimulator.cpp:20
The matrix class, also used for vectors and row-vectors.
Definition Matrix.h:180
Derived::Scalar cross2(const Eigen::MatrixBase< Derived > &v1, const Eigen::MatrixBase< Derived2 > &v2)
Definition Point.hpp:93
double angle(const Eigen::MatrixBase< Derived > &v1, const Eigen::MatrixBase< Derived2 > &v2)
Definition Point.hpp:112
__int64 int64_t
Definition unistd.h:76

References Slic3r::angle(), Slic3r::cross2(), and M_PI.

Referenced by Slic3r::Arachne::removeColinearEdges().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ isInsideCorner()

static bool Slic3r::Arachne::LinearAlg2D::isInsideCorner ( const Point a,
const Point b,
const Point c,
const Vec2i64 query_point 
)
inlinestatic

Test whether a point is inside a corner. Whether point query_point is left of the corner abc. Whether the query_point is in the circle half left of ab and left of bc, rather than to the right.

Test whether the query_point is inside of a polygon w.r.t a single corner.

20{
21 // Visualisation for the algorithm below:
22 //
23 // query
24 // |
25 // |
26 // |
27 // perp-----------b
28 // / \ (note that the lines
29 // / \ AB and AC are normalized
30 // / \ to 10000 units length)
31 // a c
32 //
33
34 auto normal = [](const Point &p0, coord_t len) -> Point {
35 int64_t _len = p0.cast<int64_t>().norm();
36 if (_len < 1)
37 return {len, 0};
38 return (p0.cast<int64_t>() * int64_t(len) / _len).cast<coord_t>();
39 };
40
41 constexpr coord_t normal_length = 10000; //Create a normal vector of reasonable length in order to reduce rounding error.
42 const Point ba = normal(a - b, normal_length);
43 const Point bc = normal(c - b, normal_length);
44 const Vec2d bq = query_point.cast<double>() - b.cast<double>();
45 const Vec2d perpendicular = perp(bq); //The query projects to this perpendicular to coordinate 0.
46
47 const double project_a_perpendicular = ba.cast<double>().dot(perpendicular); //Project vertex A on the perpendicular line.
48 const double project_c_perpendicular = bc.cast<double>().dot(perpendicular); //Project vertex C on the perpendicular line.
49 if ((project_a_perpendicular > 0.) != (project_c_perpendicular > 0.)) //Query is between A and C on the projection.
50 {
51 return project_a_perpendicular > 0.; //Due to the winding order of corner ABC, this means that the query is inside.
52 }
53 else //Beyond either A or C, but it could still be inside of the polygon.
54 {
55 const double project_a_parallel = ba.cast<double>().dot(bq); //Project not on the perpendicular, but on the original.
56 const double project_c_parallel = bc.cast<double>().dot(bq);
57
58 //Either:
59 // * A is to the right of B (project_a_perpendicular > 0) and C is below A (project_c_parallel < project_a_parallel), or
60 // * A is to the left of B (project_a_perpendicular < 0) and C is above A (project_c_parallel > project_a_parallel).
61 return (project_c_parallel < project_a_parallel) == (project_a_perpendicular > 0.);
62 }
63}
Definition Point.hpp:158
int32_t coord_t
Definition libslic3r.h:39

References Slic3r::dot(), Slic3r::Arachne::normal(), and Slic3r::perp().

Referenced by Slic3r::Arachne::SkeletalTrapezoidation::computePointCellRange().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pointIsLeftOfLine()

static int64_t Slic3r::Arachne::LinearAlg2D::pointIsLeftOfLine ( const Point p,
const Point a,
const Point b 
)
inlinestatic

Returns the determinant of the 2D matrix defined by the the vectors ab and ap as rows.

The returned value is zero for p lying (approximately) on the line going through a and b The value is positive for values lying to the left and negative for values lying to the right when looking from a to b.

Parameters
pthe point to check
athe from point of the line
bthe to point of the line
Returns
a positive value when p lies to the left of the line from a to b
77{
78 return int64_t(b.x() - a.x()) * int64_t(p.y() - a.y()) - int64_t(b.y() - a.y()) * int64_t(p.x() - a.x());
79}

Referenced by Slic3r::Arachne::fixSelfIntersections().

+ Here is the caller graph for this function: