Trying to evaluate NDSolve inside of FindRoot

I want to find the equation for the range of a projectile as a function of its elevation angle at launch.

Currently, I am stuck in my effort to calculate the time. What I have doesn't work right although it's what I was recommended to do.

tfinal[theta_] =
FindRoot[
y[t] /.
NDSolve[
{m y''[t] == -m g + 0.4 x'[t],
y == 0,
y' == vi Sin[theta],
m x''[t] == -0.01 x'[t] Abs[Sqrt[x'[t]^2 + y'[t]^2]],
x == 0,
x' == vi Cos[theta]},
{x[t], y[t]}, {t, 100}],
{t, 0, 20}]


Any help you could give me to make this work, and how to plug it into x[t] later would be appreciated.

• What are the values for vi and m and g because I don't think NDSolve will work without those. – Bill Oct 18 '18 at 19:23

You can use ParametricNDSolveValue and WhenEvent. First give your constants numerical values:

m = 10; g = 9.8; vi = 1000;

Clear[tfinal];
pf = ParametricNDSolveValue[
{
m y''[t] == -m g + .4 x'[t], y==0, y'==vi Sin[θ],
m x''[t] == -.01 x'[t] Abs[Sqrt[x'[t]^2+y'[t]^2]], x==0, x'==vi Cos[θ],
WhenEvent[y[t]==0, tfinal=t; "StopIntegration"]
},
{tfinal, x[tfinal], x[t], y[t]},
{t,0,1000},
θ,
Method->{"ParametricCaching"->None}
];


The Method option is used to prevent caching, as caching also disables the WhenEventwhen the same angle is repeated. For example:

pf[45 Degree][[;;2]]


{151.405, 877.313}

Visualization:

ParametricPlot[
pf[45 Degree][[3;;]],
{t, 0, pf[45 Degree][]},
AspectRatio->1,
PlotRange->All
] 