You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

283 lines
10 KiB

14 years ago
14 years ago
11 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
// Dick Hollenbeck's KiROUND R&D // This provides better project control over rounding to int from double // than wxRound() did. This scheme provides better logging in Debug builds // and it provides for compile time calculation of constants. #include <stdio.h> #include <assert.h> #include <limits.h> //-----<KiROUND KIT>------------------------------------------------------------ /** * KiROUND * rounds a floating point number to an int using * "round halfway cases away from zero". * In Debug build an assert fires if will not fit into an int. */ #if defined( DEBUG ) // DEBUG: a macro to capture line and file, then calls this inline static inline int KiRound( double v, int line, const char* filename ) { v = v < 0 ? v - 0.5 : v + 0.5; if( v > INT_MAX + 0.5 ) { printf( "%s: in file %s on line %d, val: %.16g too ' > 0 ' for int\n", __FUNCTION__, filename, line, v ); } else if( v < INT_MIN - 0.5 ) { printf( "%s: in file %s on line %d, val: %.16g too ' < 0 ' for int\n", __FUNCTION__, filename, line, v ); } return int( v ); } #define KiROUND( v ) KiRound( v, __LINE__, __FILE__ ) #else // RELEASE: a macro so compile can pre-compute constants. #define KiROUND( v ) int( (v) < 0 ? (v) - 0.5 : (v) + 0.5 ) #endif //-----</KiROUND KIT>----------------------------------------------------------- // Only a macro is compile time calculated, an inline function causes a static constructor // in a situation like this. // Therefore the Release build is best done with a MACRO not an inline function. int Computed = KiROUND( 14.3 * 8 ); int main( int argc, char** argv ) { for( double d = double(INT_MAX)-1; d < double(INT_MAX)+8; d += 2.0 ) { int i = KiROUND( d ); printf( "t: %d %.16g\n", i, d ); } return 0; }
14 years ago
  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 (C) 1992-2018 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, you may find one here:
  19. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  20. * or you may search the http://www.gnu.org website for the version 2 license,
  21. * or you may write to the Free Software Foundation, Inc.,
  22. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  23. */
  24. /**
  25. * @file class_drawsegment.h
  26. * @brief Class to handle a graphic segment.
  27. */
  28. #ifndef CLASS_DRAWSEGMENT_H_
  29. #define CLASS_DRAWSEGMENT_H_
  30. #include <class_board_item.h>
  31. #include <math_for_graphics.h>
  32. #include <trigo.h>
  33. #include <common.h>
  34. #include <geometry/shape_poly_set.h>
  35. class LINE_READER;
  36. class EDA_DRAW_FRAME;
  37. class MODULE;
  38. class MSG_PANEL_ITEM;
  39. class DRAWSEGMENT : public BOARD_ITEM
  40. {
  41. protected:
  42. int m_Width; ///< thickness of lines ...
  43. wxPoint m_Start; ///< Line start point or Circle and Arc center
  44. wxPoint m_End; ///< Line end point or circle and arc start point
  45. STROKE_T m_Shape; ///< Shape: line, Circle, Arc
  46. int m_Type; ///< Used in complex associations ( Dimensions.. )
  47. double m_Angle; ///< Used only for Arcs: Arc angle in 1/10 deg
  48. wxPoint m_BezierC1; ///< Bezier Control Point 1
  49. wxPoint m_BezierC2; ///< Bezier Control Point 2
  50. std::vector<wxPoint> m_BezierPoints;
  51. SHAPE_POLY_SET m_Poly; ///< Stores the S_POLYGON shape
  52. // Computes the bounding box for an arc
  53. void computeArcBBox( EDA_RECT& aBBox ) const;
  54. public:
  55. DRAWSEGMENT( BOARD_ITEM* aParent = NULL, KICAD_T idtype = PCB_LINE_T );
  56. // Do not create a copy constructor & operator=.
  57. // The ones generated by the compiler are adequate.
  58. ~DRAWSEGMENT();
  59. static inline bool ClassOf( const EDA_ITEM* aItem )
  60. {
  61. return aItem && PCB_LINE_T == aItem->Type();
  62. }
  63. /** Polygonal shape is not always filled.
  64. * For now it is filled on all layers but Edge_Cut layer
  65. */
  66. bool IsPolygonFilled() const { return m_Layer != Edge_Cuts; }
  67. void SetWidth( int aWidth ) { m_Width = aWidth; }
  68. int GetWidth() const { return m_Width; }
  69. /**
  70. * Function SetAngle
  71. * sets the angle for arcs, and normalizes it within the range 0 - 360 degrees.
  72. * @param aAngle is tenths of degrees, but will soon be degrees.
  73. */
  74. void SetAngle( double aAngle ); // encapsulates the transition to degrees
  75. double GetAngle() const { return m_Angle; }
  76. void SetType( int aType ) { m_Type = aType; }
  77. int GetType() const { return m_Type; }
  78. void SetShape( STROKE_T aShape ) { m_Shape = aShape; }
  79. STROKE_T GetShape() const { return m_Shape; }
  80. void SetBezControl1( const wxPoint& aPoint ) { m_BezierC1 = aPoint; }
  81. const wxPoint& GetBezControl1() const { return m_BezierC1; }
  82. void SetBezControl2( const wxPoint& aPoint ) { m_BezierC2 = aPoint; }
  83. const wxPoint& GetBezControl2() const { return m_BezierC2; }
  84. void SetPosition( const wxPoint& aPos ) override;
  85. const wxPoint GetPosition() const override;
  86. /**
  87. * Function GetStart
  88. * returns the starting point of the graphic
  89. */
  90. const wxPoint& GetStart() const { return m_Start; }
  91. void SetStart( const wxPoint& aStart ) { m_Start = aStart; }
  92. void SetStartY( int y ) { m_Start.y = y; }
  93. void SetStartX( int x ) { m_Start.x = x; }
  94. /**
  95. * Function GetEnd
  96. * returns the ending point of the graphic
  97. */
  98. const wxPoint& GetEnd() const { return m_End; }
  99. void SetEnd( const wxPoint& aEnd ) { m_End = aEnd; }
  100. void SetEndY( int y ) { m_End.y = y; }
  101. void SetEndX( int x ) { m_End.x = x; }
  102. // Some attributes are read only, since they are "calculated" from
  103. // m_Start, m_End, and m_Angle.
  104. // No Set...() function for these attributes.
  105. const wxPoint GetCenter() const override;
  106. const wxPoint& GetArcStart() const { return m_End; }
  107. const wxPoint GetArcEnd() const;
  108. const wxPoint GetArcMid() const;
  109. /**
  110. * function GetArcAngleStart()
  111. * @return the angle of the starting point of this arc, between 0 and 3600 in 0.1 deg
  112. */
  113. double GetArcAngleStart() const;
  114. /**
  115. * Function GetRadius
  116. * returns the radius of this item
  117. * Has meaning only for arc and circle
  118. */
  119. int GetRadius() const
  120. {
  121. double radius = GetLineLength( m_Start, m_End );
  122. return KiROUND( radius );
  123. }
  124. /**
  125. * Initialize the start arc point. can be used for circles
  126. * to initialize one point of the cicumference
  127. */
  128. void SetArcStart( const wxPoint& aArcStartPoint )
  129. { m_End = aArcStartPoint; }
  130. /** For arcs and circles:
  131. */
  132. void SetCenter( const wxPoint& aCenterPoint ) { m_Start = aCenterPoint; }
  133. /**
  134. * Function GetParentModule
  135. * returns a pointer to the parent module, or NULL if DRAWSEGMENT does not
  136. * belong to a module.
  137. * @return MODULE* - pointer to the parent module or NULL.
  138. */
  139. MODULE* GetParentModule() const;
  140. // Accessors:
  141. const std::vector<wxPoint>& GetBezierPoints() const { return m_BezierPoints; }
  142. /** Build and return the list of corners in a std::vector<wxPoint>
  143. * It must be used only to convert the SHAPE_POLY_SET internal corner buffer
  144. * to a list of wxPoints, and nothing else, because it duplicates the buffer,
  145. * that is inefficient to know for instance the corner count
  146. */
  147. const std::vector<wxPoint> BuildPolyPointsList() const;
  148. /** @return the number of corners of the polygonal shape
  149. */
  150. int GetPointCount() const;
  151. // Accessors to the polygonal shape
  152. SHAPE_POLY_SET& GetPolyShape() { return m_Poly; }
  153. const SHAPE_POLY_SET& GetPolyShape() const { return m_Poly; }
  154. /**
  155. * @return true if the polygonal shape is valid (has more than 2 points)
  156. */
  157. bool IsPolyShapeValid() const;
  158. void SetPolyShape( const SHAPE_POLY_SET& aShape ) { m_Poly = aShape; }
  159. void SetBezierPoints( const std::vector<wxPoint>& aPoints )
  160. {
  161. m_BezierPoints = aPoints;
  162. }
  163. /** Rebuild the m_BezierPoints vertex list that approximate the Bezier curve
  164. * by a list of segments
  165. * Has meaning only for S_CURVE DRAW_SEGMENT shape
  166. * @param aMinSegLen is the min length of segments approximating the shape.
  167. * the last segment can be shorter
  168. * This param avoid having too many very short segment in list.
  169. * a good value is m_Width/2 to m_Width
  170. */
  171. void RebuildBezierToSegmentsPointsList( int aMinSegLen );
  172. void SetPolyPoints( const std::vector<wxPoint>& aPoints );
  173. void Draw( EDA_DRAW_PANEL* panel, wxDC* DC,
  174. GR_DRAWMODE aDrawMode, const wxPoint& aOffset = ZeroOffset ) override;
  175. virtual void GetMsgPanelInfo( EDA_UNITS_T aUnits,
  176. std::vector< MSG_PANEL_ITEM >& aList ) override;
  177. virtual const EDA_RECT GetBoundingBox() const override;
  178. virtual bool HitTest( const wxPoint& aPosition ) const override;
  179. bool HitTest( const EDA_RECT& aRect, bool aContained = true,
  180. int aAccuracy = 0 ) const override;
  181. wxString GetClass() const override
  182. {
  183. return wxT( "DRAWSEGMENT" );
  184. }
  185. /**
  186. * Function GetLength
  187. * returns the length of the track using the hypotenuse calculation.
  188. * @return double - the length of the track
  189. */
  190. double GetLength() const
  191. {
  192. return GetLineLength( GetStart(), GetEnd() );
  193. }
  194. virtual void Move( const wxPoint& aMoveVector ) override;
  195. virtual void Rotate( const wxPoint& aRotCentre, double aAngle ) override;
  196. virtual void Flip( const wxPoint& aCentre ) override;
  197. /**
  198. * Function TransformShapeWithClearanceToPolygon
  199. * Convert the draw segment to a closed polygon
  200. * Used in filling zones calculations
  201. * Circles and arcs are approximated by segments
  202. * @param aCornerBuffer = a buffer to store the polygon
  203. * @param aClearanceValue = the clearance around the pad
  204. * @param aCircleToSegmentsCount = the number of segments to approximate a circle
  205. * @param aCorrectionFactor = the correction to apply to circles radius to keep
  206. * clearance when the circle is approximated by segment bigger or equal
  207. * to the real clearance value (usually near from 1.0)
  208. * @param ignoreLineWidth = used for edge cut items where the line width is only
  209. * for visualization
  210. */
  211. void TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
  212. int aClearanceValue,
  213. int aCircleToSegmentsCount,
  214. double aCorrectionFactor,
  215. bool ignoreLineWidth = false ) const override;
  216. virtual wxString GetSelectMenuText( EDA_UNITS_T aUnits ) const override;
  217. virtual BITMAP_DEF GetMenuImage() const override;
  218. virtual EDA_ITEM* Clone() const override;
  219. virtual const BOX2I ViewBBox() const override;
  220. virtual void SwapData( BOARD_ITEM* aImage ) override;
  221. #if defined(DEBUG)
  222. void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); }
  223. #endif
  224. };
  225. #endif // CLASS_DRAWSEGMENT_H_