KiCad PCB EDA Suite
arc_assistant.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) 2017 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 2
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, you may find one here:
18  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19  * or you may search the http://www.gnu.org website for the version 2 license,
20  * or you may write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 
25 
28 #include <view/view.h>
29 #include <pcb_painter.h>
30 
31 #include <common.h>
32 #include <base_units.h>
33 
34 using namespace KIGFX::PREVIEW;
35 
37  EDA_ITEM( NOT_USED ),
38  m_constructMan( aManager )
39 {
40 }
41 
42 
44 {
45  BOX2I tmp;
46 
47  // no bounding box when no graphic shown
48  if( m_constructMan.IsReset() )
49  return tmp;
50 
51  // just enclose the whle circular area
52  auto origin = m_constructMan.GetOrigin();
53  auto radius = m_constructMan.GetRadius();
54  VECTOR2D rVec( radius, radius );
55 
56  tmp.SetOrigin( origin + rVec );
57  tmp.SetEnd( origin - rVec );
58  tmp.Normalize();
59  return tmp;
60 }
61 
62 
69 double getNormDeciDegFromRad( double aRadians )
70 {
71  double degs = RAD2DECIDEG( aRadians );
72 
73  // normalise to +/- 360
74  while( degs < -3600.0 )
75  degs += 3600.0;
76 
77  while( degs > 3600.0 )
78  degs -= 3600.0;
79 
80  return degs;
81 }
82 
83 
84 static const double ANGLE_EPSILON = 1e-9;
85 
86 double angleIsSpecial( double aRadians )
87 {
88  return std::fabs( std::remainder( aRadians, M_PI_4 ) ) < ANGLE_EPSILON;
89 }
90 
91 
92 static void drawLineWithHilight( KIGFX::VIEW *aView,
93  const VECTOR2I& aStart, const VECTOR2I& aEnd, bool aDim )
94 {
95  auto gal = aView->GetGAL();
96  auto rs = static_cast<KIGFX::PCB_RENDER_SETTINGS*>( aView->GetPainter()->GetSettings() );
97 
98  const auto vec = aEnd - aStart;
99  COLOR4D strokeColor = rs->GetLayerColor( LAYER_AUX_ITEMS );
100 
101  if( angleIsSpecial( vec.Angle() ) )
102  strokeColor = rs->IsBackgroundDark() ? COLOR4D( 0.5, 1.0, 0.5, 1.0 ) : COLOR4D( 0.0, 0.7, 0.0, 1.0 ) ;
103 
104  gal->SetStrokeColor( strokeColor.WithAlpha( PreviewOverlayDeemphAlpha( aDim ) ) );
105  gal->DrawLine( aStart, aEnd );
106 }
107 
108 
109 static void drawArcWithHilight( KIGFX::VIEW *aView,
110  const VECTOR2I& aOrigin, double aRad, double aStartAngle,
111  double aEndAngle )
112 {
113  auto gal = aView->GetGAL();
114  auto rs = static_cast<KIGFX::PCB_RENDER_SETTINGS*>( aView->GetPainter()->GetSettings() );
115 
116  auto color = rs->GetLayerColor( LAYER_AUX_ITEMS );
117 
118  if( angleIsSpecial( aStartAngle - aEndAngle ) )
119  color = rs->IsBackgroundDark() ? COLOR4D( 0.5, 1.0, 0.5, 1.0 ) : COLOR4D( 0.0, 0.7, 0.0, 1.0 ) ;
120 
121  gal->SetStrokeColor( color );
122  gal->SetFillColor( color.WithAlpha( 0.2 ) );
123 
124  // draw the angle reference arc
125  gal->DrawArc( aOrigin, aRad, -aStartAngle, -aEndAngle );
126 }
127 
128 
129 void ARC_ASSISTANT::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
130 {
131  auto& gal = *aView->GetGAL();
132  auto rs = static_cast<KIGFX::PCB_RENDER_SETTINGS*>( aView->GetPainter()->GetSettings() );
133 
134  // not in a position to draw anything
135  if( m_constructMan.IsReset() )
136  return;
137 
138  gal.SetLineWidth( 1.0 );
139  gal.SetIsStroke( true );
140  gal.SetIsFill( true );
141 
142  gal.ResetTextAttributes();
143 
144  // constant text size on screen
145  SetConstantGlyphHeight( gal, 12.0 );
146 
147  // angle reference arc size
148  const double innerRad = 12.0 / gal.GetWorldScale();
149 
150  const auto origin = m_constructMan.GetOrigin();
151 
152  // draw first radius line
153  bool dimFirstLine = m_constructMan.GetStep() > ARC_GEOM_MANAGER::SET_START;
154 
155  drawLineWithHilight( aView, origin, m_constructMan.GetStartRadiusEnd(), dimFirstLine );
156 
157  std::vector<wxString> cursorStrings;
158 
160  {
161  // haven't started the angle selection phase yet
162 
163  auto initAngle = m_constructMan.GetStartAngle();
164 
165  const auto angleRefLineEnd = m_constructMan.GetOrigin() + VECTOR2D( innerRad * 1.5, 0.0 );
166 
167  gal.SetStrokeColor( rs->GetLayerColor( LAYER_AUX_ITEMS ) );
168  gal.DrawLine( origin, angleRefLineEnd );
169 
170  // draw the angle reference arc
171  drawArcWithHilight( aView, origin, innerRad, initAngle, 0.0 );
172 
173  double degs = getNormDeciDegFromRad( initAngle );
174 
175  cursorStrings.push_back( DimensionLabel( "r", m_constructMan.GetRadius(), g_UserUnit ) );
176  cursorStrings.push_back( DimensionLabel( "θ", degs, DEGREES ) );
177  }
178  else
179  {
180  drawLineWithHilight( aView, origin, m_constructMan.GetEndRadiusEnd(), false );
181 
182  auto start = m_constructMan.GetStartAngle();
183  auto subtended = m_constructMan.GetSubtended();
184 
185  drawArcWithHilight( aView, origin, innerRad, start, start + subtended );
186 
187  double subtendedDeg = getNormDeciDegFromRad( subtended );
188  double endAngleDeg = getNormDeciDegFromRad( start + subtended );
189 
190  // draw dimmed extender line to cursor
191  drawLineWithHilight( aView, origin, m_constructMan.GetLastPoint(), true );
192 
193  cursorStrings.push_back( DimensionLabel( "Δθ", subtendedDeg, DEGREES ) );
194  cursorStrings.push_back( DimensionLabel( "θ", endAngleDeg, DEGREES ) );
195  }
196 
197  // FIXME: spaces choke OpenGL lp:1668455
198  for( auto& str : cursorStrings )
199  {
200  str.erase( std::remove( str.begin(), str.end(), ' ' ),
201  str.end() );
202  }
203 
204  // place the text next to cursor, on opposite side from radius
206  origin - m_constructMan.GetLastPoint(),
207  cursorStrings );
208 }
Class ARC_GEOM_MANAGER.
Implementation of conversion functions that require both schematic and board internal units...
ARC_ASSISTANT(const ARC_GEOM_MANAGER &aManager)
the 3d code uses this value
Definition: typeinfo.h:80
double RAD2DECIDEG(double rad)
Definition: trigo.h:204
const ARC_GEOM_MANAGER & m_constructMan
Definition: arc_assistant.h:69
double GetRadius() const
Get the radius of the arc (valid if step >= SET_START)
Class PCB_RENDER_SETTINGS Stores PCB specific render settings.
Definition: pcb_painter.h:62
VECTOR2I GetEndRadiusEnd() const
Get the coordinates of the arc end point
Auxillary items (guides, rule, etc)
VECTOR2< double > VECTOR2D
Definition: vector2d.h:588
Waiting to lock in origin point
GAL * GetGAL() const
Function GetGAL() Returns the GAL this view is using to draw graphical primitives.
Definition: view.h:177
VECTOR2I GetLastPoint() const
Gets the last point added (locked in or not).
BOX2< Vec > & Normalize()
Function Normalize ensures that the height ant width are positive.
Definition: box2.h:117
COLOR4D WithAlpha(double aAlpha) const
Function WithAlpha Returns a colour with the same colour, but the given alpha.
Definition: color4d.h:237
void DrawTextNextToCursor(KIGFX::VIEW *aView, const VECTOR2D &aCursorPos, const VECTOR2D &aTextQuadrant, const std::vector< wxString > &aStrings)
Draw strings next to the cursor.
static const double ANGLE_EPSILON
PAINTER * GetPainter() const
Function GetPainter() Returns the painter object used by the view for drawing VIEW_ITEMS.
Definition: view.h:196
double GetSubtended() const
Get the angle of the vector leading to the end point (valid if step >= SET_ANGLE) ...
double PreviewOverlayDeemphAlpha(bool aDeemph=true)
Default alpha of "de-emphasised" features (like previously locked-in lines.
void SetEnd(coord_type x, coord_type y)
Definition: box2.h:213
EDA_UNITS_T g_UserUnit
Global variables definitions.
Definition: common.cpp:56
virtual RENDER_SETTINGS * GetSettings()=0
Function GetSettings Returns pointer to current settings that are going to be used when drawing items...
const BOX2I ViewBBox() const override
Function ViewBBox() returns the bounding box of the item covering all its layers. ...
static void drawArcWithHilight(KIGFX::VIEW *aView, const VECTOR2I &aOrigin, double aRad, double aStartAngle, double aEndAngle)
double getNormDeciDegFromRad(double aRadians)
Get deci-degrees from radians, normalised to +/- 360.
void SetConstantGlyphHeight(KIGFX::GAL &aGal, double aHeight)
Set the GAL glyph height to a constant scaled value, so that it always looks the same on screen...
void SetOrigin(const Vec &pos)
Definition: box2.h:198
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:178
The common library.
wxString DimensionLabel(const wxString &prefix, double aVal, EDA_UNITS_T aUnits)
Get a formatted string showing a dimension to a sane precision with an optional prefix and unit suffi...
double GetStartAngle() const
Get the angle of the vector leading to the start point (valid if step >= SET_START) ...
VECTOR2I GetOrigin() const
Get the centre point of the arc (valid when state > SET_ORIGIN)
Class VIEW.
Definition: view.h:58
void ViewDraw(int aLayer, KIGFX::VIEW *aView) const overridefinal
Draw the assistance (with reference to the contstruction manager.
ARC_STEPS GetStep() const
Get the current step the mananger is on (useful when drawing something depends on the current state) ...
static void drawLineWithHilight(KIGFX::VIEW *aView, const VECTOR2I &aStart, const VECTOR2I &aEnd, bool aDim)
VECTOR2I GetStartRadiusEnd() const
Get the coordinates of the arc start
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39
double angleIsSpecial(double aRadians)