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  m_units( aUnits )
40 {
41 }
42 
43 
45 {
46  BOX2I tmp;
47 
48  // no bounding box when no graphic shown
49  if( m_constructMan.IsReset() )
50  return tmp;
51 
52  // just enclose the whle circular area
53  auto origin = m_constructMan.GetOrigin();
54  auto radius = m_constructMan.GetRadius();
55  VECTOR2D rVec( radius, radius );
56 
57  tmp.SetOrigin( origin + rVec );
58  tmp.SetEnd( origin - rVec );
59  tmp.Normalize();
60  return tmp;
61 }
62 
63 
70 double getNormDeciDegFromRad( double aRadians )
71 {
72  double degs = RAD2DECIDEG( aRadians );
73 
74  // normalise to +/- 360
75  while( degs < -3600.0 )
76  degs += 3600.0;
77 
78  while( degs > 3600.0 )
79  degs -= 3600.0;
80 
81  return degs;
82 }
83 
84 
85 static const double ANGLE_EPSILON = 1e-9;
86 
87 bool angleIsSpecial( double aRadians )
88 {
89  return std::fabs( std::remainder( aRadians, M_PI_4 ) ) < ANGLE_EPSILON;
90 }
91 
92 
93 static void drawLineWithHilight( KIGFX::VIEW *aView,
94  const VECTOR2I& aStart, const VECTOR2I& aEnd, bool aDim )
95 {
96  auto gal = aView->GetGAL();
97  auto rs = static_cast<KIGFX::PCB_RENDER_SETTINGS*>( aView->GetPainter()->GetSettings() );
98 
99  const auto vec = aEnd - aStart;
100  COLOR4D strokeColor = rs->GetLayerColor( LAYER_AUX_ITEMS );
101 
102  if( angleIsSpecial( vec.Angle() ) )
103  strokeColor = rs->IsBackgroundDark() ? COLOR4D( 0.5, 1.0, 0.5, 1.0 ) : COLOR4D( 0.0, 0.7, 0.0, 1.0 ) ;
104 
105  gal->SetStrokeColor( strokeColor.WithAlpha( PreviewOverlayDeemphAlpha( aDim ) ) );
106  gal->DrawLine( aStart, aEnd );
107 }
108 
109 
110 static void drawArcWithHilight( KIGFX::VIEW *aView,
111  const VECTOR2I& aOrigin, double aRad, double aStartAngle,
112  double aEndAngle )
113 {
114  auto gal = aView->GetGAL();
115  auto rs = static_cast<KIGFX::PCB_RENDER_SETTINGS*>( aView->GetPainter()->GetSettings() );
116 
117  auto color = rs->GetLayerColor( LAYER_AUX_ITEMS );
118 
119  if( angleIsSpecial( aStartAngle - aEndAngle ) )
120  color = rs->IsBackgroundDark() ? COLOR4D( 0.5, 1.0, 0.5, 1.0 ) : COLOR4D( 0.0, 0.7, 0.0, 1.0 ) ;
121 
122  gal->SetStrokeColor( color );
123  gal->SetFillColor( color.WithAlpha( 0.2 ) );
124 
125  // draw the angle reference arc
126  gal->DrawArc( aOrigin, aRad, -aStartAngle, -aEndAngle );
127 }
128 
129 
130 void ARC_ASSISTANT::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
131 {
132  auto& gal = *aView->GetGAL();
133  auto rs = static_cast<KIGFX::PCB_RENDER_SETTINGS*>( aView->GetPainter()->GetSettings() );
134 
135  // not in a position to draw anything
136  if( m_constructMan.IsReset() )
137  return;
138 
139  gal.SetLineWidth( 1.0 );
140  gal.SetIsStroke( true );
141  gal.SetIsFill( true );
142 
143  gal.ResetTextAttributes();
144 
145  // constant text size on screen
146  SetConstantGlyphHeight( gal, 12.0 );
147 
148  // angle reference arc size
149  const double innerRad = 12.0 / gal.GetWorldScale();
150 
151  const auto origin = m_constructMan.GetOrigin();
152 
153  // draw first radius line
154  bool dimFirstLine = m_constructMan.GetStep() > ARC_GEOM_MANAGER::SET_START;
155 
156  drawLineWithHilight( aView, origin, m_constructMan.GetStartRadiusEnd(), dimFirstLine );
157 
158  std::vector<wxString> cursorStrings;
159 
161  {
162  // haven't started the angle selection phase yet
163 
164  auto initAngle = m_constructMan.GetStartAngle();
165 
166  const auto angleRefLineEnd = m_constructMan.GetOrigin() + VECTOR2D( innerRad * 1.5, 0.0 );
167 
168  gal.SetStrokeColor( rs->GetLayerColor( LAYER_AUX_ITEMS ) );
169  gal.DrawLine( origin, angleRefLineEnd );
170 
171  // draw the angle reference arc
172  drawArcWithHilight( aView, origin, innerRad, initAngle, 0.0 );
173 
174  double degs = getNormDeciDegFromRad( initAngle );
175 
176  cursorStrings.push_back( DimensionLabel( "r", m_constructMan.GetRadius(), m_units ) );
177  cursorStrings.push_back( DimensionLabel( wxString::FromUTF8( "θ" ), degs, DEGREES ) );
178  }
179  else
180  {
181  drawLineWithHilight( aView, origin, m_constructMan.GetEndRadiusEnd(), false );
182 
183  auto start = m_constructMan.GetStartAngle();
184  auto subtended = m_constructMan.GetSubtended();
185 
186  drawArcWithHilight( aView, origin, innerRad, start, start + subtended );
187 
188  double subtendedDeg = getNormDeciDegFromRad( subtended );
189  double endAngleDeg = getNormDeciDegFromRad( start + subtended );
190 
191  // draw dimmed extender line to cursor
192  drawLineWithHilight( aView, origin, m_constructMan.GetLastPoint(), true );
193 
194  cursorStrings.push_back( DimensionLabel( wxString::FromUTF8( "Δθ" ), subtendedDeg, DEGREES ) );
195  cursorStrings.push_back( DimensionLabel( wxString::FromUTF8( "θ" ), endAngleDeg, DEGREES ) );
196  }
197 
198  // FIXME: spaces choke OpenGL lp:1668455
199  for( auto& str : cursorStrings )
200  {
201  str.erase( std::remove( str.begin(), str.end(), ' ' ), str.end() );
202  }
203 
204  // place the text next to cursor, on opposite side from radius
206  origin - m_constructMan.GetLastPoint(),
207  cursorStrings );
208 }
void ViewDraw(int aLayer, KIGFX::VIEW *aView) const override final
Draw the assistance (with reference to the contstruction manager.
VECTOR2I GetEndRadiusEnd() const
Get the coordinates of the arc end point
Implementation of conversion functions that require both schematic and board internal units.
the 3d code uses this value
Definition: typeinfo.h:80
int color
Definition: DXF_plotter.cpp:62
double RAD2DECIDEG(double rad)
Definition: trigo.h:204
COLOR4D WithAlpha(double aAlpha) const
Function WithAlpha Returns a colour with the same colour, but the given alpha.
Definition: color4d.h:255
GAL * GetGAL() const
Function GetGAL() Returns the GAL this view is using to draw graphical primitives.
Definition: view.h:180
VECTOR2I GetStartRadiusEnd() const
Get the coordinates of the arc start
const ARC_GEOM_MANAGER & m_constructMan
Definition: arc_assistant.h:68
bool angleIsSpecial(double aRadians)
const string & str
Definition: json11.cpp:596
double GetStartAngle() const
Get the angle of the vector leading to the start point (valid if step >= SET_START)
double GetSubtended() const
Get the angle of the vector leading to the end point (valid if step >= SET_ANGLE)
PAINTER * GetPainter() const
Function GetPainter() Returns the painter object used by the view for drawing VIEW_ITEMS.
Definition: view.h:199
virtual void SetLineWidth(float aLineWidth)
Set the line width.
Auxiliary items (guides, rule, etc)
VECTOR2< double > VECTOR2D
Definition: vector2d.h:586
Waiting to lock in origin point
VECTOR2I GetOrigin() const
Get the centre point of the arc (valid when state > SET_ORIGIN)
BOX2< Vec > & Normalize()
Function Normalize ensures that the height ant width are positive.
Definition: box2.h:127
double GetRadius() const
Get the radius of the arc (valid if step >= SET_START)
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
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:223
VECTOR2I GetLastPoint() const
Gets the last point added (locked in or not).
virtual RENDER_SETTINGS * GetSettings()=0
Function GetSettings Returns pointer to current settings that are going to be used when drawing items...
ARC_ASSISTANT(const ARC_GEOM_MANAGER &aManager, EDA_UNITS_T aUnits)
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.
ARC_STEPS GetStep() const
Get the current step the mananger is on (useful when drawing something depends on the current state)
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:208
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:154
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...
Class VIEW.
Definition: view.h:61
static void drawLineWithHilight(KIGFX::VIEW *aView, const VECTOR2I &aStart, const VECTOR2I &aEnd, bool aDim)
EDA_UNITS_T
Definition: common.h:160
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39