Hi everyone, and thank you Charles for these awesome papers and robust library.
I've used your code to assemble together C++ tools for solving the common geodesic problems, as well as various intersections between different types of curves (currently geodesic segments and circles... while i'm also planning for offset curves, rhumb lines and some others used in some aeronautical geographic definitions). Each curve type is currently able to intersect with others, as well as parallels and meridians. For parallels, solving for a point on a geodesic line with a given latitude was straightforward, however when solving against given longitude, I'm hitting that hairy "I3" integral.
My temporary solution for intersecting stuff with a meridian is to treat it as a geodesic (works as a 180° arclength geodesic segment at least for oblate ellipsoids) and use the geodesic segment intersection routines instead. However it's itching that I could do better than this... I see that you give the series expansion coefficients for reverting the distance integral, which is used in the direct problem. Would it be possible to also invert the lambda integral in a similar manner ? Quickly browsing for Lagrange inversion give me formulas which are quite beyond my own grasp on mathematics, and I'm not versed in Maxima either. In case this kind of exercise is easy for you, could you maybe show me the way to get the coefficients of the inverted expansion ?
Thanks,
Guillaume Mirey
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
By the way, I improved my current implementation. now trying to solve for it iteratively.
Using your naming scheme, I would begin from a first guess sig12 == lam12, recomputing each time an omg12 and a new lam12 from this sigma, comparing the resulting lam12 delta to desired (dErr), and correcting back (in the majority of cases where salp0 isn't too small) omg12 with
omg12 -= dErr * (1 - _A3c);
and recovering the next iteration sig12 from this updated omg12...
(I'm thus simply ignoring the I3 term in the correction, as I have no clue how to handle it...)
This seems already quite precise and way faster than using an intersection routine with a geodesic segment in place of the meridian, although I'm still wondering whether inverting I3, in a similar manner to inverting I1, is doable ^^
Last edit: FaleneLogics 2017-07-27
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Yes the I3 series is surely invertible. But rather than messing up your
code with another compilicated series expansion, why not invert it with
Newton's method? Compute the error with the series exansion; however
use the integrand in Eq. (8) to give the derivative needed to compute
the Newton correction. This method will converge quadratically (double
the number of correct digits with each iteration). This will do a lot
better that the method given in your second message (which seems to be a
rather ad hoc approach).
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
A quick check says:
Need a - instead of + in the second equation for lam'(sig).
Oh and I see you fixed the iteration to use lam(sig.n) - lam0 instead of lam(sig.n).
However, a really good test is to print out the errors as the method progresses
and you need to see the error going like
1e-2
1e-4
1e-8
1e-16
1e-16 (at round off limit)
I will also repeat the check with MPFR because then you can extend the
test arbitrarily far.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
In case anyone is interested, my attempt at derivating lambda above was quite wrong. (I miserad a w for omega in Charles Karney's paper). the omega derivative part is much more like :
Lambda as a function of sigma however is far less well-behaved than was the distance function : in case of geodesics which are quite close to meridians themselves, there are two cases where applying the Newton's method naively would fail :
First, when getting really close to the apex point of those almost-meridian geodesics, that derivative explodes. dividing the error by it thus would result in adding zero and no progress being made, even if the error is still significant.
Second, on the contrary, the "flat" parts of the function are really flat for almost meridians, thus the derivative is almost zero and dividing the error by it would result in correction of sigma by huge amounts (I cut those when they'd get above a quarter pi).
In those cases, I "did" revert the newton iteration to that "ad-hoc" method of mine in the second post.
Now works like a charm for all my test cases so far ;)
Note that if the geodesic line is really, really close to a meridian (sin(alp0) ~= 0), then this time I shortcut that whole iterative part altogether and force sigma2 to either the northern or southern apex of the line (whichever closer), ie an almost-polar point. [Edit] Also, first guess for sigma is now computed from a first guess omega12 == target lambda12
Regards,
Guillaume Mirey
Last edit: FaleneLogics 2017-07-29
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Indeed... β, ω, σ, and α are all quantities defined on the auxiliary sphere. So the formulas connecting them, Eqs. (9) to (18) in Geodesics on an ellipsoid of revolution, do not depend on the ellipsoid parameters, f or e. Sorry I didn't catch this earlier.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anonymous
Anonymous
-
2020-04-15
As discussed in this thread, I need to solve for the point on a geodesic line with a given longitude. Has this method been refined? Is there code somewhere that I can use? Thanks!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
For what it's worth, I can post the code I ended up with (it's been a while, I can't really tell the whys of everything, now).
[Note: judging by all this, in retrospect, you'd probably be better checking for intersect between two geodesics. On Earth at least, the line with constant longitude is a geodesic. Simply initialize it at equator for example, and with your desired longitude, towards azimuth 0.]
Anyway. This is the function doing the main computation work:
And the structures that I use, appearing as parameters in the functions above.
Hopefully self-explanatory if you understand Charles code (I have simply divided the concerns of a point on a line, from the point-agnostic params of the line, and my whole codebase is organized around this)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anonymous
Anonymous
-
2020-04-16
Guillaume,
Thank you very much for posting. I was thinking that this approach would have better performance than the intersect between two geodesics using the gnomonic projection iteratively. I'll compare and see; I need to do this with thousands of lines, and some of the lines change dynamically as the user edits them.
Best regards,
Sean
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
There is certainly some overhead in using solution to the intersection problem via the gnomonic projection and coding the problem directly will give you a faster result. However, it may be that the gnomonic method is "fast enough". The gnomonic method also has the drawback that everything needs to be within one hemisphere. But, you can get around this restriction by finding an approximate solution using spherical geometry and moving the starting point for the geodesic to be close to the intersection point.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
View and moderate all "Open Discussion" comments posted by this user
Mark all as spam, and block user from posting to "Help"
Hi everyone, and thank you Charles for these awesome papers and robust library.
I've used your code to assemble together C++ tools for solving the common geodesic problems, as well as various intersections between different types of curves (currently geodesic segments and circles... while i'm also planning for offset curves, rhumb lines and some others used in some aeronautical geographic definitions). Each curve type is currently able to intersect with others, as well as parallels and meridians. For parallels, solving for a point on a geodesic line with a given latitude was straightforward, however when solving against given longitude, I'm hitting that hairy "I3" integral.
My temporary solution for intersecting stuff with a meridian is to treat it as a geodesic (works as a 180° arclength geodesic segment at least for oblate ellipsoids) and use the geodesic segment intersection routines instead. However it's itching that I could do better than this... I see that you give the series expansion coefficients for reverting the distance integral, which is used in the direct problem. Would it be possible to also invert the lambda integral in a similar manner ? Quickly browsing for Lagrange inversion give me formulas which are quite beyond my own grasp on mathematics, and I'm not versed in Maxima either. In case this kind of exercise is easy for you, could you maybe show me the way to get the coefficients of the inverted expansion ?
Thanks,
Guillaume Mirey
By the way, I improved my current implementation. now trying to solve for it iteratively.
Using your naming scheme, I would begin from a first guess sig12 == lam12, recomputing each time an omg12 and a new lam12 from this sigma, comparing the resulting lam12 delta to desired (dErr), and correcting back (in the majority of cases where salp0 isn't too small) omg12 with
and recovering the next iteration sig12 from this updated omg12...
(I'm thus simply ignoring the I3 term in the correction, as I have no clue how to handle it...)
This seems already quite precise and way faster than using an intersection routine with a geodesic segment in place of the meridian, although I'm still wondering whether inverting I3, in a similar manner to inverting I1, is doable ^^
Last edit: FaleneLogics 2017-07-27
Yes the I3 series is surely invertible. But rather than messing up your
code with another compilicated series expansion, why not invert it with
Newton's method? Compute the error with the series exansion; however
use the integrand in Eq. (8) to give the derivative needed to compute
the Newton correction. This method will converge quadratically (double
the number of correct digits with each iteration). This will do a lot
better that the method given in your second message (which seems to be a
rather ad hoc approach).
Thanks a lot for pointing me the way. My lack of mathematical background makes those "obvious" methods hard to spot for me.
so...
Am I on the right track ?
Thanks !
Guillaume Mirey
Last edit: FaleneLogics 2017-07-27
A quick check says:
Need a - instead of + in the second equation for lam'(sig).
Oh and I see you fixed the iteration to use lam(sig.n) - lam0 instead of lam(sig.n).
However, a really good test is to print out the errors as the method progresses
and you need to see the error going like
1e-2
1e-4
1e-8
1e-16
1e-16 (at round off limit)
I will also repeat the check with MPFR because then you can extend the
test arbitrarily far.
View and moderate all "Open Discussion" comments posted by this user
Mark all as spam, and block user from posting to "Help"
You, sir, rox.
Many thanks !
View and moderate all "Open Discussion" comments posted by this user
Mark all as spam, and block user from posting to "Help"
In case anyone is interested, my attempt at derivating lambda above was quite wrong. (I miserad a w for omega in Charles Karney's paper). the omega derivative part is much more like :
Lambda as a function of sigma however is far less well-behaved than was the distance function : in case of geodesics which are quite close to meridians themselves, there are two cases where applying the Newton's method naively would fail :
First, when getting really close to the apex point of those almost-meridian geodesics, that derivative explodes. dividing the error by it thus would result in adding zero and no progress being made, even if the error is still significant.
Second, on the contrary, the "flat" parts of the function are really flat for almost meridians, thus the derivative is almost zero and dividing the error by it would result in correction of sigma by huge amounts (I cut those when they'd get above a quarter pi).
In those cases, I "did" revert the newton iteration to that "ad-hoc" method of mine in the second post.
Now works like a charm for all my test cases so far ;)
Note that if the geodesic line is really, really close to a meridian (sin(alp0) ~= 0), then this time I shortcut that whole iterative part altogether and force sigma2 to either the northern or southern apex of the line (whichever closer), ie an almost-polar point.
[Edit] Also, first guess for sigma is now computed from a first guess omega12 == target lambda12
Regards,
Guillaume Mirey
Last edit: FaleneLogics 2017-07-29
Indeed... β, ω, σ, and α are all quantities defined on the auxiliary sphere. So the formulas connecting them, Eqs. (9) to (18) in Geodesics on an ellipsoid of revolution, do not depend on the ellipsoid parameters, f or e. Sorry I didn't catch this earlier.
As discussed in this thread, I need to solve for the point on a geodesic line with a given longitude. Has this method been refined? Is there code somewhere that I can use? Thanks!
For what it's worth, I can post the code I ended up with (it's been a while, I can't really tell the whys of everything, now).
[Note: judging by all this, in retrospect, you'd probably be better checking for intersect between two geodesics. On Earth at least, the line with constant longitude is a geodesic. Simply initialize it at equator for example, and with your desired longitude, towards azimuth 0.]
Anyway. This is the function doing the main computation work:
This is the calling function, where we query intersection between geodesic line and meridian:
And the structures that I use, appearing as parameters in the functions above.
Hopefully self-explanatory if you understand Charles code (I have simply divided the concerns of a point on a line, from the point-agnostic params of the line, and my whole codebase is organized around this)
Cheers,
Guillaume.
Last edit: FaleneLogics 2020-04-16
Guillaume,
Thank you very much for posting. I was thinking that this approach would have better performance than the intersect between two geodesics using the gnomonic projection iteratively. I'll compare and see; I need to do this with thousands of lines, and some of the lines change dynamically as the user edits them.
Best regards,
Sean
There is certainly some overhead in using solution to the intersection problem via the gnomonic projection and coding the problem directly will give you a faster result. However, it may be that the gnomonic method is "fast enough". The gnomonic method also has the drawback that everything needs to be within one hemisphere. But, you can get around this restriction by finding an approximate solution using spherical geometry and moving the starting point for the geodesic to be close to the intersection point.