Options[FindAllCrossings] = Sort[Join[Options[FindRoot], {MaxRecursion -> Automatic, PerformanceGoal :> $PerformanceGoal, PlotPoints -> Automatic}]]; FindAllCrossings[f_, {t_, a_, b_}, opts___] := Module[{r, s, s1, ya}, {r, ya} = Transpose[First[Cases[Normal[Plot[fTranspose[First[Cases[Normal[ Plot[f, {t, a, b}, Method -> Automatic, Evaluate[Sequence @@ FilterRules[Join[{opts}, Options[FindAllCrossings]], Options[Plot]]]]], Line[l_] :> l, Infinity]]]; s1 = Sign[ya]; If[ ! MemberQ[Abs[s1], 1], Return[{}]]; s = Times @@@ Partition[s1, 2, 1]; If[MemberQ[s, -1] || MemberQ[Take[s, {2, -2}], 0], Union[Join[Pick[r, s1, 0], Select[t /. Map[FindRoot[f, {t, r[[#]], r[[# + 1]]}, Evaluate[Sequence @@ FilterRules[Join[{opts}, Options[FindAllCrossings]], Options[FindRoot]]]] &, Flatten[Position[s, -1]]], a <= # <= b &]]], {}]] A different implementation involves the use of the MeshFunctions option of Plot[] to generate the seeds. Here's how it looks:
FindAllCrossings[f_, {t_, a_, b_}, opts : OptionsPattern[]] := Module[{r}, r = Cases[Normal[Plot[f, {t, a, b}, MeshFunctions -> (#2 &), Mesh -> {{0}}, Method -> Automatic, Evaluate[Sequence @@ FilterRules[Join[{opts}, Options[FindAllCrossings]], Options[Plot]]]]], Point[p_] :> SetPrecision[p[[1]], OptionValue[WorkingPrecision]], Infinity]; If[r =!= {}, Union[Select[t /. Map[FindRoot[f, {t, #}, Evaluate[Sequence @@ FilterRules[Join[{opts}, Options[FindAllCrossings]], Options[FindRoot]]]] &, r], a <= # <= b &]], {}]] This version might be a bit faster in some cases, but it no longer has the safety feature of root bracketing in the previous version.