Bracketed solver for step function

This may be more of a Hipparchus question but Orekit might have something useful already

My implementation specific question is: is it possible to root find on a lambda value where the target function is a step function? Everything to the left is -1, everything to the right is +1. Obviously this will never hit true zero but eventually the step size is small enough where the value of the independent variable is good enough.

The true problem I am trying to solve is creating vertices that represent a field of view that is not obstructed by a central body. My plan is to use the equivalent of the directionAt() method from CircularFieldOfView to create a vector v1 and if that vector intersects the earth then I look for a new vector v2 that lies somewhere on the plane defined by v and the boresight vector vb, where v2 is tangential to the OneAxisEllipsod. My first thought was to define a function where I pass the abscissa of the line v1vb as the lambda that gives me the pointing direction of v2, and if OneAxisEllipsod.getCartesianIntersectionPoint() returns a value then f(x)=+1 and if it returns a null then f(x)=-1.

Yes, it is possible, but as the values of the function do not give any hints about the behavior near the root, the root finding algorithm falls back to dichotomy, which is slower than the regular order 5 algorithm.

There is however a better way to implement what you need. You can look at the InterSatDirectViewDetector, which uses a skimming altittude threshold to decide if a line of sight is obstructed by the body (in fact even adding a user-defined skimming altitude). In order to do that, it uses OneAxisEllipsoid.lowestAltitudeIntermediate(endpoint1, endpoint2) which compute the intermediate point at lowest altitude between two endpoints. The altitude of this intermediate point is a continuous function, more suitable to be used in a root finding algorithm (which is exactly what InterSatDirectViewDetector uses).

Thank you @luc I actually ended up going down that path but still need to test the behavior.

For the eval function I created a piecewise function that I think should be continuous if not very smooth. To bracket the negative side I use getCartesianIntersectionPoint() to find the near intersection point, if that returns a non-null then I look for the other intersection point on the far side of the ellipsoid. The eval function value is then the negative norm of the vector between the two intersection points. If the first intersection calculation returns null then I use the lowestAltitudeIntermediate() method and the value of the eval function is the altitude of the returned GeodeticPoint

I’ll let you know how it goes.

Actually I think I see what you mean now. I will also try an eval function that only uses lowestAltitudeIntermediate()

^^^^ this worked perfectly, there was no need to over-complicate things like I originally intended.