Let’s create some points corresponding to a simple closed curve

C0 = ContourPlot[x^2/4 + y^2/9 == 1, {x, -5, 5}, {y, -5, 5}, PlotPoints -> 100];

data = C0[[1, 1]];

S0 = ListPlot[data, PlotStyle -> {Blue, PointSize[0.005]}]

Now I would like to find the intersection points with the two axes. In this example the solutions should be x=±2x=±2x = \pm 2 and y=±3y=±3y = \pm 3.

IMPORTANT NOTE: The real data file corresponds to a closed curve with unknown analytical equation, so in the suggested solution you should not take into account the equation of the ellipse, only data is known.

Many thanks in advance.

=================

What version are you on? C0[[1, 1]] works for extracting points in old versions, but not in the new ones.

– J. M.♦

Nov 21 ’15 at 18:00

@J.M. I have v9.0.

– Vaggelis_Z

Nov 21 ’15 at 18:02

@J.M. BTW, if I want to extract points in v10 what should I use?

– Vaggelis_Z

Nov 21 ’15 at 18:09

2

@J.M. Actually C0[[1,1]] works just fine in v10.3: it extracts the actual coordinates of the points from the GraphicsComplex generated by ContourPlot.

– MarcoB

Nov 21 ’15 at 18:50

@Marco, ah, right; nevertheless, it’s not really the best way of extracting those points.

– J. M.♦

Nov 21 ’15 at 19:05

=================

1 Answer

1

=================

Get rid of duplicate x values we can feed to an interpolation function

domain = Select[Tally[data[[All, 1]]], #[[2]] == 1 &][[All, 1]];

Create Interpolation functions and evaluate at 0

These are for the top and bottom halves of the fn

Interpolation[Select[data, #[[2]] < 0 && MemberQ[domain, #[[1]]] &]][0] Interpolation[Select[data, #[[2]] > 0 && MemberQ[domain, #[[1]]] &]][0]

-2.99994

2.99994

Max and Min on the domain can approximate the x intercepts:

Max[domain]

Min[domain]

1.99985

-1.99985

EDIT

Assuming your ellipse isn’t 0-centered you will need exact x-intercepts

This requires a second domain and second set of interpolating functions, necessitating a transposition and reevaluation.

data2 = Reverse /@ data;

domain2 = Select[Tally[data2[[All, 1]]], #[[2]] == 1 &][[All, 1]];

Interpolation[Select[data2, #[[2]] < 0 && MemberQ[domain2, #[[1]]] &]][0] Interpolation[Select[data2, #[[2]] > 0 && MemberQ[domain2, #[[1]]] &]][0]

-1.99996

1.99996

It works like a charm! However I think that the second Max and Min of the domain approximate the x intercepts, not y, right?

– Vaggelis_Z

Nov 21 ’15 at 19:16

@Vaggelis_Z correct! made the edit in the answer

– Peter Roberge

Nov 21 ’15 at 19:18

@Vaggelis_Z please see the edit I made to actually solve for the x-intercepts, which will allow for your data to not be centered on 0

– Peter Roberge

Nov 23 ’15 at 1:16