# Tag Info

35

So, what is the best way to join points in Mathematica? There is no one "best way" (not only in Mathematica, but in general); an interpolation scheme that behaves nicely for data set A might be a crapshoot when applied to data set B. It depends on the configuration of your points, and impositions you have on the interpolant (e.g. $C^1$/$C^2$ continuity, ...

22

May not turn out to be a very general method but here I will adapt the Interpolation function of MMA in a way so that smoother result can be obtained for your specific data set. Interpolation vs. ListLinePlot First lets see how the default Interpolation behaves compared to the interpolating function used when we call ListLinePlot with same interpolation ...

19

You can use MeshFunctions to do the trick: g = BSplineFunction[{RandomReal[1, 20], RandomReal[1, 20]}\[Transpose]]; dg = g'; ParametricPlot[ g[t], {t, 0, 1}, MeshFunctions -> Function[{x, y, t}, dg[t].{0, 1}], Mesh -> {{0}}, MeshStyle -> Directive[AbsolutePointSize[5], Red] ] Here the MeshFunctions specifies the value of ...

18

I'm not sure if this addesses all of the issues you are having but here is an implementation I put together some time ago that allows us to use LinearModelFit and BSplineBasis to do spline regression. The benefit of this approach is that all of the properties of FittedModel are immediately available to us. This allows for checking for fit, residual ...

15

The natural way to go is BSplineFunction[]. The problem is that it needs a rectangular array of data as input and you collected a different number of points for each z plane. So what we will do is to get an interpolating function for each z == const plane and generate an equal number of points at each plane. To be somewhat more clever, we could generate [...

14

Fortunately there is a solution but it appears to be undocumented and takes a bit of guess work. The magic is: FilledCurveBoxOptions -> {Method -> {"SplinePoints" -> (* integer value *)}} This may be set globally or for a Notebook: SetOptions[InputNotebook[], FilledCurveBoxOptions -> {Method -> {"SplinePoints" -> 30}}] (Use $FrontEnd ... 13 A simple line strip should be sufficient for most purposes and there you can use VertexColors as usual: pts = {{0, 0}, {1, 1}, {2, 0}}; Graphics[{Thick, Line[BezierFunction[pts] /@ #, VertexColors -> (Blend[{Red, Green}, #] & /@ #)] &[Range[0, 1, .01]], Line[{{0, 0}, {2, 0}}, VertexColors -> {Red, Green}]} ] 13 For a simple image like that (high-contrast object in front of a monochrome background), calling EdgeDetect is actually enough to find the edges: img = Import["http://i.stack.imgur.com/UhLrU.png"]; edges = EdgeDetect[img]; Then we can find the leftmost and rightmost points on every line to get an array of radii: radii = Map[Max[#[[All, 1]]] - Min[#[[... 13 The following works for your curve: points = {{1, 4}, {.5, 6}, {5, 4}, {3, 12}, {11, 14}, {8, 4}, {12, 3}, {11, 9}, {15, 10}, {17, 8}}; deg = 3; pointsCLOSE1 = Join[points, points]; n = Length@pointsCLOSE1; knotsCLOSE1 = Range[0, 1, 1/(n + 1)]; ParametricPlot[deBoor[pointsCLOSE1, {deg, knotsCLOSE1}, t], {t, deg/(n + 1), 1}, Axes -&... 12 I appreciate kguler's elegant solution, but it doesn't join the points. To be more precise, it joins only every third point because Bezier line additionally takes 2 anchor points for each point. There are different methods to obtain these points. The simplest one is the following (pictures taken here) In Mathematica it looks like the following code (... 12 The built-in functionality can do this directly: {xs, ys} = Transpose[points]; xinterp = Interpolation[xs, Method -> "Spline"]; yinterp = Interpolation[ys, Method -> "Spline"]; ParametricPlot[{xinterp[t], yinterp[t]}, {t, 1, Length@points}, Epilog -> Point /@ points] Without the "Spline" method, the interpolating functions are not always ... 12 f[n_, j_, u_] := PiecewiseExpand[BernsteinBasis[n, j, u]] cv[pt_, n_, u_] := (f[n, #, u] & /@ Range[0, n]).pt Test: pts = {{0, 0}, {2, 4}, {4, 5}, {6, 0}}; ParametricPlot[cv[pts, Length@pts - 1, v], {v, 0, 1}, Epilog -> {Red, PointSize[0.02], Point[pts], Green, Line[pts]}, PlotRange -> {0, 6}] Or DynamicModule[{p = {{0, 0}, {2, 4}, {4, ... 12 This might help you get an idea: n = 4; BlockRandom[SeedRandom[42, Method -> "Legacy"]; (* for reproducibility *) cpts = Table[{i, j, RandomReal[{-1, 1}]}, {i, n + 1}, {j, n + 1}]]; GraphicsRow[{ParametricPlot3D[BezierFunction[cpts][u, v], {u, 0, 1}, {v, 0, 1}, Evaluated -> True], (* built-in function *) ... 12 Graphics[{ Yellow, FilledCurve[{BSplineCurve /@ {pts1, pts4, Reverse@pts2, pts3}}], Green, Line[Join[pts1, pts4, Reverse@pts2, pts3]], Red, Point[Join[pts1, pts2, pts3, pts4]] }] 11 I have long been looking for a good implementation of Cubic Spline Smoothing with adjustable roughness penalty parameter for Mathematica. Your module gave me enough hints to understand how to make this work in Mathematica so I basically made a Cubic spline smoothing from your code with minor adjustments (about knots, a little bit about performance) ... 11 The OP linked to an answer of mine for interpolating over general point sets; for constructing a single interpolating function, a slight modification of my procedure is needed. (In particular, you don't need centripetal or chord-length parametrization in this case.) Let's start with some data: data = {{0, 0}, {1/10, 3/10}, {1/2, 3/5}, {1, -1/5}, {2, 3}, {3,... 11 Major update, version 2.0 What changed: Is a different, more clever way of solving the problem. Overcomes most of the issues of previous versions. Problem summary: I will rephrase the problem in simplest terms. There exests a named curve called limacon (french, pronounced [ˈlɪməsɒn], means snail), described by a simple equation$r=a+b\cos{\theta}$in ... 10 Reason for incompatibility Yes, the doc shouldn't mention that it is fully compatible (that's an oversight...). BSplineFunction and BSplineCurve are fully compatible as far as I remember, but not BezierCurve and BezierFunction. The reason is that what BezierCurve is doing when it has more than d+1 control points for SplineDegree->d case is something ... 10 Update Fully compiling the code to C makes it as fast as the built-in: cBernstein = Compile @@ (Hold[{n, {j, _Real, 1}, u}, Table[expr u^i (1 - u)^(n - i), {i, j}], CompilationTarget -> C] /. expr -> FunctionExpand[Binomial[n, i]]) BezierSurface4 = With[{cBernstein = cBernstein}, With[{AllBasis = Function[{deg, u0}, cBernstein[deg, ... 9 I've used the method I'm about to show in this answer, but I suppose having it explicitly answer an interpolation question would be convenient. Starting with your points, testData = {{10, 10}, {10, 20}, {10, 25}, {10, 27}, {10, 28}, {9, 26}, {8, 25}, {5, 20}, {3, 1}}; we use Lee's centripetal parametrization scheme to generate corresponding ... 9 The warning is probably caused by premature evaluation (no pun intended). Because of the symbolic parameter t, s[t] evaluates to BSplineFunction[{{0.,1.}},<>][t] instead of a list of the form {x,y}, and only evaluates to numeric values when t assumes numeric values, too. The normal solution to this is to postpone the access of the y-variable [[2]] to ... 9 Here is my implementation of quadric spline arbitrary precision interpolation which is defined exactly as in Interpolation with options Method->"Spline", InterpolationOrder->2. Theoretical background Quadric spline interpolation for n datapoints is defined as a Piecewise function which consists of n-2 parabolas which are spliced together in the ... 8 BSplineCurve is based on BSplineFunction. But BSplineFunction is analytic expression - so you do not need to interpolate it - you can use it as a (parametric) function: g = BSplineFunction[points]; ParametricPlot[g[t], {t, 0, 1}] If you still need points - this will work with any step: bspts=Table[g[t], {t, 0, 1, .1}] 8 pts = {{0, 0}, {1, 1}, {2, 0}}; f = BezierFunction[pts]; Show[ ParametricPlot[f[t], {t, 0, 2}, ColorFunction -> Function[{x}, RGBColor[1 - x, x, 0]]], Graphics[{Thick,Line[{{0, 0}, {2, 0}}, VertexColors -> {Red, Green}]}], Axes -> None ] 8 Yes, there seems to be a bug in there. You still may use BSplineFunctionif you are OK with numerical results: << NumericalCalculus` d = 2; kV = {0, 0, 0, 1, 1, 1}; P = {{0, 0}, {0, 1}, {1, 1}}; W = {1, 1/Sqrt[2], 1}; x[t_] := BSplineFunction[P[[All, 1]], SplineWeights -> W, SplineDegree -> d, SplineKnots -> kV][t] /; 0 < t < 1 x[r_] :... 8 The definition of B-Spline curve $$\vec{C}(u)=\sum _{i=0}^n N_{i,p}(u) \vec{P}_i \text{ }\qquad (0\leq u\leq 1)$$ where,$\vec{P}_i$is the control point, and the$N_ {i, p} (u)$are the$p$-th - degree B-spline basis functions defined on the non-periodic(and non-uniform) knot vector$U$.$\$U=\{\underbrace {0,\cdots ,0}_{p+1},u_{p+1},\cdots u_{m-p-1},\...

8

A more interesting example with multiple extrema.. g = BSplineFunction[{{1, 2}, {2, 4}, {3, -1}, {4, 2}, {5, 0}, {6, 1}}]; gp = g'; gpy[t_?NumericQ] := gp[t][[2]]; This is utilising Plot to generate the curve and look for zero crossings, which we then pass as starting points to FindRoot loc = Flatten[ t /. # & /@ FindRoot[gpy[t] , ...

8

Perhaps more compact: Manipulate[ ParametricPlot[BezierFunction[lo]@t, {t, 0, 1}, Epilog -> {Green, Line[lo]}], {{lo, pts}, Locator}, Initialization :> (pts = {{0, 0}, {1, 2}, {2, 0}, {3, 3}})]

8

Since there is really something wrong with the BezierCurve, I made this work-around: Clear[bezierCurve]; bezierCurve[pts_] := First@ParametricPlot[ BezierFunction[pts, SplineDegree -> Length[pts] - 1][t], {t, 0, 1}] Manipulate[ Graphics[{bezierCurve[pts], Dashed, Green, Line[pts]}, PlotRange -> {{-.5, 1.5}, {-.5, 1.5}}, Frame -> True],...

8

This was solved with help from Shutao Tang, J.M., Sander Huisman and Eric Rimbey. Why do BezierFunction[pt] and BezierCurve[pt] not agree? Because BezierCurve uses SplineDegree -> 3 by default and BezierFunction always uses degree Length[pt] - 1 (not settable). Why does DiscretizeGraphics give a bad result? Because it appears to use (the equivalent of)...

Only top voted, non community-wiki answers of a minimum length are eligible