KiCad PCB EDA Suite
Loading...
Searching...
No Matches
vertex_set.h
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.TXT for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 3
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 *
19 * Based on Uniform Plane Subdivision algorithm from Lamot, Marko, and Borut Žalik.
20 * "A fast polygon triangulation algorithm based on uniform plane subdivision."
21 * Computers & graphics 27, no. 2 (2003): 239-253.
22 *
23 * Code derived from:
24 * K-3D which is Copyright (c) 2005-2006, Romain Behar, GPL-2, license above
25 * earcut which is Copyright (c) 2016, Mapbox, ISC
26 *
27 * ISC License:
28 * Permission to use, copy, modify, and/or distribute this software for any purpose
29 * with or without fee is hereby granted, provided that the above copyright notice
30 * and this permission notice appear in all copies.
31 *
32 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
33 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
34 * FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
35 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
36 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
37 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
38 * THIS SOFTWARE.
39 *
40 */
41
42#ifndef VERTEX_SET_H
43#define VERTEX_SET_H
44
45#include <algorithm>
46#include <deque>
47
48#include <math/box2.h>
50
51class VERTEX_SET;
52
53class VERTEX
54{
55 public:
56
57 VERTEX( int aIndex, double aX, double aY, VERTEX_SET* aParent, void* aUserData = nullptr ) :
58 i( aIndex ),
59 x( aX ),
60 y( aY ),
61 parent( aParent ),
62 m_userData( aUserData )
63 {
64 }
65
66 VERTEX& operator=( const VERTEX& ) = delete;
67 VERTEX& operator=( VERTEX&& ) = delete;
68
69 bool operator==( const VERTEX& rhs ) const
70 {
71 return this->x == rhs.x && this->y == rhs.y;
72 }
73 bool operator!=( const VERTEX& rhs ) const { return !( *this == rhs ); }
74
75 void* GetUserData() const { return m_userData; }
76
80 void remove()
81 {
82 next->prev = prev;
83 prev->next = next;
84
85 if( prevZ )
86 prevZ->nextZ = nextZ;
87
88 if( nextZ )
89 nextZ->prevZ = prevZ;
90
91 next = nullptr;
92 prev = nullptr;
93 nextZ = nullptr;
94 prevZ = nullptr;
95 }
96
97
98
109 VERTEX* split( VERTEX* b );
110
111 void updateOrder();
112
118 {
119 VERTEX* p = next;
120
121 while( p != this )
122 {
126 if( *p == *p->next )
127 {
128 p = p->prev;
129 p->next->remove();
130
131 if( p == p->next )
132 break;
133 }
134
135 p->updateOrder();
136 p = p->next;
137 };
138
139 updateOrder();
140 zSort();
141 }
142
146 void zSort()
147 {
148 std::vector<VERTEX*> queue;
149
150 queue.push_back( this );
151
152 for( VERTEX* p = next; p && p != this; p = p->next )
153 queue.push_back( p );
154
155 std::sort( queue.begin(), queue.end(), []( const VERTEX* a, const VERTEX* b )
156 {
157 if( a->z != b->z )
158 return a->z < b->z;
159
160 if( a->x != b->x )
161 return a->x < b->x;
162
163 if( a->y != b->y )
164 return a->y < b->y;
165
166 return a->i < b->i;
167 } );
168
169 VERTEX* prev_elem = nullptr;
170
171 for( VERTEX* elem : queue )
172 {
173 if( prev_elem )
174 prev_elem->nextZ = elem;
175
176 elem->prevZ = prev_elem;
177 prev_elem = elem;
178 }
179
180 prev_elem->nextZ = nullptr;
181 }
182
183
187 bool inTriangle( const VERTEX& a, const VERTEX& b, const VERTEX& c )
188 {
189 return ( c.x - x ) * ( a.y - y ) - ( a.x - x ) * ( c.y - y ) >= 0
190 && ( a.x - x ) * ( b.y - y ) - ( b.x - x ) * ( a.y - y ) >= 0
191 && ( b.x - x ) * ( c.y - y ) - ( c.x - x ) * ( b.y - y ) >= 0;
192 }
193
198 double area( const VERTEX* aEnd = nullptr ) const
199 {
200 const VERTEX* p = this;
201 double a = 0.0;
202
203 do
204 {
205 a += ( p->x + p->next->x ) * ( p->next->y - p->y );
206 p = p->next;
207 } while( p != this && p != aEnd );
208
209 if( p != this )
210 a += ( p->x + x ) * ( y - p->y );
211
212 return a / 2;
213 }
214
228 bool isEar( bool aMatchUserData = false ) const;
229
230 const int i;
231 const double x;
232 const double y;
234
235 // previous and next vertices nodes in a polygon ring
236 VERTEX* prev = nullptr;
237 VERTEX* next = nullptr;
238
239 // z-order curve value
240 uint32_t z = 0;
241
242 // previous and next nodes in z-order
243 VERTEX* prevZ = nullptr;
244 VERTEX* nextZ = nullptr;
245
246 void* m_userData = nullptr;
247};
248
250{
251 friend class VERTEX;
252
253public:
254 VERTEX_SET( int aSimplificationLevel )
255 {
256 m_simplificationLevel = aSimplificationLevel * ( VECTOR2I::extended_type ) aSimplificationLevel;
257 }
259
260 void SetBoundingBox( const BOX2I& aBBox );
261
270 VERTEX* insertVertex( int aIndex, const VECTOR2I& pt, VERTEX* last, void* aUserData = nullptr );
271
279 VERTEX* createList( const SHAPE_LINE_CHAIN& points, VERTEX* aTail = nullptr, void* aUserData = nullptr );
280
281protected:
282
289 VERTEX* getNextOutlineVertex( const VERTEX* aPt ) const;
290
297 VERTEX* getPrevOutlineVertex( const VERTEX* aPt ) const;
298
308 bool locallyInside( const VERTEX* a, const VERTEX* b ) const;
309
316 bool middleInside( const VERTEX* a, const VERTEX* b ) const;
317
324 bool same_point( const VERTEX* aA, const VERTEX* aB ) const;
325
331 uint32_t zOrder( const double aX, const double aY ) const;
332
336 double area( const VERTEX* p, const VERTEX* q, const VERTEX* r ) const;
337
339 std::deque<VERTEX> m_vertices;
341};
342
343
344
345#endif // VERTEX_SET_H
BOX2< VECTOR2I > BOX2I
Definition box2.h:918
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
VECTOR2_TRAITS< int32_t >::extended_type extended_type
Definition vector2d.h:69
std::deque< VERTEX > m_vertices
Definition vertex_set.h:339
friend class VERTEX
Definition vertex_set.h:251
bool middleInside(const VERTEX *a, const VERTEX *b) const
Check if the middle of the segment from a to b is inside the polygon.
VERTEX * createList(const SHAPE_LINE_CHAIN &points, VERTEX *aTail=nullptr, void *aUserData=nullptr)
Create a list of vertices from a line chain.
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 o...
BOX2I m_bbox
Definition vertex_set.h:338
VERTEX * getPrevOutlineVertex(const VERTEX *aPt) const
Get the previous vertex in the outline, avoiding steiner points and points that overlap with splits.
void SetBoundingBox(const BOX2I &aBBox)
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.
VERTEX * insertVertex(int aIndex, const VECTOR2I &pt, VERTEX *last, void *aUserData=nullptr)
Insert a vertex into the vertex set.
VERTEX_SET(int aSimplificationLevel)
Definition vertex_set.h:254
VECTOR2I::extended_type m_simplificationLevel
Definition vertex_set.h:340
VERTEX * getNextOutlineVertex(const VERTEX *aPt) const
Get the next vertex in the outline, avoiding steiner points and points that overlap with splits.
uint32_t zOrder(const double aX, const double aY) const
Note that while the inputs are doubles, these are scaled by the size of the bounding box to fit into ...
bool same_point(const VERTEX *aA, const VERTEX *aB) const
Check if two vertices are at the same point.
void zSort()
Sort all vertices in this vertex's list by their Morton code.
Definition vertex_set.h:146
VERTEX * split(VERTEX *b)
Split the referenced polygon between the reference point and vertex b, assuming they are in the same ...
VERTEX & operator=(const VERTEX &)=delete
const double x
Definition vertex_set.h:231
bool operator!=(const VERTEX &rhs) const
Definition vertex_set.h:73
VERTEX * next
Definition vertex_set.h:237
VERTEX * prevZ
Definition vertex_set.h:243
void updateList()
After inserting or changing nodes, this function should be called to remove duplicate vertices and en...
Definition vertex_set.h:117
bool inTriangle(const VERTEX &a, const VERTEX &b, const VERTEX &c)
Check to see if triangle surrounds our current vertex.
Definition vertex_set.h:187
VERTEX * nextZ
Definition vertex_set.h:244
VERTEX * prev
Definition vertex_set.h:236
const int i
Definition vertex_set.h:230
bool operator==(const VERTEX &rhs) const
Definition vertex_set.h:69
void * GetUserData() const
Definition vertex_set.h:75
void * m_userData
Definition vertex_set.h:246
void remove()
Remove the node from the linked list and z-ordered linked list.
Definition vertex_set.h:80
VERTEX(int aIndex, double aX, double aY, VERTEX_SET *aParent, void *aUserData=nullptr)
Definition vertex_set.h:57
VERTEX & operator=(VERTEX &&)=delete
double area(const VERTEX *aEnd=nullptr) const
Returns the signed area of the polygon connected to the current vertex, optionally ending at a specif...
Definition vertex_set.h:198
uint32_t z
Definition vertex_set.h:240
bool isEar(bool aMatchUserData=false) const
Check whether the given vertex is in the middle of an ear.
const double y
Definition vertex_set.h:232
void updateOrder()
VERTEX_SET * parent
Definition vertex_set.h:233
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683