How to get exact point of intersection of a plot with axis?

I have a parametric plot y(t) vs. x(t). I want to know exactly at what value of x, this y vs x curve crosses the x-axis? I tried with "Get coordinates" of Drawing tools but this is not so accurate. Can anyone please tell me how I can print the exact point of intersection between this curve and x-axis?

I want to find at what value of t, dbdt becomes zero.

• How about Solve[y[t]==0,t] – mikado Sep 5 '16 at 20:33
• I had tried with Solve too. But it was taking so much time (more than half an hour and still running) to print output! Actually these functions are not so simple. They both are like implicit functions f(x(y(z...)))). I don't care about the value of the independent variable t at which y becomes zero. I need the value of x only. If there is a faster way, please let me know. – cosmos Sep 5 '16 at 20:57
• Can you give what you actually have in code? – Feyre Sep 5 '16 at 21:00
• Please edit your question with the code, and provide a functioning code, this code won't run. – Feyre Sep 5 '16 at 21:17
• FindRoot[] is the way to find roots numerically, especially of equations that are difficult (e.g. non-analytic, use a numerical procedure such as NIntegrate, etc.). You should post code that adequately reproduces the computational issue you're having, but it doesn't have to be your private/confidential code. – Michael E2 Sep 5 '16 at 21:46

You may use MeshFunctions, though I don't know the precision :

gr00 = ParametricPlot[{t, t^2 - 1}, {t, 0, 2}, Mesh -> {{0}},
MeshFunctions ->  {#2 &},
MeshStyle -> Directive[Black, PointSize[.05]]]


Cases[Normal[gr00], Point[___], {1, Infinity}]


{Point[{0.999811, 0.}]}

• I got blank {{}} as output! – cosmos Sep 5 '16 at 22:12
• This probably won't work if the curve is tangent to the axis. Not sure what to recommend for that case. – Michael E2 Sep 7 '16 at 12:52

Consider

x[u_] := Sin[u]
y[u_] := Sin[2 u]
ParametricPlot[{x[u], y[u]}, {u, 0, 2 Pi}]


Solve for u an equation $y(u)=0$:

sol = u /. Solve[y[u] == 0, u]


{ConditionalExpression[[Pi] C1, C1 [Element] Integers], ConditionalExpression[1/2 ([Pi] + 2 [Pi] C1), C1 [Element] Integers]}

Evaluate x[u] taking sol as input and taking into account the conditions from the ConditionalExpressions:

Table[Simplify[x[sol[[i]]], Assumptions -> sol[[i, 2]]], {i, 1, Length@sol}]


{0, (-1)^C1}

One probably has to check what values can C[1] take (in this case Integers), so maybe instead

Simplify[x[sol], Assumptions -> sol]


{ConditionalExpression[Sin[[Pi] C1], C1 [Element] Integers], ConditionalExpression[Cos[[Pi] C1], C1 [Element] Integers]}

which on the other hand returns a slightly less clear solution.

EDIT: I developed a different method, suitable for this problem also, while answering another question.

Let's take the plot in the form

x[u_] := Sin[u]
y[u_] := Sin[2 u]
curve = Show[
ParametricPlot[{x[u], y[u]}, {u, 0, 2 Pi}, Axes -> None,
Plot[0, {x, -1, 1}, Axes -> None, PlotRangePadding -> None]]


and extract the pixel positions of intersection with

px = PixelValuePositions[#, White] & @
MorphologicalBranchPoints @ Thinning @ Binarize @ ColorNegate @ curve


{{180, 182}, {2, 180}, {180, 180}, {359, 180}, {180, 179}}

We need to connect them to the actual coordinates on the plot:

pl = PlotRange@curve


{{-1., 1.}, {-1., 0.999999}}

id = ImageDimensions@curve


{360, 360}

The relation between pl and id is linear, $y=ax+b$ and $y=cx+d$ in the horizontal and vertical directions, respecively:

{a, b} = {a, b} /.
First@Solve[{pl[[1, 1]] == b, pl[[1, 2]] == a id[[1]] + b}, {a, b}]
{c, d} = {c, d} /.
First@Solve[{pl[[2, 1]] == d, pl[[2, 2]] == c id[[2]] + d}, {c, d}]


{0.00555555, -1.}

{0.00555555, -1.}

The pixel positions transformed to plot coordinates:

ic = {a #1 + b, c #2 + d} & @@@ px


{{9.49664*10^-9, 0.011111}, {-0.988889, -1.50139*10^-7}, {9.49664*10^-9, \ -1.50139*10^-7}, {0.994444, -1.50139*10^-7}, {9.49664*10^-9, \ -0.0055557}}

look like this:

We can get rid of the ambiguity (5 points for 3 intersections) with clustering:

clu = ClusterClassify[ic, Method -> "DBSCAN"]


Number of clusters: 3

g = GatherBy[ic, clu]
icmean = Chop[#, 10^-6] &@Reverse[Mean /@ g]


{{0.994444, 0}, {-0.988889, 0}, {0, 0.0018517}}

Show[curve, Graphics[{PointSize[Large], Point[#]}] &@icmean]


which looks very good; icmean are the positions of the three intersections.