/** * pair.as - Actionscript analog to STL Pair class. * * Copyright (c) 2004, 2112 F/X. All Rights Reserved. * * Licensed for educational, non-commercial use. This software program is * supplied 'as is' without any warranty, express, implied, or otherwise, * including without limitation all warranties of merchantability or fitness * for a particular purpose. 2112 F/X shall not be liable for any special * incidental, or consequential damages, including, witout limitation, lost * revenues, lost profits, or loss of prospective economic advantage, resulting * from the use or misuse of this software program. * * @ignore * * @author Jim Armstrong * @version 1.1 */ class pair { static var FEET:Number = 100; static var MILES:Number = 101; static var KM:Number = 102; static var DEG_TO_RAD:Number = Math.PI/180.0; private var __first:Number; private var __second:Number; // for geo-coded data private var __isRadians:Boolean; private var __rMetric:Number; private var __rEnglish:Number; public function pair( _u:Number, _v:Number ) { __isRadians = false; // default to degrees if internal inputs are lat/long __rMetric = 6378.5; // radius of earth in km. __rEnglish = 20925524.97; // radius of earth in ft. if ( arguments.length == 0 ) { __first = 0; __second = 0; } else if ( arguments.length == 1 ) { __first = _u; __second = 0; } else { __first = _u; __second = _v; } } public function get first():Number { return __first; } public function get second():Number { return __second; } public function isRadians():Boolean { return __isRadians; } public function set first(_u:Number) { __first = _u; } public function set second(_v:Number) { __second = _v; } public function set radians(_b:Boolean) { __isRadians = _b; } // comparisons are lexicographic public function __lt(_p:pair):Boolean { if ( _p == undefined || _p == null ) return false; else return ( __first < _p.first || ( !(_p.first < __first) && __second < _p.second ) ); } public function __eq(_p:pair):Boolean { if ( _p == undefined || _p == null ) return false; else return ( __first == _p.first && __second == _p.second ); } // for printing public function format(Void):String { return ( "(" + __first + "," + __second + ")" ); } // create new pair public static function make_pair( _t:Number, _u:Number ):pair { return new pair(_t, _u); } // in lieu of a copy constructor public static function copy_pair( _p:pair ):pair { return new pair(_p.first, _p.second); } // l-1 norm public function __l1(Void):Number { return Math.abs(__first) + Math.abs(__second); } // l-2 norm public function __l2(Void):Number { return Math.sqrt( __first*__first + __second*__second ); } // l-inf norm public function __linf(Void):Number { return Math.max( Math.abs(__first), Math.abs(__second) ); } // Euclidean distance public function __dist(_p:pair):Number { if ( _p == undefined ) return undefined; else { var d1:Number = Math.abs( _p.first - __first ); var d2:Number = Math.abs( _p.second - __second ); return Math.sqrt( d1*d1 + d2*d2 ); } } // great-circle distance (no error checking on inputs). First pair value MUST be latitude. // Second is longitude. Latitude is in range [-90,90] with southern latitudes negative. // Longitude is in range [-180,180] with western latitudes negative. // // Lat/long may be entered in degrees or radians. Use the radians setter to control whether // all values are interpreted as degrees or radians. // public function __gcd(_p:pair, _units:Number ):Number { // compute result based on metric radius, then convert if necessary on return. var radius:Number = __rMetric; var lat1:Number = __first; var lat2:Number = _p.first; var long1:Number = __second; var long2:Number = _p.second; // convert to radians? if ( !__isRadians ) { lat1 *= DEG_TO_RAD; long1 *= DEG_TO_RAD; } if ( !_p.isRadians() ) { lat2 *= DEG_TO_RAD; long2 *= DEG_TO_RAD; } var dlat:Number = Math.abs(lat2 - lat1); var dlon:Number = Math.abs(long2 - long1); var sLat:Number = Math.sin(dlat*0.5); var sLong:Number = Math.sin(dlon*0.5); var a:Number = sLat*sLat + Math.cos(lat1)*Math.cos(lat2)*sLong*sLong; var c:Number = 2*Math.asin(Math.min(1.0,Math.sqrt(a))); var km:Number = radius*c; // results in klicks if ( _units == undefined || _units == KM ) return km; else if ( _units == MILES ) return km*0.621371192; else if ( _units == FEET ) return km*3280.8399; else return km; // an error could be thrown here as well } }