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.

110 lines
3.7 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2009-2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
  5. * Copyright (C) 1992-2017 KiCad Developers, see CHANGELOG.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. #ifndef BEZIER_CURVES_H
  25. #define BEZIER_CURVES_H
  26. #include <vector>
  27. #include <wx/gdicmn.h>
  28. /**
  29. * Bezier curves to polygon converter.
  30. * Only quadratic and cubic Bezier curves are handled
  31. */
  32. class BEZIER_POLY
  33. {
  34. public:
  35. /** cubic Bezier curve */
  36. BEZIER_POLY( int x1, int y1, int x2, int y2, int x3, int y3 )
  37. {
  38. m_ctrlPts.emplace_back( x1, y1 );
  39. m_ctrlPts.emplace_back( x2, y2 );
  40. m_ctrlPts.emplace_back( x3, y3 );
  41. m_output = nullptr;
  42. m_minSegLen = 0;
  43. }
  44. /** Quadratic and cubic Bezier curve */
  45. BEZIER_POLY( int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4 )
  46. {
  47. m_ctrlPts.emplace_back( x1, y1 );
  48. m_ctrlPts.emplace_back( x2, y2 );
  49. m_ctrlPts.emplace_back( x3, y3 );
  50. m_ctrlPts.emplace_back( x4, y4 );
  51. m_output = nullptr;
  52. m_minSegLen = 0;
  53. }
  54. BEZIER_POLY( const std::vector<wxPoint>& aControlPoints )
  55. : m_ctrlPts( aControlPoints )
  56. {
  57. m_output = nullptr;
  58. m_minSegLen = 0;
  59. }
  60. /**
  61. * Converts Bezier curve to a polygon.
  62. * @param aOutput will be used as an output vector storing polygon points.
  63. * @param aMinSegLen is the min dist between 2 successve points.
  64. * It can be used to reduce the number of points.
  65. * (the last point is always generated)
  66. */
  67. void GetPoly( std::vector<wxPoint>& aOutput, int aMinSegLen = 0 );
  68. private:
  69. int m_minSegLen;
  70. ///> Control points
  71. std::vector<wxPoint> m_ctrlPts;
  72. ///> Pointer to the output vector
  73. std::vector<wxPoint>* m_output;
  74. void addSegment( const wxPoint& aSegment )
  75. {
  76. int seglen = std::abs( m_output->back().x - aSegment.x )
  77. + std::abs( m_output->back().y - aSegment.y );
  78. // m_minSegLen is always > 0, so never store a 0 len segment
  79. if( seglen >= m_minSegLen )
  80. m_output->push_back( aSegment );
  81. }
  82. void recursiveBezier( int x1, int y1, int x2, int y2, int x3, int y3, unsigned int level );
  83. void recursiveBezier( int x1, int y1, int x2, int y2,
  84. int x3, int y3, int x4, int y4, unsigned int level );
  85. // Conversion parameters
  86. constexpr static double angle_tolerance = 0.0;
  87. constexpr static double cusp_limit = 0.0;
  88. constexpr static unsigned int recursion_limit = 12;
  89. constexpr static double approximation_scale = 0.5; // 1
  90. constexpr static double distance_tolerance_square = ( 0.5 / approximation_scale ) * ( 0.5 / approximation_scale );
  91. constexpr static double curve_collinearity_epsilon = 1e-30;
  92. constexpr static double curve_angle_tolerance_epsilon = 0.0001;
  93. };
  94. #endif // BEZIER_CURVES_H