# How to get a uniformly distributed list of points from a B-spline function

I created a spline function from a list of points and made a plot as follows:

  list2 = {{3.93453, -0.623168}, {3.79708, -0.187231}, {3.72835,
0.0307369}, {3.65963, 0.248705}, {3.5909, 0.466673}, {3.52218,
0.684642}, {3.44186, 1.05816}, {3.36155, 1.29764}, {3.28124,
1.5219}, {3.20093, 1.73094}, {3.12061, 1.92474}, {3.0403,
2.10331}, {2.95999, 2.26666}, {2.87968, 2.41477}, {2.79937,
2.54766}, {2.71905, 2.66532}, {2.63874, 2.76774}, {2.55843,
2.85494}, {2.41254, 2.97924}, {1.98589, 3.2791}, {1.52249,
3.51828}, {1.27967, 3.61368}, {1.03092, 3.69235}, {0.777399,
3.75392}, {0.520275, 3.7981}, {0.260741, 3.82469}, {0., 3.83357}}

g = BSplineFunction[list2,
SplineWeights -> {50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50}]

ListPlot[Table[g[t], {t, 0, 1, 1/100}]]


I need my plot to have more evenly placed points. When I take the plot out of this sample table to a larger scale plot, there are gaping holes that are too extreme for my needs. Is there any way to adjust the density of my spline function without just adding more points? Adding more points is not proving to be an effective solution.

-
So you want an arc-length reparametrization ... –  belisarius Jul 14 at 22:00
some of this may be useful mathematica.stackexchange.com/questions/50581/… –  george2079 Jul 15 at 2:59
Strongly related: mathematica.stackexchange.com/q/39394 The answers there may be applied to plotting g[t]. –  Michael E2 Jul 15 at 3:18
@Kaisey You have asked 13 questions and accepted none of the answers. (Are they all wrong?) You should see a check mark you can click below the vote count. Accepting the best correct answer is the way such answers are marked on the site and an expected way to say "thank you" to those you tried help you. –  Michael E2 Jul 30 at 16:37
@MichaelE2 sorry was not aware of said etiquette. –  Kaisey Jul 31 at 20:50

Here is an arc-length reparametrization in terms of a function tfn that maps the arclength along the B-spline curve to the parameter t. It's important to use AspectRatio -> Automatic to get the spacing even.

There are two truncation-error issues with parametrizing the full length of the curve. One is that the stopping point is found by stepping past the end of the curve. BSplineFunction does not extrapolate, so I extended its derivative in dg.The other is actually getting to the end of the curve. I dealt with it by over estimating the arclength and using WhenEvent to stop the integration. The NIntegrate used to get the total arclength is fast, so it is not very wasteful in this case. If NIntegate were slower, one could overestimate the arclength in other ways, e.g. from list2.

The domain of tfn runs from 0 to the arclength. To get even spacing, I rescaled an even division of the unit interval to the domain of tfn.

ClearAll[s, t];
(* g defined as in OP *)
dg[t_?NumericQ] := If[t - 1. <= 0, g'[t], g'[1]];
tfn = NDSolveValue[{t'[s] == 1/Norm[dg[t[s]]], t[0] == 0,
WhenEvent[t[s] == 1, "StopIntegration"]},
t, {s, 0, 1 + NIntegrate[Norm[g'[t]], {t, 0, 1}]}];

ListPlot[g /@ tfn[Rescale[Range[0, 1, 1/20], {0, 1}, First@tfn["Domain"]]],
AspectRatio -> Automatic]


Aspect ratio

If you want a different aspect ratio other than Automatic, such as the default 1/GoldenRatio, then we have to adjust how the arclength is computed by scaling the derivative vector, e.g., by {1, 1/GoldenRatio}.

ClearAll[s, t];
(* g defined as in OP *)
dg2[t_?NumericQ] :=  If[t - 1. <= 0, g'[t], g'[1]] {1, 1/GoldenRatio};
tfn2 = NDSolveValue[{t'[s] == 1/Norm[dg2[t[s]]], t[0] == 0,
WhenEvent[t[s] == 1, "StopIntegration"]},
t, {s, 0, 1 + NIntegrate[Norm[dg2[t]], {t, 0, 1}]}]

ListPlot[g /@ tfn2[Rescale[Range[0, 1, 1/20], {0, 1}, First@tfn2["Domain"]]]]


Here is another way based on my answer to this question:

Different MeshStyle for different functions

It used to not work on Windows, but I'm not sure about whether that is so for V10.

ParametricPlot[g[t], {t, 0, 1},
PlotStyle -> {Directive[CapForm["Round"], Dashing[{0, 0.06}],
Thickness[0.02]], Directive[]}, AspectRatio -> 1/GoldenRatio]


-