@ -1050,8 +1050,7 @@ void ImDrawList::PathArcTo(const ImVec2& center, float radius, float a_min, floa
}
}
// Cubic bezier
ImVec2 ImBezierCalc ( const ImVec2 & p1 , const ImVec2 & p2 , const ImVec2 & p3 , const ImVec2 & p4 , float t )
ImVec2 ImBezierCubicCalc ( const ImVec2 & p1 , const ImVec2 & p2 , const ImVec2 & p3 , const ImVec2 & p4 , float t )
{
float u = 1.0f - t ;
float w1 = u * u * u ;
@ -1061,9 +1060,17 @@ ImVec2 ImBezierCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const
return ImVec2 ( w1 * p1 . x + w2 * p2 . x + w3 * p3 . x + w4 * p4 . x , w1 * p1 . y + w2 * p2 . y + w3 * p3 . y + w4 * p4 . y ) ;
}
// Cubic bezier
// Closely mimics BezierClosestPointCasteljauStep() in imgui.cpp
static void PathBezierToCasteljau ( ImVector < ImVec2 > * path , float x1 , float y1 , float x2 , float y2 , float x3 , float y3 , float x4 , float y4 , float tess_tol , int level )
ImVec2 ImBezierQuadraticCalc ( const ImVec2 & p1 , const ImVec2 & p2 , const ImVec2 & p3 , float t )
{
float u = 1.0f - t ;
float w1 = u * u ;
float w2 = 2 * u * t ;
float w3 = t * t ;
return ImVec2 ( w1 * p1 . x + w2 * p2 . x + w3 * p3 . x , w1 * p1 . y + w2 * p2 . y + w3 * p3 . y ) ;
}
// Closely mimics ImBezierCubicClosestPointCasteljau() in imgui.cpp
static void PathBezierCubicCurveToCasteljau ( ImVector < ImVec2 > * path , float x1 , float y1 , float x2 , float y2 , float x3 , float y3 , float x4 , float y4 , float tess_tol , int level )
{
float dx = x4 - x1 ;
float dy = y4 - y1 ;
@ -1083,39 +1090,12 @@ static void PathBezierToCasteljau(ImVector<ImVec2>* path, float x1, float y1, fl
float x123 = ( x12 + x23 ) * 0.5f , y123 = ( y12 + y23 ) * 0.5f ;
float x234 = ( x23 + x34 ) * 0.5f , y234 = ( y23 + y34 ) * 0.5f ;
float x1234 = ( x123 + x234 ) * 0.5f , y1234 = ( y123 + y234 ) * 0.5f ;
PathBezierToCasteljau ( path , x1 , y1 , x12 , y12 , x123 , y123 , x1234 , y1234 , tess_tol , level + 1 ) ;
PathBezierToCasteljau ( path , x1234 , y1234 , x234 , y234 , x34 , y34 , x4 , y4 , tess_tol , level + 1 ) ;
}
}
// Cubic bezier
void ImDrawList : : PathBezierCurveTo ( const ImVec2 & p2 , const ImVec2 & p3 , const ImVec2 & p4 , int num_segments )
{
ImVec2 p1 = _Path . back ( ) ;
if ( num_segments = = 0 )
{
PathBezierToCasteljau ( & _Path , p1 . x , p1 . y , p2 . x , p2 . y , p3 . x , p3 . y , p4 . x , p4 . y , _Data - > CurveTessellationTol , 0 ) ; // Auto-tessellated
}
else
{
float t_step = 1.0f / ( float ) num_segments ;
for ( int i_step = 1 ; i_step < = num_segments ; i_step + + )
_Path . push_back ( ImBezierCalc ( p1 , p2 , p3 , p4 , t_step * i_step ) ) ;
PathBezierCubicCurveToCasteljau ( path , x1 , y1 , x12 , y12 , x123 , y123 , x1234 , y1234 , tess_tol , level + 1 ) ;
PathBezierCubicCurveToCasteljau ( path , x1234 , y1234 , x234 , y234 , x34 , y34 , x4 , y4 , tess_tol , level + 1 ) ;
}
}
// Quadratic bezier
ImVec2 ImQuadBezierCalc ( const ImVec2 & p1 , const ImVec2 & p2 , const ImVec2 & p3 , float t )
{
float u = 1.0f - t ;
float w1 = u * u ;
float w2 = 2 * u * t ;
float w3 = t * t ;
return ImVec2 ( w1 * p1 . x + w2 * p2 . x + w3 * p3 . x , w1 * p1 . y + w2 * p2 . y + w3 * p3 . y ) ;
}
// Quadratic bezier
static void PathQuadBezierToCasteljau ( ImVector < ImVec2 > * path , float x1 , float y1 , float x2 , float y2 , float x3 , float y3 , float tess_tol , int level )
static void PathBezierQuadraticCurveToCasteljau ( ImVector < ImVec2 > * path , float x1 , float y1 , float x2 , float y2 , float x3 , float y3 , float tess_tol , int level )
{
float dx = x3 - x1 , dy = y3 - y1 ;
float det = ( x2 - x3 ) * dy - ( y2 - y3 ) * dx ;
@ -1128,24 +1108,38 @@ static void PathQuadBezierToCasteljau(ImVector<ImVec2>* path, float x1, float y1
float x12 = ( x1 + x2 ) * 0.5f , y12 = ( y1 + y2 ) * 0.5f ;
float x23 = ( x2 + x3 ) * 0.5f , y23 = ( y2 + y3 ) * 0.5f ;
float x123 = ( x12 + x23 ) * 0.5f , y123 = ( y12 + y23 ) * 0.5f ;
PathQuadBezierToCasteljau ( path , x1 , y1 , x12 , y12 , x123 , y123 , tess_tol , level + 1 ) ;
PathQuadBezierToCasteljau ( path , x123 , y123 , x23 , y23 , x3 , y3 , tess_tol , level + 1 ) ;
PathBezierQuadraticCurveToCasteljau ( path , x1 , y1 , x12 , y12 , x123 , y123 , tess_tol , level + 1 ) ;
PathBezierQuadraticCurveToCasteljau ( path , x123 , y123 , x23 , y23 , x3 , y3 , tess_tol , level + 1 ) ;
}
}
void ImDrawList : : PathBezierCubicCurveTo ( const ImVec2 & p2 , const ImVec2 & p3 , const ImVec2 & p4 , int num_segments )
{
ImVec2 p1 = _Path . back ( ) ;
if ( num_segments = = 0 )
{
PathBezierCubicCurveToCasteljau ( & _Path , p1 . x , p1 . y , p2 . x , p2 . y , p3 . x , p3 . y , p4 . x , p4 . y , _Data - > CurveTessellationTol , 0 ) ; // Auto-tessellated
}
else
{
float t_step = 1.0f / ( float ) num_segments ;
for ( int i_step = 1 ; i_step < = num_segments ; i_step + + )
_Path . push_back ( ImBezierCubicCalc ( p1 , p2 , p3 , p4 , t_step * i_step ) ) ;
}
}
// Quadratic bezier
void ImDrawList : : PathQuadBezierCurveTo ( const ImVec2 & p2 , const ImVec2 & p3 , int num_segments )
void ImDrawList : : PathBezierQuadraticCurveTo ( const ImVec2 & p2 , const ImVec2 & p3 , int num_segments )
{
ImVec2 p1 = _Path . back ( ) ;
if ( num_segments = = 0 )
{
PathQuadBezierToCasteljau ( & _Path , p1 . x , p1 . y , p2 . x , p2 . y , p3 . x , p3 . y , _Data - > CurveTessellationTol , 0 ) ; // Auto-tessellated
Path BezierQuadraticCurve ToCasteljau( & _Path , p1 . x , p1 . y , p2 . x , p2 . y , p3 . x , p3 . y , _Data - > CurveTessellationTol , 0 ) ; // Auto-tessellated
}
else
{
float t_step = 1.0f / ( float ) num_segments ;
for ( int i_step = 1 ; i_step < = num_segments ; i_step + + )
_Path . push_back ( Im Quad BezierCalc( p1 , p2 , p3 , t_step * i_step ) ) ;
_Path . push_back ( Im BezierQuadratic Calc( p1 , p2 , p3 , t_step * i_step ) ) ;
}
}
@ -1359,24 +1353,24 @@ void ImDrawList::AddNgonFilled(const ImVec2& center, float radius, ImU32 col, in
}
// Cubic Bezier takes 4 controls points
void ImDrawList : : AddBezierCu rve ( const ImVec2 & p1 , const ImVec2 & p2 , const ImVec2 & p3 , const ImVec2 & p4 , ImU32 col , float thickness , int num_segments )
void ImDrawList : : AddBezierCu bic ( const ImVec2 & p1 , const ImVec2 & p2 , const ImVec2 & p3 , const ImVec2 & p4 , ImU32 col , float thickness , int num_segments )
{
if ( ( col & IM_COL32_A_MASK ) = = 0 )
return ;
PathLineTo ( p1 ) ;
PathBezierCu rveTo( p2 , p3 , p4 , num_segments ) ;
PathBezierCu bicCu rveTo( p2 , p3 , p4 , num_segments ) ;
PathStroke ( col , false , thickness ) ;
}
// Quadratic Bezier takes 3 controls points
void ImDrawList : : Add QuadBezierCurve ( const ImVec2 & p1 , const ImVec2 & p2 , const ImVec2 & p3 , ImU32 col , float thickness , int num_segments )
void ImDrawList : : Add BezierQuadratic ( const ImVec2 & p1 , const ImVec2 & p2 , const ImVec2 & p3 , ImU32 col , float thickness , int num_segments )
{
if ( ( col & IM_COL32_A_MASK ) = = 0 )
return ;
PathLineTo ( p1 ) ;
Path Quad BezierCurveTo( p2 , p3 , num_segments ) ;
Path BezierQuadratic CurveTo( p2 , p3 , num_segments ) ;
PathStroke ( col , false , thickness ) ;
}