KiCad PCB EDA Suite
|
#include <polygon_triangulation.h>
Classes | |
struct | VERTEX |
Public Member Functions | |
POLYGON_TRIANGULATION (SHAPE_POLY_SET::TRIANGULATED_POLYGON &aResult) | |
bool | TesselatePolygon (const SHAPE_LINE_CHAIN &aPoly, SHAPE_POLY_SET::TRIANGULATED_POLYGON *aHintData) |
Private Member Functions | |
int32_t | zOrder (const double aX, const double aY) const |
Calculate the Morton code of the Vertex http://www.graphics.stanford.edu/~seander/bithacks.html#InterleaveBMN. | |
void | logRemaining () |
Outputs a list of vertices that have not yet been triangulated. | |
void | logVertices (VERTEX *aStart, std::set< VERTEX * > *aSeen) |
VERTEX * | simplifyList (VERTEX *aStart) |
Simplify the line chain by removing points that are too close to each other. | |
VERTEX * | removeNullTriangles (VERTEX *aStart) |
Iterate through the list to remove NULL triangles if they exist. | |
VERTEX * | createList (const SHAPE_LINE_CHAIN &points) |
Take a SHAPE_LINE_CHAIN and links each point into a circular, doubly-linked list. | |
bool | earcutList (VERTEX *aPoint, int pass=0) |
Walk through a circular linked list starting at aPoint. | |
bool | isTooSmall (const VERTEX *aPoint) const |
Check whether a given vertex is too small to matter. | |
bool | isEar (VERTEX *aEar) const |
Check whether the given vertex is in the middle of an ear. | |
void | subdividePolygon (VERTEX *aStart, int pass=0) |
Inserts a new vertex halfway between each existing pair of vertices. | |
bool | splitPolygon (VERTEX *start) |
If we cannot find an ear to slice in the current polygon list, we use this to split the polygon into two separate lists and slice them each independently. | |
bool | goodSplit (const VERTEX *a, const VERTEX *b) const |
Check if a segment joining two vertices lies fully inside the polygon. | |
double | area (const VERTEX *p, const VERTEX *q, const VERTEX *r) const |
Return the twice the signed area of the triangle formed by vertices p, q, and r. | |
constexpr int | sign (double aVal) const |
constexpr bool | overlapping (const VERTEX *p, const VERTEX *q, const VERTEX *r) const |
If p, q, and r are collinear and r lies between p and q, then return true. | |
bool | intersects (const VERTEX *p1, const VERTEX *q1, const VERTEX *p2, const VERTEX *q2) const |
Check for intersection between two segments, end points included. | |
bool | intersectsPolygon (const VERTEX *a, const VERTEX *b) const |
Check whether the segment from vertex a -> vertex b crosses any of the segments of the polygon of which vertex a is a member. | |
bool | locallyInside (const VERTEX *a, const VERTEX *b) const |
Check whether the segment from vertex a -> vertex b is inside the polygon around the immediate area of vertex a. | |
bool | middleInside (const VERTEX *a, const VERTEX *b) const |
Check to see if the segment halfway point between a and b is inside the polygon. | |
VERTEX * | insertVertex (const VECTOR2I &pt, VERTEX *last) |
Create an entry in the vertices lookup and optionally inserts the newly created vertex into an existing linked list. | |
Private Attributes | |
BOX2I | m_bbox |
std::deque< VERTEX > | m_vertices |
size_t | m_vertices_original_size |
SHAPE_POLY_SET::TRIANGULATED_POLYGON & | m_result |
Definition at line 63 of file polygon_triangulation.h.
|
inline |
Definition at line 66 of file polygon_triangulation.h.
|
inlineprivate |
Return the twice the signed area of the triangle formed by vertices p, q, and r.
Definition at line 962 of file polygon_triangulation.h.
References POLYGON_TRIANGULATION::VERTEX::x, and POLYGON_TRIANGULATION::VERTEX::y.
Referenced by earcutList(), goodSplit(), intersects(), isEar(), locallyInside(), removeNullTriangles(), and splitPolygon().
|
inlineprivate |
Take a SHAPE_LINE_CHAIN and links each point into a circular, doubly-linked list.
Definition at line 516 of file polygon_triangulation.h.
References SHAPE_LINE_CHAIN::CPoint(), ADVANCED_CFG::GetCfg(), insertVertex(), ADVANCED_CFG::m_TriangulateSimplificationLevel, POLYGON_TRIANGULATION::VERTEX::next, SHAPE_LINE_CHAIN::PointCount(), POLYGON_TRIANGULATION::VERTEX::remove(), VECTOR2< T >::SquaredEuclideanNorm(), TRIANGULATE_TRACE, VECTOR2< T >::x, and VECTOR2< T >::y.
Referenced by TesselatePolygon().
|
inlineprivate |
Walk through a circular linked list starting at aPoint.
For each point, test to see if the adjacent points form a triangle that is completely enclosed by the remaining polygon (an "ear" sticking off the polygon). If the three points form an ear, we log the ear's location and remove the center point from the linked list.
This function can be called recursively in the case of difficult polygons. In cases where there is an intersection (not technically allowed by KiCad, but could exist in an edited file), we create a single triangle and remove both vertices before attempting to.
Definition at line 577 of file polygon_triangulation.h.
References std::abs(), SHAPE_POLY_SET::TRIANGULATED_POLYGON::AddTriangle(), POLYGON_TRIANGULATION::VERTEX::area(), area(), ADVANCED_CFG::GetCfg(), POLYGON_TRIANGULATION::VERTEX::i, intersects(), isEar(), isTooSmall(), locallyInside(), m_result, ADVANCED_CFG::m_TriangulateMinimumArea, next(), POLYGON_TRIANGULATION::VERTEX::next, POLYGON_TRIANGULATION::VERTEX::prev, POLYGON_TRIANGULATION::VERTEX::remove(), removeNullTriangles(), splitPolygon(), subdividePolygon(), and TRIANGULATE_TRACE.
Referenced by splitPolygon(), and TesselatePolygon().
Check if a segment joining two vertices lies fully inside the polygon.
To do this, we first ensure that the line isn't along the polygon edge. Next, we know that if the line doesn't intersect the polygon, then it is either fully inside or fully outside the polygon. Next, we ensure that the proposed split is inside the local area of the polygon at both ends and the midpoint. Finally, we check to split creates two new polygons, each with positive area.
Definition at line 945 of file polygon_triangulation.h.
References POLYGON_TRIANGULATION::VERTEX::area(), area(), POLYGON_TRIANGULATION::VERTEX::i, intersectsPolygon(), locallyInside(), middleInside(), POLYGON_TRIANGULATION::VERTEX::next, POLYGON_TRIANGULATION::VERTEX::nextZ, POLYGON_TRIANGULATION::VERTEX::prev, and POLYGON_TRIANGULATION::VERTEX::prevZ.
Referenced by splitPolygon().
Create an entry in the vertices lookup and optionally inserts the newly created vertex into an existing linked list.
Definition at line 1083 of file polygon_triangulation.h.
References SHAPE_POLY_SET::TRIANGULATED_POLYGON::AddVertex(), SHAPE_POLY_SET::TRIANGULATED_POLYGON::GetVertexCount(), m_result, m_vertices, POLYGON_TRIANGULATION::VERTEX::next, POLYGON_TRIANGULATION::VERTEX::prev, VECTOR2< T >::x, and VECTOR2< T >::y.
Referenced by createList(), and subdividePolygon().
|
inlineprivate |
Check for intersection between two segments, end points included.
Definition at line 989 of file polygon_triangulation.h.
References area(), overlapping(), and sign().
Referenced by earcutList(), and intersectsPolygon().
|
inlineprivate |
Check whether the segment from vertex a -> vertex b crosses any of the segments of the polygon of which vertex a is a member.
Definition at line 1021 of file polygon_triangulation.h.
References POLYGON_TRIANGULATION::VERTEX::i, intersects(), m_vertices, and m_vertices_original_size.
Referenced by goodSplit().
|
inlineprivate |
Check whether the given vertex is in the middle of an ear.
This works by walking forward and backward in zOrder to the limits of the minimal bounding box formed around the triangle, checking whether any points are located inside the given triangle.
Definition at line 731 of file polygon_triangulation.h.
References area(), POLYGON_TRIANGULATION::VERTEX::inTriangle(), POLYGON_TRIANGULATION::VERTEX::next, POLYGON_TRIANGULATION::VERTEX::nextZ, POLYGON_TRIANGULATION::VERTEX::prev, POLYGON_TRIANGULATION::VERTEX::prevZ, POLYGON_TRIANGULATION::VERTEX::x, POLYGON_TRIANGULATION::VERTEX::y, POLYGON_TRIANGULATION::VERTEX::z, and zOrder().
Referenced by earcutList().
|
inlineprivate |
Check whether a given vertex is too small to matter.
Definition at line 708 of file polygon_triangulation.h.
References ADVANCED_CFG::GetCfg(), ADVANCED_CFG::m_TriangulateMinimumArea, POLYGON_TRIANGULATION::VERTEX::next, POLYGON_TRIANGULATION::VERTEX::prev, POLYGON_TRIANGULATION::VERTEX::x, and POLYGON_TRIANGULATION::VERTEX::y.
Referenced by earcutList().
|
inlineprivate |
Check whether the segment from vertex a -> vertex b is inside the polygon around the immediate area of vertex a.
We don't define the exact area over which the segment is inside but it is guaranteed to be inside the polygon immediately adjacent to vertex a.
Definition at line 1047 of file polygon_triangulation.h.
References area(), POLYGON_TRIANGULATION::VERTEX::next, and POLYGON_TRIANGULATION::VERTEX::prev.
Referenced by earcutList(), and goodSplit().
|
inlineprivate |
Outputs a list of vertices that have not yet been triangulated.
Definition at line 343 of file polygon_triangulation.h.
References logVertices(), and m_vertices.
Referenced by TesselatePolygon().
|
inlineprivate |
Definition at line 356 of file polygon_triangulation.h.
References POLYGON_TRIANGULATION::VERTEX::next, TRIANGULATE_TRACE, POLYGON_TRIANGULATION::VERTEX::x, and POLYGON_TRIANGULATION::VERTEX::y.
Referenced by logRemaining(), and splitPolygon().
Check to see if the segment halfway point between a and b is inside the polygon.
Definition at line 1058 of file polygon_triangulation.h.
References POLYGON_TRIANGULATION::VERTEX::next, POLYGON_TRIANGULATION::VERTEX::x, and POLYGON_TRIANGULATION::VERTEX::y.
Referenced by goodSplit().
|
inlineconstexprprivate |
If p, q, and r are collinear and r lies between p and q, then return true.
Definition at line 976 of file polygon_triangulation.h.
References POLYGON_TRIANGULATION::VERTEX::x, and POLYGON_TRIANGULATION::VERTEX::y.
Referenced by intersects().
Iterate through the list to remove NULL triangles if they exist.
This should only be called as a last resort when tesselation fails as the NULL triangles are inserted as Steiner points to improve the triangulation regularity of polygons
We've removed all possible triangles
Definition at line 446 of file polygon_triangulation.h.
References std::abs(), area(), POLYGON_TRIANGULATION::VERTEX::next, POLYGON_TRIANGULATION::VERTEX::prev, POLYGON_TRIANGULATION::VERTEX::remove(), simplifyList(), TRIANGULATE_TRACE, POLYGON_TRIANGULATION::VERTEX::x, and POLYGON_TRIANGULATION::VERTEX::y.
Referenced by earcutList().
|
inlineconstexprprivate |
Definition at line 968 of file polygon_triangulation.h.
Referenced by intersects().
Simplify the line chain by removing points that are too close to each other.
If no points are removed, it returns nullptr.
Definition at line 391 of file polygon_triangulation.h.
References ADVANCED_CFG::GetCfg(), ADVANCED_CFG::m_TriangulateSimplificationLevel, next(), POLYGON_TRIANGULATION::VERTEX::next, POLYGON_TRIANGULATION::VERTEX::prev, POLYGON_TRIANGULATION::VERTEX::remove(), VECTOR2< T >::SquaredEuclideanNorm(), TRIANGULATE_TRACE, POLYGON_TRIANGULATION::VERTEX::x, and POLYGON_TRIANGULATION::VERTEX::y.
Referenced by removeNullTriangles().
|
inlineprivate |
If we cannot find an ear to slice in the current polygon list, we use this to split the polygon into two separate lists and slice them each independently.
This is assured to generate at least one new ear if the split is successful
Definition at line 840 of file polygon_triangulation.h.
References area(), earcutList(), goodSplit(), POLYGON_TRIANGULATION::VERTEX::i, logVertices(), next(), POLYGON_TRIANGULATION::VERTEX::next, POLYGON_TRIANGULATION::VERTEX::nextZ, POLYGON_TRIANGULATION::VERTEX::prev, POLYGON_TRIANGULATION::VERTEX::prevZ, POLYGON_TRIANGULATION::VERTEX::split(), TRIANGULATE_TRACE, and POLYGON_TRIANGULATION::VERTEX::updateList().
Referenced by earcutList().
|
inlineprivate |
Inserts a new vertex halfway between each existing pair of vertices.
Definition at line 784 of file polygon_triangulation.h.
References insertVertex(), POLYGON_TRIANGULATION::VERTEX::next, TRIANGULATE_TRACE, POLYGON_TRIANGULATION::VERTEX::updateList(), POLYGON_TRIANGULATION::VERTEX::x, and POLYGON_TRIANGULATION::VERTEX::y.
Referenced by earcutList().
|
inline |
Place the polygon Vertices into a circular linked list and check for lists that have only 0, 1 or 2 elements and therefore cannot be polygons
If we have a hint data, we can skip the tesselation process as long as the the hint source did not need to subdivide the polygon.
Definition at line 70 of file polygon_triangulation.h.
References POLYGON_TRIANGULATION::VERTEX::area(), SHAPE_LINE_CHAIN::BBox(), SHAPE_POLY_SET::TRIANGULATED_POLYGON::Clear(), createList(), earcutList(), BOX2< Vec >::GetHeight(), BOX2< Vec >::GetWidth(), logRemaining(), m_bbox, m_result, m_vertices, m_vertices_original_size, POLYGON_TRIANGULATION::VERTEX::next, POLYGON_TRIANGULATION::VERTEX::prev, SHAPE_POLY_SET::TRIANGULATED_POLYGON::SetTriangles(), SHAPE_POLY_SET::TRIANGULATED_POLYGON::Triangles(), TRIANGULATE_TRACE, POLYGON_TRIANGULATION::VERTEX::updateList(), and SHAPE_POLY_SET::TRIANGULATED_POLYGON::Vertices().
Referenced by SHAPE_POLY_SET::cacheTriangulation().
|
inlineprivate |
Calculate the Morton code of the Vertex http://www.graphics.stanford.edu/~seander/bithacks.html#InterleaveBMN.
Definition at line 321 of file polygon_triangulation.h.
References BOX2< Vec >::GetHeight(), BOX2< Vec >::GetWidth(), BOX2< Vec >::GetX(), BOX2< Vec >::GetY(), and m_bbox.
Referenced by isEar(), and POLYGON_TRIANGULATION::VERTEX::updateOrder().
|
private |
Definition at line 1106 of file polygon_triangulation.h.
Referenced by TesselatePolygon(), and zOrder().
|
private |
Definition at line 1109 of file polygon_triangulation.h.
Referenced by earcutList(), insertVertex(), and TesselatePolygon().
|
private |
Definition at line 1107 of file polygon_triangulation.h.
Referenced by insertVertex(), intersectsPolygon(), logRemaining(), POLYGON_TRIANGULATION::VERTEX::split(), and TesselatePolygon().
|
private |
Definition at line 1108 of file polygon_triangulation.h.
Referenced by intersectsPolygon(), and TesselatePolygon().