Add bezier curve functions to prepare teardrop calculations

This commit is contained in:
jean-pierre charras 2021-12-31 15:54:35 +01:00
parent 640cc60bf4
commit 68f6db7213
2 changed files with 35 additions and 21 deletions

View File

@ -36,6 +36,9 @@
class BEZIER_POLY class BEZIER_POLY
{ {
public: public:
BEZIER_POLY( const VECTOR2I& aStart, const VECTOR2I& aCtrl1,
const VECTOR2I& aCtrl2, const VECTOR2I& aEnd );
BEZIER_POLY( const std::vector<wxPoint>& aControlPoints ); BEZIER_POLY( const std::vector<wxPoint>& aControlPoints );
BEZIER_POLY( const std::vector<VECTOR2I>& aControlPoints ); BEZIER_POLY( const std::vector<VECTOR2I>& aControlPoints );
@ -53,10 +56,11 @@ public:
* @param aMinSegLen is the min dist between 2 successive points. * @param aMinSegLen is the min dist between 2 successive points.
* It can be used to reduce the number of points. * It can be used to reduce the number of points.
* (the last point is always generated) * (the last point is always generated)
* aMaxSegCount is the max number of segments created
*/ */
void GetPoly( std::vector<wxPoint>& aOutput, int aMinSegLen = 0 ); void GetPoly( std::vector<wxPoint>& aOutput, int aMinSegLen = 0, int aMaxSegCount = 32 );
void GetPoly( std::vector<VECTOR2I>& aOutput, int aMinSegLen = 0 ); void GetPoly( std::vector<VECTOR2I>& aOutput, int aMinSegLen = 0, int aMaxSegCount = 32 );
void GetPoly( std::vector<VECTOR2D>& aOutput, double aMinSegLen = 0.0 ); void GetPoly( std::vector<VECTOR2D>& aOutput, double aMinSegLen = 0.0, int aMaxSegCount = 32 );
private: private:
double m_minSegLen; double m_minSegLen;

View File

@ -1,7 +1,7 @@
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2014-2019 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2014-2021 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -39,6 +39,28 @@ BEZIER_POLY::BEZIER_POLY( const std::vector<wxPoint>& aControlPoints )
m_minSegLen = 0.0; m_minSegLen = 0.0;
} }
BEZIER_POLY::BEZIER_POLY( const VECTOR2I& aStart, const VECTOR2I& aCtrl1,
const VECTOR2I& aCtrl2, const VECTOR2I& aEnd )
{
m_ctrlPts.emplace_back( VECTOR2D( aStart ) );
m_ctrlPts.emplace_back( VECTOR2D( aCtrl1 ) );
m_ctrlPts.emplace_back( VECTOR2D( aCtrl2 ) );
m_ctrlPts.emplace_back( VECTOR2D( aEnd ) );
m_minSegLen = 0.0;
}
void BEZIER_POLY::GetPoly( std::vector<wxPoint>& aOutput, int aMinSegLen, int aMaxSegCount )
{
aOutput.clear();
std::vector<VECTOR2D> buffer;
GetPoly( buffer, double( aMinSegLen ), aMaxSegCount );
for( unsigned ii = 0; ii < buffer.size(); ++ii )
aOutput.emplace_back( wxPoint( int( buffer[ii].x ), int( buffer[ii].y ) ) );
}
BEZIER_POLY::BEZIER_POLY( const std::vector<VECTOR2I>& aControlPoints ) BEZIER_POLY::BEZIER_POLY( const std::vector<VECTOR2I>& aControlPoints )
{ {
@ -49,36 +71,24 @@ BEZIER_POLY::BEZIER_POLY( const std::vector<VECTOR2I>& aControlPoints )
} }
void BEZIER_POLY::GetPoly( std::vector<wxPoint>& aOutput, int aMinSegLen ) void BEZIER_POLY::GetPoly( std::vector<VECTOR2I>& aOutput, int aMinSegLen, int aMaxSegCount )
{
aOutput.clear();
std::vector<VECTOR2D> buffer;
GetPoly( buffer, double( aMinSegLen ) );
for( unsigned ii = 0; ii < buffer.size(); ++ii )
aOutput.emplace_back( wxPoint( int( buffer[ii].x ), int( buffer[ii].y ) ) );
}
void BEZIER_POLY::GetPoly( std::vector<VECTOR2I>& aOutput, int aMinSegLen )
{ {
aOutput.clear(); aOutput.clear();
std::vector<VECTOR2I> buffer; std::vector<VECTOR2I> buffer;
GetPoly( buffer, double( aMinSegLen ) ); GetPoly( buffer, double( aMinSegLen ), aMaxSegCount );
for( unsigned ii = 0; ii < buffer.size(); ++ii ) for( unsigned ii = 0; ii < buffer.size(); ++ii )
aOutput.emplace_back( VECTOR2I( int( buffer[ii].x ), int( buffer[ii].y ) ) ); aOutput.emplace_back( VECTOR2I( int( buffer[ii].x ), int( buffer[ii].y ) ) );
} }
void BEZIER_POLY::GetPoly( std::vector<VECTOR2D>& aOutput, double aMinSegLen ) void BEZIER_POLY::GetPoly( std::vector<VECTOR2D>& aOutput, double aMinSegLen, int aMaxSegCount )
{ {
wxASSERT( m_ctrlPts.size() == 4 ); wxASSERT( m_ctrlPts.size() == 4 );
// FIXME Brute force method, use a better (recursive?) algorithm // FIXME Brute force method, use a better (recursive?) algorithm
// with a max error value. // with a max error value.
// to optimize the number of segments // to optimize the number of segments
#define CURVE_POINTS 32 double dt = 1.0 / aMaxSegCount;
double dt = 1.0 / CURVE_POINTS;
aOutput.clear(); aOutput.clear();
aOutput.push_back( m_ctrlPts[0] ); aOutput.push_back( m_ctrlPts[0] );
@ -88,7 +98,7 @@ void BEZIER_POLY::GetPoly( std::vector<VECTOR2D>& aOutput, double aMinSegLen )
if( !degenerated ) if( !degenerated )
{ {
for( int ii = 1; ii < CURVE_POINTS; ii++ ) for( int ii = 1; ii < aMaxSegCount; ii++ )
{ {
double t = dt * ii; double t = dt * ii;
double omt = 1.0 - t; double omt = 1.0 - t;