KiCad PCB EDA Suite
Loading...
Searching...
No Matches
seg.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 (C) 2013 CERN
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * @author Tomasz Wlostowski <[email protected]>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 */
22
23#ifndef __SEG_H
24#define __SEG_H
25
26#include <math.h> // for sqrt
27#include <stdlib.h> // for abs
28#include <optional>
29#include <ostream> // for operator<<, ostream, basic_os...
30#include <type_traits> // for swap
31
32#include <math/vector2d.h>
33#include <geometry/eda_angle.h>
34
35typedef std::optional<VECTOR2I> OPT_VECTOR2I;
36
37class SEG
38{
39public:
41 friend inline std::ostream& operator<<( std::ostream& aStream, const SEG& aSeg );
42
43 /* Start and the of the segment. Public, to make access simpler.
44 */
47
52 {
53 m_index = -1;
54 }
55
59 SEG( int aX1, int aY1, int aX2, int aY2 ) :
60 A( VECTOR2I( aX1, aY1 ) ),
61 B( VECTOR2I( aX2, aY2 ) )
62 {
63 m_index = -1;
64 }
65
69 SEG( const VECTOR2I& aA, const VECTOR2I& aB ) :
70 A( aA ),
71 B( aB )
72 {
73 m_index = -1;
74 }
75
83 SEG( const VECTOR2I& aA, const VECTOR2I& aB, int aIndex ) :
84 A( aA ),
85 B( aB )
86 {
87 m_index = aIndex;
88 }
89
93 SEG( const SEG& aSeg ) :
94 A( aSeg.A ),
95 B( aSeg.B ),
96 m_index( aSeg.m_index )
97 {
98 }
99
100 SEG& operator=( const SEG& aSeg )
101 {
102 A = aSeg.A;
103 B = aSeg.B;
104 m_index = aSeg.m_index;
105
106 return *this;
107 }
108
109 bool operator==( const SEG& aSeg ) const
110 {
111 return (A == aSeg.A && B == aSeg.B) ;
112 }
113
114 bool operator!=( const SEG& aSeg ) const
115 {
116 return (A != aSeg.A || B != aSeg.B);
117 }
118
119 static SEG::ecoord Square( int a )
120 {
121 return ecoord( a ) * a;
122 }
123
131 VECTOR2I LineProject( const VECTOR2I& aP ) const;
132
139 int Side( const VECTOR2I& aP ) const
140 {
141 const ecoord det = ( B - A ).Cross( aP - A );
142
143 return det < 0 ? -1 : ( det > 0 ? 1 : 0 );
144 }
145
155 int LineDistance( const VECTOR2I& aP, bool aDetermineSide = false ) const;
156
163 EDA_ANGLE Angle( const SEG& aOther ) const;
164
170 const VECTOR2I NearestPoint( const VECTOR2I& aP ) const;
171
177 const VECTOR2I NearestPoint( const SEG &aSeg ) const;
178
188 bool NearestPoints( const SEG& aSeg, VECTOR2I& aPtA, VECTOR2I& aPtB, int64_t& aDistSq ) const;
189
195 const VECTOR2I ReflectPoint( const VECTOR2I& aP ) const;
196
206 OPT_VECTOR2I Intersect( const SEG& aSeg, bool aIgnoreEndpoints = false,
207 bool aLines = false ) const;
208
209 bool Intersects( const SEG& aSeg ) const;
210
217 OPT_VECTOR2I IntersectLines( const SEG& aSeg ) const
218 {
219 return Intersect( aSeg, false, true );
220 }
221
230 bool IntersectsLine( double aSlope, double aOffset, VECTOR2I& aIntersection ) const;
231
238 SEG PerpendicularSeg( const VECTOR2I& aP ) const;
239
246 SEG ParallelSeg( const VECTOR2I& aP ) const;
247
248 bool Collide( const SEG& aSeg, int aClearance, int* aActual = nullptr ) const;
249
250 ecoord SquaredDistance( const SEG& aSeg ) const;
251
258 int Distance( const SEG& aSeg ) const;
259
260 ecoord SquaredDistance( const VECTOR2I& aP ) const;
261
268 int Distance( const VECTOR2I& aP ) const;
269
270 void CanonicalCoefs( ecoord& qA, ecoord& qB, ecoord& qC ) const
271 {
272 qA = ecoord{ A.y } - B.y;
273 qB = ecoord{ B.x } - A.x;
274 qC = -qA * A.x - qB * A.y;
275 }
276
283 bool Collinear( const SEG& aSeg ) const
284 {
285 ecoord qa, qb, qc;
286 CanonicalCoefs( qa, qb, qc );
287
288 ecoord d1 = std::abs( aSeg.A.x * qa + aSeg.A.y * qb + qc );
289 ecoord d2 = std::abs( aSeg.B.x * qa + aSeg.B.y * qb + qc );
290
291 return ( d1 <= 1 && d2 <= 1 );
292 }
293
294 bool ApproxCollinear( const SEG& aSeg, int aDistanceThreshold = 1 ) const;
295 bool ApproxParallel( const SEG& aSeg, int aDistanceThreshold = 1 ) const;
296 bool ApproxPerpendicular( const SEG& aSeg ) const;
297
298 bool Overlaps( const SEG& aSeg ) const
299 {
300 if( aSeg.A == aSeg.B ) // single point corner case
301 {
302 if( A == aSeg.A || B == aSeg.A )
303 return false;
304
305 return Contains( aSeg.A );
306 }
307
308 if( !Collinear( aSeg ) )
309 return false;
310
311 if( Contains( aSeg.A ) || Contains( aSeg.B ) )
312 return true;
313
314 if( aSeg.Contains( A ) || aSeg.Contains( B ) )
315 return true;
316
317 return false;
318 }
319
320
321 bool Contains( const SEG& aSeg ) const
322 {
323 if( aSeg.A == aSeg.B ) // single point corner case
324 return Contains( aSeg.A );
325
326 if( !Collinear( aSeg ) )
327 return false;
328
329 if( Contains( aSeg.A ) && Contains( aSeg.B ) )
330 return true;
331
332 return false;
333 }
334
340 int Length() const
341 {
342 return ( A - B ).EuclideanNorm();
343 }
344
346 {
347 return ( A - B ).SquaredEuclideanNorm();
348 }
349
350 ecoord TCoef( const VECTOR2I& aP ) const;
351
358 int Index() const
359 {
360 return m_index;
361 }
362
363 bool Contains( const VECTOR2I& aP, int aSqDistanceThreshold = 3 ) const;
364
365 void Reverse()
366 {
367 std::swap( A, B );
368 }
369
370 SEG Reversed() const
371 {
372 return SEG( B, A );
373 }
374
377 {
378 return A + ( B - A ) / 2;
379 }
380
381 bool operator<( const SEG& aSeg ) const
382 {
383 if( A == aSeg.A )
384 return B < aSeg.B;
385
386 return A < aSeg.A;
387 }
388
389private:
390
391 bool checkCollinearOverlap( const SEG& aSeg, bool useXAxis, bool aIgnoreEndpoints, VECTOR2I* aPt ) const;
392 bool intersects( const SEG& aSeg, bool aIgnoreEndpoints = false, bool aLines = false,
393 VECTOR2I* aPt = nullptr ) const;
394
395 bool mutualDistanceSquared( const SEG& aSeg, ecoord& aD1, ecoord& aD2 ) const;
396
397private:
400};
401
402inline SEG::ecoord SEG::TCoef( const VECTOR2I& aP ) const
403{
404 VECTOR2I d = B - A;
405 return d.Dot( aP - A);
406}
407
408inline std::ostream& operator<<( std::ostream& aStream, const SEG& aSeg )
409{
410 aStream << "[ " << aSeg.A << " - " << aSeg.B << " ]";
411
412 return aStream;
413}
414
415#endif // __SEG_H
Definition seg.h:38
const VECTOR2I ReflectPoint(const VECTOR2I &aP) const
Reflect a point using this segment as axis.
Definition seg.cpp:630
VECTOR2I A
Definition seg.h:45
int LineDistance(const VECTOR2I &aP, bool aDetermineSide=false) const
Return the closest Euclidean distance between point aP and the line defined by the ends of segment (t...
Definition seg.cpp:710
ecoord SquaredDistance(const SEG &aSeg) const
Definition seg.cpp:35
bool IntersectsLine(double aSlope, double aOffset, VECTOR2I &aIntersection) const
Check if this segment intersects a line defined by slope aSlope and offset aOffset.
Definition seg.cpp:412
bool intersects(const SEG &aSeg, bool aIgnoreEndpoints=false, bool aLines=false, VECTOR2I *aPt=nullptr) const
Definition seg.cpp:267
int m_index
index within the parent shape (used when m_is_local == false)
Definition seg.h:399
VECTOR2I::extended_type ecoord
Definition seg.h:40
void CanonicalCoefs(ecoord &qA, ecoord &qB, ecoord &qC) const
Definition seg.h:270
SEG(const VECTOR2I &aA, const VECTOR2I &aB, int aIndex)
Create a segment between (aA) and (aB), referenced to a multi-segment shape.
Definition seg.h:83
friend std::ostream & operator<<(std::ostream &aStream, const SEG &aSeg)
Definition seg.h:408
SEG & operator=(const SEG &aSeg)
Definition seg.h:100
VECTOR2I B
Definition seg.h:46
int Index() const
Return the index of this segment in its parent shape (applicable only to non-local segments).
Definition seg.h:358
const VECTOR2I NearestPoint(const VECTOR2I &aP) const
Compute a point on the segment (this) that is closest to point aP.
Definition seg.cpp:599
bool Intersects(const SEG &aSeg) const
Definition seg.cpp:395
int Length() const
Return the length (this).
Definition seg.h:340
SEG(int aX1, int aY1, int aX2, int aY2)
Create a segment between (aX1, aY1) and (aX2, aY2).
Definition seg.h:59
bool checkCollinearOverlap(const SEG &aSeg, bool useXAxis, bool aIgnoreEndpoints, VECTOR2I *aPt) const
Definition seg.cpp:175
OPT_VECTOR2I Intersect(const SEG &aSeg, bool aIgnoreEndpoints=false, bool aLines=false) const
Compute intersection point of segment (this) with segment aSeg.
Definition seg.cpp:401
static SEG::ecoord Square(int a)
Definition seg.h:119
VECTOR2I Center() const
Returns the center point of the line.
Definition seg.h:376
bool Collide(const SEG &aSeg, int aClearance, int *aActual=nullptr) const
Definition seg.cpp:497
bool ApproxParallel(const SEG &aSeg, int aDistanceThreshold=1) const
Definition seg.cpp:771
SEG()
Create an empty (0, 0) segment.
Definition seg.h:51
bool Collinear(const SEG &aSeg) const
Check if segment aSeg lies on the same line as (this).
Definition seg.h:283
SEG ParallelSeg(const VECTOR2I &aP) const
Compute a segment parallel to this one, passing through point aP.
Definition seg.cpp:488
ecoord TCoef(const VECTOR2I &aP) const
Definition seg.h:402
OPT_VECTOR2I IntersectLines(const SEG &aSeg) const
Compute the intersection point of lines passing through ends of (this) and aSeg.
Definition seg.h:217
ecoord SquaredLength() const
Definition seg.h:345
bool operator==(const SEG &aSeg) const
Definition seg.h:109
void Reverse()
Definition seg.h:365
bool ApproxPerpendicular(const SEG &aSeg) const
Definition seg.cpp:783
bool ApproxCollinear(const SEG &aSeg, int aDistanceThreshold=1) const
Definition seg.cpp:759
bool operator<(const SEG &aSeg) const
Definition seg.h:381
bool Overlaps(const SEG &aSeg) const
Definition seg.h:298
bool mutualDistanceSquared(const SEG &aSeg, ecoord &aD1, ecoord &aD2) const
Definition seg.cpp:730
bool operator!=(const SEG &aSeg) const
Definition seg.h:114
bool NearestPoints(const SEG &aSeg, VECTOR2I &aPtA, VECTOR2I &aPtB, int64_t &aDistSq) const
Compute closest points between this segment and aSeg.
Definition seg.cpp:117
int Distance(const SEG &aSeg) const
Compute minimum Euclidean distance to segment aSeg.
Definition seg.cpp:668
bool Contains(const SEG &aSeg) const
Definition seg.h:321
SEG(const SEG &aSeg)
Copy constructor.
Definition seg.h:93
VECTOR2I LineProject(const VECTOR2I &aP) const
Compute the perpendicular projection point of aP on a line passing through ends of the segment.
Definition seg.cpp:651
SEG PerpendicularSeg(const VECTOR2I &aP) const
Compute a segment perpendicular to this one, passing through point aP.
Definition seg.cpp:479
int Side(const VECTOR2I &aP) const
Determine on which side of directed line passing via segment ends point aP lies.
Definition seg.h:139
EDA_ANGLE Angle(const SEG &aOther) const
Determine the smallest angle between two segments.
Definition seg.cpp:66
SEG(const VECTOR2I &aA, const VECTOR2I &aB)
Create a segment between (aA) and (aB).
Definition seg.h:69
SEG Reversed() const
Definition seg.h:370
VECTOR2_TRAITS< int32_t >::extended_type extended_type
Definition vector2d.h:69
constexpr extended_type Dot(const VECTOR2< T > &aVector) const
Compute dot product of self with aVector.
Definition vector2d.h:567
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition eda_angle.h:437
std::ostream & operator<<(std::ostream &aStream, const SEG &aSeg)
Definition seg.h:408
std::optional< VECTOR2I > OPT_VECTOR2I
Definition seg.h:35
VECTOR2I::extended_type ecoord
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:708