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

enter image description here

that follow these rules:

  • 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:

enter image description here

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.