Finding the arc length of a region defined implicitly with an interpolated function

I begin by defining an interpolation of some data I have stored at this link for brevity. The interpolating function is a function of two variables, x and y

S = (*data*)
f = Interpolation[S]
Plot3D[f[x, y], {x, -5, 4}, {y, -5, 4}]


I then want to define a one-dimensional surface by when this interpolated function intersects zero

R = ImplicitRegion[f[x, y] == 0.0]
RegionPlot[R, PlotRange -> {{-5, 4}, {-5, 4}}


This looks like it has worked quite well, but now when I try to calculate ArcLength[R], I don't get an answer, even when I try restricting the domain of the implicit region

R = ImplicitRegion[f[x, y] == 0.0, {{x, -5, 4}, {y, -5, 4}}]


The ellipse looks pretty well-defined, is there a way of getting its arc Length?

• Here's one way folks can import the data: S = Import["https://gist.github.com/jhwilson/10467024a973e3b8cf0acf4990a1a21d", "Data"][[1, 2]] // ToExpression Feb 11 at 16:22

I don't know how accurately you want the arc length, but going along the lines you started, one can do this:

R = ImplicitRegion[f[x, y] == 0.0, {{x, -5, 4}, {y, -5, 4}}];
DiscretizeRegion[R, MaxCellMeasure -> 0.01] // ArcLength

(*  19.7927  *)


A more accurate determination:

Module[{tf},
NDSolveValue[{{x'[t], y'[t]} ==
Cross@D[f[x[t], y[t]], {{x[t], y[t]}}],
x[0] == (x /. FindRoot[f[x, 0], {x, 2}]), y[0] == 0,
s'[t] == Sqrt[x'[t]^2 + y'[t]^2], s[0] == 0,
WhenEvent[y[t] == 0 && x[t] > 0, {tf = t; "StopIntegration"}]},
s[tf], {t, 0, 10000}]
]

(*  19.7955  *)


It takes a bit of work to get there with DiscretizeRegion:

DiscretizeRegion[R, MaxCellMeasure -> 0.0001] // ArcLength

(*  19.7954  *)


This is a bit of a hack. Assume we have your plot: pl from the data:

R = ImplicitRegion[f[x, y] == 0.0, {x, y}]
pl = RegionPlot[R, PlotRange -> {{-5, 4}, {-5, 4}}]


We may no dissect pl to get the relevant information. Unfortunately, the line is not stored directly, but first the coordinates of the points are stored and then the line is specified by the indices of the coordinates. To get the coordinates of the line and to check if it is o.k. we write:

coor = g[[1, 1, 1]];
ind = g[[1, 1, 2, 1, 1, 3, 1]];
line = coor[[ind]];
ListLinePlot[line]


Now the length of the line is easily calculated by taking the successive differences and the norm therefrom and finally adding up:

Total[Norm /@ Differences[line]]
(* 19.7268 *)

• Slightly less hacky: Total@Cases[Normal@pl, l_Line :> ArcLength[l], Infinity]. Feb 11 at 18:17
• Michael E2 Hi, Line gives indices, not coordinates. Reason: GraphicsComplex Feb 11 at 19:30
• Try my code. I got 19.7268 when I ran it. Feb 11 at 19:32
• Hmmm, I get 306.008. Look at pl[[1, 1, 2]] then you see that Line[..] is a list of indices. Only to make sure, pl is the output of Plot3D. Feb 11 at 19:47
• It's the last point under "Details and Options" of the doc page for GraphicsComplex. Feb 11 at 21:06