Re: Uniform arc length basis curve fitting
- To: mathgroup at smc.vnet.net
- Subject: [mg67429] Re: Uniform arc length basis curve fitting
- From: christopherpurcell <christopherpurcell at mac.com>
- Date: Fri, 23 Jun 2006 04:31:59 -0400 (EDT)
- Sender: owner-wri-mathgroup at wolfram.com
This is a nice problem you are posing, with practical applications. I
have the start of a solution here - leaving lots for you to add. The
challenge comes in solving for the arc length. I do it here with
NIntegrate and FindMinimum, but it's slow, and there must be a faster
way.
(* Fit a curve composed from a set of 2 (or 3) Interpolation
functions (one for each vector component of the points) to a list of
points. The fit works for points in 2D and 3D. The curve is
parameterized by a parameter, say u, such that 0<u<1. *)
<<Graphics`Graphics`
Clear[Curve,S];
p = {{0,0},{1,2},{-1,3},{0,1},{3,0}}; (* the 2d points to fit, could
also be 3d *)
Curve[pts_List,u_]:=Module[{fit},
fit=Map[Interpolation[Transpose[{Range[0,Length[#]-1]/(Length
[#]-1),#}]]&,Transpose[pts]];
Table[fit[[i]][u],{i,1,Length[fit]}]];
DisplayTogether[ParametricPlot[Curve[p,t],{t,0,1}],Graphics[Map
[Point,pts]]];
(* Define the arc length S of the curve defined by the list of points
pts, at parameter tt. *)
S[pts_List,tt_?NumberQ]:=Module[{f,t},
f=Norm[D[Curve[pts,t],t]];
NIntegrate[f,{t,0,tt}]];
In[10]:= S[p,1.] (* the length of the curve *)
Out[10]= 10.6388
(* Now we re-parametrize the curve, using arc length s as the
parameter. Note to sweep out the entire curve, we now have to let s
vary from 0 to S[p,1.]. We see the plot looks the same, but it will
be swept out using arc length as the parameter. This is painfully
slow to evaluate. *)
ParametricPlot[Curve[p,(tt /. FindMinimum[Abs[S[p,tt]-s],{tt, 0, 1}]
[[2]])],{s,0,S[p,1.]}];
(* We can demonstrate that this is arc length by creating points
along the curve, and we see the points are nicely spaced. *)
ListPlot[Table[Curve[p,(tt /. FindMinimum[Abs[S[p,tt]-s],{tt, 0, 1}]
[[2]])],{s,0,S[p,1.],.2}]];
(* By comparison here we plot points using our initial
parametrization, and if you look closely you will see they are not
evenly spaced along the curve. *)
ListPlot[Table[Curve[p,t],{t,0,1,.02}]];
I leave it to you to implement your tangent vectors, curvatures, etc.
christopherpurcell at mac.com
On Jun 19, 2006, at 1:01 AM, Narasimham wrote:
> How to find slopes, curvature etc. of cubic splines as a function of
> arc length? With this example from Help,attempted to find piecewise
> derivatives, but it cannot be right as the given pts need not be
> spaced
> evenly on the arc. TIA.
>
> << NumericalMath`SplineFit`
> pts = {{0,0},{1,2},{-1,3},{0,1},{3,0} };
> spline = SplineFit[pts, Cubic] ;
> plspl=ParametricPlot[spline[u], {u, 0, 4}, PlotRange -> All, Compiled
> -> False];
> "derivative components"
> der[x_]:=( spline[x+10^-10]-spline[x-10^-10] ) /( 2 10^-10);
> dxu[x_]:=der[x].{1,0}; dxv[x_]:=der[x].{0,1};
> Plot[{dxu[v],dxv[v]},{v,0,4}];
> ">>> slopes >>>"
> Plot[ArcTan[dxu[v],dxv[v]] ,{v,0,4}] ;
> plder=ParametricPlot[der[v],{v,0,4}] ;
> der[2]
> Show[plspl,plder];
>