@ -1109,6 +1109,72 @@ void ImGuiIO::ClearInputCharacters()
// [SECTION] MISC HELPERS/UTILITIES (Geometry, String, Format, Hash, File functions)
// [SECTION] MISC HELPERS/UTILITIES (Geometry, String, Format, Hash, File functions)
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
ImVec2 ImBezierClosestPoint ( const ImVec2 & p , const ImVec2 & p1 , const ImVec2 & p2 , const ImVec2 & p3 , const ImVec2 & p4 , int num_segments )
{
IM_ASSERT ( num_segments > 0 ) ;
ImVec2 p_last = p1 ;
ImVec2 p_closest ;
float p_closest_dist2 = FLT_MAX ;
float t_step = 1.0f / ( float ) num_segments ;
for ( int i_step = 1 ; i_step < = num_segments ; i_step + + )
{
ImVec2 p_current = ImBezierCalc ( p1 , p2 , p3 , p4 , t_step * i_step ) ;
ImVec2 p_line = ImLineClosestPoint ( p_last , p_current , p ) ;
float dist2 = ImLengthSqr ( p - p_line ) ;
if ( dist2 < p_closest_dist2 )
{
p_closest = p_line ;
p_closest_dist2 = dist2 ;
}
p_last = p_current ;
}
return p_closest ;
}
// Closely mimics PathBezierToCasteljau() in imgui_draw.cpp
static void ClosestPointBezierCasteljau ( const ImVec2 & p , ImVec2 & p_closest , ImVec2 & p_last , float & p_closest_dist2 , 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 ;
float d2 = ( ( x2 - x4 ) * dy - ( y2 - y4 ) * dx ) ;
float d3 = ( ( x3 - x4 ) * dy - ( y3 - y4 ) * dx ) ;
d2 = ( d2 > = 0 ) ? d2 : - d2 ;
d3 = ( d3 > = 0 ) ? d3 : - d3 ;
if ( ( d2 + d3 ) * ( d2 + d3 ) < tess_tol * ( dx * dx + dy * dy ) )
{
ImVec2 p_current ( x4 , y4 ) ;
ImVec2 p_line = ImLineClosestPoint ( p_last , p_current , p ) ;
float dist2 = ImLengthSqr ( p - p_line ) ;
if ( dist2 < p_closest_dist2 )
{
p_closest = p_line ;
p_closest_dist2 = dist2 ;
}
p_last = p_current ;
}
else if ( level < 10 )
{
float x12 = ( x1 + x2 ) * 0.5f , y12 = ( y1 + y2 ) * 0.5f ;
float x23 = ( x2 + x3 ) * 0.5f , y23 = ( y2 + y3 ) * 0.5f ;
float x34 = ( x3 + x4 ) * 0.5f , y34 = ( y3 + y4 ) * 0.5f ;
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 ;
ClosestPointBezierCasteljau ( p , p_closest , p_last , p_closest_dist2 , x1 , y1 , x12 , y12 , x123 , y123 , x1234 , y1234 , tess_tol , level + 1 ) ;
ClosestPointBezierCasteljau ( p , p_closest , p_last , p_closest_dist2 , x1234 , y1234 , x234 , y234 , x34 , y34 , x4 , y4 , tess_tol , level + 1 ) ;
}
}
ImVec2 ImBezierClosestPointCasteljau ( const ImVec2 & p , const ImVec2 & p1 , const ImVec2 & p2 , const ImVec2 & p3 , const ImVec2 & p4 , float tess_tol )
{
IM_ASSERT ( tess_tol > 0.0f ) ;
ImVec2 p_last = p1 ;
ImVec2 p_closest ;
float p_closest_dist2 = FLT_MAX ;
ClosestPointBezierCasteljau ( p , p_closest , p_last , p_closest_dist2 , p1 . x , p1 . y , p2 . x , p2 . y , p3 . x , p3 . y , p4 . x , p4 . y , tess_tol , 0 ) ;
return p_closest ;
}
ImVec2 ImLineClosestPoint ( const ImVec2 & a , const ImVec2 & b , const ImVec2 & p )
ImVec2 ImLineClosestPoint ( const ImVec2 & a , const ImVec2 & b , const ImVec2 & p )
{
{
ImVec2 ap = p - a ;
ImVec2 ap = p - a ;