KiCad PCB EDA Suite
Loading...
Searching...
No Matches
marker_base.cpp
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) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
27
28
29#include "base_screen.h"
30#include "marker_base.h"
31#include <core/arraydim.h>
35
36
45{
46 VECTOR2I( 0, 0 ),
47 VECTOR2I( 8, 1 ),
48 VECTOR2I( 4, 3 ),
49 VECTOR2I( 13, 8 ),
50 VECTOR2I( 9, 9 ),
51 VECTOR2I( 8, 13 ),
52 VECTOR2I( 3, 4 ),
53 VECTOR2I( 1, 8 ),
54 VECTOR2I( 0, 0 )
55};
56
58
59
60MARKER_BASE::MARKER_BASE( int aScalingFactor, std::shared_ptr<RC_ITEM> aItem, MARKER_T aType ) :
61 m_markerType( aType ),
62 m_excluded( false ),
63 m_rcItem( std::move( aItem ) ),
64 m_scalingFactor( aScalingFactor )
65{
66 const VECTOR2I* point_shape = MarkerShapeCorners;
67 VECTOR2I start( point_shape->x, point_shape->y );
68 VECTOR2I end = start;
69
70 for( unsigned ii = 1; ii < CORNERS_COUNT; ii++ )
71 {
72 ++point_shape;
73 start.x = std::min( start.x, point_shape->x );
74 start.y = std::min( start.y, point_shape->y );
75 end.x = std::max( end.x, point_shape->x );
76 end.y = std::max( end.y, point_shape->y );
77 }
78
79 m_shapeBoundingBox.SetOrigin( start);
80 m_shapeBoundingBox.SetEnd( end);
81}
82
83
84bool MARKER_BASE::HitTestMarker( const VECTOR2I& aHitPosition, int aAccuracy ) const
85{
86 const BOX2I bbox = GetBoundingBoxMarker().GetInflated( aAccuracy );
87
88 // Fast hit test using boundary box. A finer test will be made if requested
89 bool hit = bbox.Contains( aHitPosition );
90
91 if( hit ) // Fine test
92 {
93 SHAPE_LINE_CHAIN polygon;
94 ShapeToPolygon( polygon );
95 VECTOR2I rel_pos( aHitPosition - m_Pos );
96 hit = polygon.PointInside( rel_pos, aAccuracy );
97 }
98
99 return hit;
100}
101
102
103bool MARKER_BASE::HitTestMarker( const BOX2I& aRect, bool aContained, int aAccuracy ) const
104{
105 const BOX2I bbox = GetBoundingBoxMarker().GetInflated( aAccuracy );
106
107 if( aContained )
108 return aRect.Contains( bbox );
109
110 return aRect.Intersects( bbox );
111}
112
113
114bool MARKER_BASE::HitTestMarker( const SHAPE_LINE_CHAIN& aPoly, bool aContained ) const
115{
116 SHAPE_LINE_CHAIN shape;
117 ShapeToPolygon( shape );
118 shape.Move( m_Pos );
119
120 return KIGEOM::ShapeHitTest( aPoly, shape, aContained );
121}
122
123
124void MARKER_BASE::ShapeToPolygon( SHAPE_LINE_CHAIN& aPolygon, int aScale ) const
125{
126 if( aScale < 0 )
127 aScale = MarkerScale();
128
129 for( const VECTOR2I& corner : MarkerShapeCorners )
130 aPolygon.Append( corner * aScale );
131
132 // Be sure aPolygon is seen as a closed polyline:
133 aPolygon.SetClosed( true );
134}
135
136
138{
140
141 VECTOR2I pos = m_Pos;
142 pos += m_shapeBoundingBox.GetPosition() * m_scalingFactor;
143
144 return BOX2I( pos, bbox.GetSize() * m_scalingFactor );
145}
146
147
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Returns # of elements in an array.
Definition arraydim.h:27
BASE_SCREEN class implementation.
BOX2< VECTOR2I > BOX2I
Definition box2.h:918
constexpr bool Contains(const Vec &aPoint) const
Definition box2.h:164
constexpr BOX2< Vec > GetInflated(coord_type aDx, coord_type aDy) const
Get a new rectangle that is this one, inflated by aDx and aDy.
Definition box2.h:634
constexpr const SizeVec & GetSize() const
Definition box2.h:202
constexpr bool Intersects(const BOX2< Vec > &aRect) const
Definition box2.h:307
bool HitTestMarker(const VECTOR2I &aHitPosition, int aAccuracy) const
Test if the given VECTOR2I is within the bounds of this object.
int m_scalingFactor
Scaling factor to convert corners coordinates to internal units.
int MarkerScale() const
The scaling factor to convert polygonal shape coordinates to internal units.
Definition marker_base.h:65
VECTOR2I m_Pos
Position of the marker.
MARKER_T m_markerType
The type of marker.
bool m_excluded
User has excluded this specific error.
std::shared_ptr< RC_ITEM > m_rcItem
BOX2I m_shapeBoundingBox
Bounding box of the graphic symbol relative to the position of the shape in marker shape units.
void ShapeToPolygon(SHAPE_LINE_CHAIN &aPolygon, int aScale=-1) const
Return the shape polygon in internal units in a SHAPE_LINE_CHAIN the coordinates are relatives to the...
MARKER_BASE(int aScalingFactor, std::shared_ptr< RC_ITEM > aItem, MARKER_T aType=MARKER_UNSPEC)
BOX2I GetBoundingBoxMarker() const
Return the orthogonal, bounding box of this object for display purposes.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
void Move(const VECTOR2I &aVector) override
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
bool PointInside(const VECTOR2I &aPt, int aAccuracy=0, bool aUseBBoxCache=false) const override
Check if point aP lies inside a closed shape.
a few functions useful in geometry calculations.
static const VECTOR2I MarkerShapeCorners[]
The graphic shape of markers is a polygon.
const unsigned CORNERS_COUNT
bool ShapeHitTest(const SHAPE_LINE_CHAIN &aHitter, const SHAPE &aHittee, bool aHitteeContained)
Perform a shape-to-shape hit test.
STL namespace.
VECTOR2I end
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683