In the case that one cannot solve the equation for a symbolic parametric representation, then NDSolve
can be used to do so numerically. And while we're at it, we may as well integrate the arclength. In the code below, we compute an arc length parametrization, so the parametrization returns to it's starting point when the parameter s
equals the total arc length of the loop.
ClearAll[f, x, y];
eqn = 1/x + 3/4 (((y - 1/Sqrt[3])/x)^2 + 1) Exp[ArcTan[(y - 1/Sqrt[3])/x] - Pi/6] == 0;
cplot = ContourPlot[Evaluate @ eqn, {x, -3, 1}, {y, -(1/5), 4}];
f[x_, y_] = eqn /. Equal -> Subtract // Together // Numerator // Simplify;
grad[x_, y_] = D[f[x, y], {{x, y}}];
unitTangent[x_, y_] = #/Sqrt[#.#] &@Cross@grad[x, y];
p0 = NestWhile[ (* Newton's method to find starting point *)
With[{g = grad @@ #}, (* use gradient for derivative *)
# - (f @@ #) g / g.g (* Newton's method step *)
] &,
cplot[[1, 1, 1]], (* start at a point on the contour plot *)
Abs[#1 - #2]/Norm[#1] > 1*^-15 &, (* stopping criterion *)
2,
20 (* no more than 20 iterations *)
];
sol = First@NDSolve[{
{x'[s], y'[s]} == unitTangent[x[s], y[s]], {x[0], y[0]} == p0,
WhenEvent[x[s] > p0[[1]], "StopIntegration"]},
{x, y}, {s, 0, Infinity}];
x["Coordinates"] /. sol // Last // Last
% - NIntegrate[
Sqrt[Simplify[(D[solx, t])^2 + (D[soly, t])^2]], {t, -Infinity,
Infinity}]
(*
9.83926 - arc length
8.24538*10^-7 - error (compared to b.gatessucks's result)
*)
Remarks: (1) One might need extra conditions for the stopping condition WhenEvent[x[s] > p0[[1]]...
in the case of more complicated curve. (2) The error when starting at p0 = cplot[[1, 1, 1]]
is almost 0.001
, so it is probably worth improving it in most cases.
Precision
. The result is alwaysMachinePrecision
, and the influence fromPlotPoints
is also big:PlotPoints -> 70
gives9.92371
,-> 200
gives9.85703
,-> 300
gives9.84398
,-> 400
gives9.84211
… $\endgroup$