Episode #125 of the Stack Overflow podcast is here. We talk Tilde Club and mechanical keyboards. Listen now

14 of 17 added 1181 characters in body

# Curve fit based on minimal data

Inspired by the fantastic answers here and here, I would like to ask a questions along similar lines.

I have 6 curve types

• Type A: If point 1 is positive and point 2 is negative, the curve will not pass through the origin.
• Type B: If point 1 is negative and point 2 is positive, the curve will pass through the origin twice.
• Types C-F: If both points are positive or both points are negative, the curve will pass through the origin once.

What is known:

• The coordinates of points 1 and 2.
• The gradient of tangents at points 1 and 2.
• The approximate curve type (limaçon).

What is not known:

• The arc length.

Data for A-F:

(* A *) {{0.000564367, 0.690525}, {-0.000689501, -0.984192}, 3.03065, -1.95699}
(* B *) {{-0.000689501, -0.984192}, {0.000664785, 1.07289}, -1.95699, 1.82419}
(* C *) {{0.000179304, 1.61576}, {0.0000936314, 0.852042}, 1.15014, 3.52804}
(* D *) {{0.000116063, 0.431337}, {0.000443491, 1.70111}, 2.88997, 1.41834}
(* E *) {{0.0000347276, 0.190688}, {0.000190634, 1.06651}, -3.77228, -2.08792}
(* F *) {{-0.000432719, -1.90935}, {-0.000142565, -0.645011}, -1.36691, -1.927}


in format: {{point 1}, {point 2}, gradient of tangent @ point 1, gradient of tangent at point 2}

Is it possible to estimate a curve fit (and hence arc length & skew) with only the data given?

# Notes

I apologise for the lack of clarity on this question. The limacon is only a guess really as to the approximate shape. I have approximated the curves with limacons, but only after much fiddling. Any other approach is welcomed.

I can try to rephrase a little as follows: The problem can also be thought of like this:

A circle is cut and the points are slid up and down a vertical axis as shown:

Imagine that the tangents and positions of the endpoints are controllable, but there are no other parameters other than the theoretical elasticity (and tendency to move back to a circular form) are known.

I posted this image on a question on physics SE and John Rennie gave a link to an interesting PDF here on a similar subject.

It is essentially modelling a physical phenomenon. I have been playing around with Bezier curves, and have been getting fairly close, and even closer to the shapes doing it intuitively in Illustrator. I have even tried modelling it with wire - which gets the closest to the curves shown. Apart from this though, I am not having much success. As said previously, any approaches are welcome. I am looking for any insights into the problem.

Piecewise limacon example:

Show[PolarPlot[{ θ^(1/12) 1.815 Re[E^( I ( θ + 0.075))] -
0.86}, {θ, 0.98, 2 Pi - 1.22}],
PolarPlot[{1.875 Re[E^( I ( θ - 0.015))] - 0.95}, {θ, -1.02, 1.05}]]


Apologies for using the same image on both sites, but I thought it might be allowed since I was asking something essentially different! ;)

Data for one f the curves might help:

{{-0.000432719, -1.90935}, {-0.0572673, -1.82719}, {-0.108982,
-1.74322}, {-0.15552, -1.65773}, {-0.196844, -1.57104}, {-0.232935,
-1.48345}, {-0.263789, -1.39526}, {-0.289422, -1.30677}, {-0.309866,
-1.21829}, {-0.325172, -1.1301}, {-0.335405, -1.04249}, {-0.340648,
-0.955758}, {-0.341, -0.870171}, {-0.336576, -0.786}, {-0.327504,
-0.703507}, {-0.313929, -0.622942}, {-0.296007, -0.544546},
{-0.273908, -0.468551}, {-0.247817, -0.395174}, {-0.217925,
-0.324621}, {-0.184439, -0.257086}, {-0.147573, -0.192748},
{-0.107551, -0.131773}, {-0.0646045, -0.0743111}, {-0.0189726,
-0.0204992}, {0.0290993, 0.0295421}, {0.0793607,
0.0757076}, {0.131557, 0.117908}, {0.185429, 0.156069}, {0.240717,
0.190133}, {0.297158, 0.22006}, {0.35449, 0.245823}, {0.412451,
0.267413}, {0.470781, 0.284837}, {0.529221, 0.298116}, {0.587518,
0.307289}, {0.64542, 0.312408}, {0.702684, 0.313539}, {0.75907,
0.310766}, {0.814345, 0.304183}, {0.868287, 0.293899}, {0.920678,
0.280037}, {0.971313, 0.262729}, {1.02, 0.242122}, {1.06654,
0.218372}, {1.11077, 0.191646}, {1.15252, 0.162119}, {1.19164,
0.129975}, {1.22799, 0.0954078}, {1.26146, 0.0586159}, {1.29191,
0.0198048}, {1.31927, -0.0208148}, {1.34344, -0.063028}, {1.36435,
-0.106616}, {1.38195, -0.151359}, {1.39619, -0.197032}, {1.40705,
-0.243414}, {1.41451, -0.29028}, {1.41858, -0.337408}, {1.41927,
-0.384578}, {1.41661, -0.431572}, {1.41063, -0.478177}, {1.4014,
-0.524182}, {1.38899, -0.569383}, {1.37347, -0.613581}, {1.35493,
-0.656586}, {1.33349, -0.698213}, {1.30925, -0.738286}, {1.28234,
-0.776638}, {1.25289, -0.81311}, {1.22105, -0.847555}, {1.18697,
-0.879835}, {1.15081, -0.909823}, {1.11274, -0.937404}, {1.07292,
-0.962474}, {1.03154, -0.984942}, {0.988782, -1.00473}, {0.944824,
-1.02176}, {0.899858, -1.03599}, {0.854076, -1.04738}, {0.80767,
-1.05589}, {0.760831, -1.06151}, {0.713753, -1.06423}, {0.666624,
-1.06407}, {0.619634, -1.06104}, {0.572969, -1.05518}, {0.526811,
-1.04654}, {0.481336, -1.03516}, {0.436719, -1.02113}, {0.393124,
-1.00451}, {0.350714, -0.985394}, {0.309639, -0.963889}, {0.270047,
-0.940099}, {0.232073, -0.914142}, {0.195846, -0.886144}, {0.161485,
-0.856239}, {0.129097, -0.824567}, {0.0987833, -0.791274},
{0.0706306, -0.756513}, {0.0447164, -0.720441}, {0.0211071,
-0.683219}, {-0.000142565, -0.645011}}


# Update

Here is a start, using @ybeltukov 's spline method from here.

Manipulate[ pts = {{1, -1}, {0, ya}, {1, 1}, {2, 0}, {1, -1}, {0, yb}, {1, 1}};
dist = Norm /@ Differences[pts];
k = 0.5;
coeff = Rest[dist]/(Most[dist] + Rest[dist]);
diff = Differences[pts, 1, 2];
a1 = Join[pts - Flatten[{{{0, 0}}, k (1 - coeff) diff, {{0, 0}}}, 1]];
a2 = Join[pts + Flatten[{{{0, 0}}, k coeff diff, {{0, 0}}}, 1]];
bc = Drop[Drop[Flatten[{a1, pts, a2}, {{2, 1}}][[2 ;; -2]], 3], -3];
bezier = BezierCurve@bc;
Show[Graphics[{Blue, Thick, bezier, Black, Thick,
Line[{{0, -2}, {0, 2}}]}, PlotRange -> {{-1, 3}, {-2, 2}}],
ListPlot[{{0, ya}, {0, yb}}, PlotStyle -> {Red}]],
{{ya, 0}, -1, 1}, {{yb, 0}, -1, 1}]


Of course the points are only acting independently at the moment. Since a circle can be approximated with only 4 cubic splines, a solution based on that should be fine. Though the other 3 points aren't known, I think using the gradient parameter of points 1 & 2, and the added parameter of having to (generally) pass through the origin should be enough.