From 808e37b1b393e81124c6177125c0c06806d0e976 Mon Sep 17 00:00:00 2001 From: sheaf Date: Mon, 14 Sep 2020 06:28:35 +0200 Subject: [PATCH] fix issue with incorrect subdivision in fit * was using `Max ( Arg t sq_dist )` instead of `Max ( Arg sq_dist t )` --- app/Main.hs | 4 ++-- src/lib/Math/Bezier/Cubic/Fit.hs | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/Main.hs b/app/Main.hs index 8d3d39f..6b7daf4 100644 --- a/app/Main.hs +++ b/app/Main.hs @@ -215,8 +215,8 @@ main = do fitParametersTVar <- STM.newTVarIO @FitParameters ( FitParameters { maxSubdiv = 3 - , nbSegments = 30 - , dist_tol = 5e-4 + , nbSegments = 13 + , dist_tol = 5e-3 , t_tol = 1e-4 , maxIters = 100 } diff --git a/src/lib/Math/Bezier/Cubic/Fit.hs b/src/lib/Math/Bezier/Cubic/Fit.hs index 03a77d7..7316e62 100644 --- a/src/lib/Math/Bezier/Cubic/Fit.hs +++ b/src/lib/Math/Bezier/Cubic/Fit.hs @@ -134,7 +134,7 @@ fitSpline ( FitParameters {..} ) = go 0 qs = [ fst $ curve ( dt * fromIntegral j ) | j <- [ 1 .. nbSegments - 1 ] ] in case fitPiece dist_tol t_tol maxIters p tp qs r tr of - ( bez, Max ( Arg t_split sq_d ) ) + ( bez, Max ( Arg sq_d t_split ) ) | subdiv >= maxSubdiv || sq_d <= dist_tol ^ ( 2 :: Int ) -> ( Seq.singleton bez, ( FitTangent p tp :<| Seq.fromList ( map FitPoint qs ) ) :|> FitTangent r tr ) @@ -150,7 +150,7 @@ fitSpline ( FitParameters {..} ) = go 0 -- * ends at \( r \) with tangent \( \textrm{t}_r \), -- * best fits the intermediate sequence of points \( \left ( q_i \right )_{i=1}^n \). -- --- This function also returns \( \textrm{ArgMax}\ t_\textrm{max}\ d^2_\textrm{max}: \) +-- This function also returns \( \textrm{ArgMax}\ d^2_\textrm{max}\ t_\textrm{max}: \) -- the parameter and squared distance of the worst-fitting point. -- It is guaranteed that all points to fit lie within the tubular neighbourhood -- of radius \( d_\textrm{max} \) of the fitted curve. @@ -254,11 +254,11 @@ fitPiece dist_tol t_tol maxIters p tp qs r tr = let sq_dist :: Double sq_dist = quadrance @( Vector2D Double ) q ( Cubic.bezier @( Vector2D Double ) bez ti' ) - modify' ( second ( <> Max ( Arg ti' sq_dist ) ) ) + modify' ( second ( <> Max ( Arg sq_dist ti' ) ) ) lift ( Unboxed.MVector.unsafeWrite ts i ti' ) case argmax_sq_dist of - Max ( Arg _ max_sq_dist ) + Max ( Arg max_sq_dist _ ) | count < maxIters && ( dts_changed || max_sq_dist > dist_tol ^ ( 2 :: Int ) ) -> loop ts ( count + 1 )