There is a small technical bug in "sub great_circle_destination {...}".
An additional (optional) argument, RHO, must be passed to the
subroutine. Otherwise, the calculation will always be based on the
assumption that we are using a unit sphere. RHO will represent the
radius of the sphere. I have previously written a subroutine also named
great_circle_destination which may be of use to you :) The subroutine
assumes that the user is inputting coordinates in radians using the
following standards:

North Western Hemisphere = (
                                        -pi <= Longitude <= 0,
                                        0 <= Latitude <= pi/2
                                   )

South Western Hemisphere = (
                                        -pi <= Longitude <= 0,
                                        -pi/2 <= Latitude <= 0
                                   )

North Eastern Hemisphere = (
                                        0 <= Longitude <= pi,
                                        0 <= Latitude <= pi/2
                                   )

South Eastern Hemisphere = (
                                        0 <= Longitude <= pi,
-pi/2 <= Latitude <= 0
                                   )

There is no need to subtract by pi/2 (pip2) in this case. The
destination is also required to be input in radians where:

 North is 0;
 South is -pi or pi;
 East is pi/2;
 West is -pi/2;

Here it is (tried and tested on GIS applications):

=cut
Example:

my ($dlat, $dlon) = great_circle_distance($lat, $lon, $distance,
$direction, 6378.1);

# 6378.1 is the radius of the earth in km. You could alternatively use
any 
# other value for rho, for example, 3443.89849 which is the radius of
the
# earth in nautical miles;)
=cut

sub great_circle_destination {
 
        my (
                $lat0,
                $lon0,
                $distance,
                $direction,
                $rho
        ) = @_;
 
        my (
                $lat1,
                $lon1
        );
 
# lat2 = asin(sin(lat1)*cos(d) + cos(lat1)*sin(d)*cos(hdng)) 
# lon2 = lon1 + atan2(sin(hdng)*sin(d)*cos(lat1),
cos(d)-sin(lat1)*sin(lat2)) 
# Reference: http://www.movable-type.co.uk/scripts/LatLong.html
 
        $rho = 1 unless defined($rho);
        $distance = $distance/$rho;
        $lat1 = asin(sin($lat0)*cos($distance) +
cos($lat0)*sin($distance)*cos($direction));
        $lon1 = $lon0 + atan2(sin($direction)*sin($distance)*cos($lat0),
cos($distance)-sin($lat0)*sin($lat1));
 
        return ($lat1, $lon1);
 
}



-----Original Message-----
From: Jarkko Hietaniemi [mailto:[EMAIL PROTECTED] 
Sent: Wednesday, September 14, 2005 2:26 AM
To: Mueller, Steffen
Cc: perl5-porters@perl.org; Douba,Nadeem [CIS]
Subject: [PATCH] Math::Complex and Math::Trig updates (Re: [perl #37117]
Math::Complex atan2 bug)

The attached patch (#1) brings several pending updates to Math::Complex
and Math::Trig.

        - Complex: fix for the [perl #31117]: atan2(0, i) now works,
          as do all the (computable) complex argument cases (I adopted
          the Mathematica definition)
        - Complex: fixes for certain bugs in the make() and emake()
        - Complex: support returning the kth root directly
        - Complex: support [2,-3pi/8] in emake()
        - Complex: support 'inf' for make()/emake() (the 9**9**9 trick)
        - Complex: document make()/emake() more visibly
        - Trig: add more great circle routines: great_circle_waypoint()
          and great_circle_destination()

I also made the modules scratch-proof, err, 5.00504 and 5.6.2-resistant.

Since the Complex+Trig have had some fixes/updates over the years, maybe
also them should be spun off to CPAN so that users of older Perls can
use the latest versions?

The tiny patch (#2) documents the attested fact that atan2(0, 0) is not
well-defined (i.e., or ie., or ie, the result depends on the underlying
math libraries).

Both patches should be maint-worthy.



Reply via email to