Created
November 19, 2014 10:42
-
-
Save k0t0vich/26b2074f119af2480773 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ru.yandex.maps.pano.engine.math.utils { | |
import ru.yandex.maps.geo.GeoPoint; | |
import ru.yandex.maps.pano.engine.core.SphericalCoordinates; | |
public class CoordinatesUtil { | |
public static function sphericalFromGeoPoints(centralPoint:GeoPoint, | |
geoPoint:GeoPoint):SphericalCoordinates { | |
var distance:Number = centralPoint.distanceTo(geoPoint); | |
var azimuth:Number = centralPoint.azimuthTo(geoPoint); | |
var elevation:Number = -Math.atan2(centralPoint.altitude - geoPoint.altitude, distance); | |
var radius:Number = Math.sqrt(distance * distance + | |
centralPoint.altitude * centralPoint.altitude); | |
var result:SphericalCoordinates = new SphericalCoordinates(azimuth, elevation, | |
radius); | |
return result; | |
} | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ru.yandex.maps.pano.engine.math.projections.source { | |
import flash.geom.Point; | |
import flash.geom.Rectangle; | |
import ru.yandex.maps.pano.engine.core.SphericalCoordinates; | |
import ru.yandex.utils.math.AngleUtil; | |
public class EquirectangularProjection implements ISourceProjection { | |
public static const projection:ISourceProjection = new EquirectangularProjection(); | |
public function EquirectangularProjection() { | |
} | |
public function sphericalToUv(sphericalPoint:SphericalCoordinates, span:Rectangle, | |
origin:SphericalCoordinates):Point { | |
// приводим к [0; 2П] | |
var dx:Number = AngleUtil.diff(sphericalPoint.azimuth, origin.azimuth) / span.width; | |
var dy:Number = (span.y - sphericalPoint.elevation + origin.elevation) / | |
span.height; | |
return new Point(dx, dy); | |
} | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ru.yandex.maps.geo { | |
import flash.geom.Point; | |
import ru.yandex.utils.math.Range; | |
public class GeoPoint { | |
public static function fromMercator(point:Point):GeoPoint { | |
// Isometric longitude | |
var lambda:Number = point.x / WGS84.RADIUS; | |
// Isometric latitude | |
var xPhi:Number = Math.PI / 2.0 | |
- 2.0 * Math.atan(1.0 / Math.exp(point.y / WGS84.RADIUS)); | |
var phi:Number = xPhi | |
+ WGS84.AB * Math.sin(2.0 * xPhi) | |
+ WGS84.BB * Math.sin(4.0 * xPhi) | |
+ WGS84.CB * Math.sin(6.0 * xPhi) | |
+ WGS84.DB * Math.sin(8.0 * xPhi); | |
return new GeoPoint(lambda, phi); | |
} | |
public function GeoPoint(longitude:Number = 0, | |
latitude:Number = 0, altitude:Number = 0) { | |
_latitude = latitude; | |
_longitude = longitude; | |
_altitude = altitude; | |
} | |
public function distanceTo(other:GeoPoint):Number { | |
if (this.equals(other)) { | |
return 0; | |
} | |
return new GeoVector(this, other).distance; | |
} | |
public function azimuthTo(other:GeoPoint):Number { | |
if (this.equals(other)) { | |
return 0; | |
} | |
return new GeoVector(this, other).azimuth; | |
} | |
public function toMercator():Point { | |
var f:Number = WGS84.E2 / 2; | |
var e:Number = Math.sqrt(f * (2.0 - f)); | |
var eSinLat:Number = e * Math.sin(_latitude); | |
var temp1:Number = Math.tan(Math.PI / 4.0 + _latitude / 2.0); | |
var temp2:Number = Math.pow( | |
Math.tan(Math.PI / 4.0 + Math.asin(eSinLat) / 2.0), e | |
); | |
var U:Number = temp1 / temp2; | |
var y:Number = WGS84.RADIUS * Math.log(U); | |
var x:Number = WGS84.RADIUS * _longitude; | |
return new Point(x, y); | |
} | |
public function copy(other:GeoPoint):void { | |
_latitude = other._latitude; | |
_longitude = other._longitude; | |
_altitude = other._altitude; | |
} | |
public function equals(other:GeoPoint):Boolean { | |
return other && ((GeoUtil.sign(_longitude - other._longitude) == 0) | |
&& (GeoUtil.sign(_latitude - other._latitude) == 0) | |
&& (GeoUtil.sign(_altitude - other._altitude) == 0) | |
); | |
} | |
public function clone():GeoPoint { | |
return new GeoPoint(_longitude, _latitude, _altitude); | |
} | |
public function toString():String { | |
return "{lat: " + _latitude + ", lng: " + _longitude + | |
", alt: " + _altitude + "}"; | |
} | |
private var _latitude:Number; | |
public function get latitude():Number { | |
return _latitude; | |
} | |
public function set latitude(value:Number):void { | |
_latitude = value; | |
} | |
private var _longitude:Number; | |
public function get longitude():Number { | |
return _longitude; | |
} | |
public function set longitude(value:Number):void { | |
_longitude = value; | |
} | |
private var _altitude:Number; | |
public function get altitude():Number { | |
return _altitude; | |
} | |
public function set altitude(value:Number):void { | |
_altitude = value; | |
} | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ru.yandex.maps.geo { | |
public class GeoUtil { | |
public static const EPS:Number = 1E-7; | |
public static function sign(x:Number, epsilon:Number = EPS):int { | |
if (x < -epsilon) { | |
return -1; | |
} | |
if (x > epsilon) { | |
return 1; | |
} | |
return 0; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ru.yandex.maps.geo { | |
import ru.yandex.utils.math.Range; | |
public class GeoVector { | |
private var _lon1:Number; | |
private var _lat1:Number; | |
private var _lon2:Number; | |
private var _lat2:Number; | |
private var _dLambda:Number; | |
private var _dPhi:Number; | |
private var _distance:Number; | |
private var _sphericalAngularDistance:Number; | |
private var _angularDistance:Number; | |
private var _azimuth:Number; | |
public function GeoVector(p1:GeoPoint, p2:GeoPoint) { | |
_lon1 = p1.longitude; | |
_lat1 = p1.latitude; | |
_lon2 = p2.longitude; | |
_lat2 = p2.latitude; | |
_dLambda = _lon1 - _lon2; | |
_dPhi = _lat1 - _lat2; | |
} | |
public function calculateAzimuth():Number { | |
if (isNaN(_azimuth)) { | |
if (isNaN(_angularDistance)) { | |
calculateAngularDistance(); | |
} | |
_azimuth = _angularDistance; | |
var alpha:Number = Math.abs(_angularDistance); | |
if ((_lat1 <= _lat2) && (_lon1 <= _lon2)) { | |
_azimuth = alpha; | |
} else if ((_lat1 <= _lat2) && (_lon1 >= _lon2)) { | |
_azimuth = (2.0 * Math.PI - alpha); | |
} else if ((_lat1 >= _lat2) && (_lon1 >= _lon2)) { | |
_azimuth = (Math.PI + alpha); | |
} else if ((_lat1 >= _lat2) && (_lon1 <= _lon2)) { | |
_azimuth = (Math.PI - alpha); | |
} | |
/*if (_lat1 > _lat2) { | |
_azimuth += Math.PI; | |
}*/ | |
} | |
return _azimuth; | |
} | |
public function calculateDistance():Number { | |
if (isNaN(_distance)) { | |
var phiMean:Number = (_lat1 + _lat2) * 0.5; | |
var sinPhiMean:Number = Math.sin(phiMean); | |
var temp:Number = 1.0 - WGS84.E2 * sinPhiMean * sinPhiMean; | |
var rho:Number = WGS84.RADIUS * (1.0 - WGS84.E2) / Math.pow(temp, 1.5); | |
var nu:Number = WGS84.RADIUS / Math.sqrt(temp); | |
if (isNaN(_angularDistance)) { | |
calculateAngularDistance(); | |
} | |
var alpha:Number = _angularDistance; | |
var r:Number = rho * nu / ((rho * Math.pow(Math.sin(alpha), 2)) | |
+ (nu * Math.pow(Math.cos(alpha), 2))); | |
_distance = _sphericalAngularDistance * r; | |
} | |
return _distance; | |
} | |
private function calculateAngularDistance():void { | |
var sinPhi:Number = Math.sin(_dPhi * 0.5); | |
var sinLambda:Number = Math.sin(_dLambda * 0.5); | |
var z:Number = Math.sqrt(sinPhi * sinPhi | |
+ Math.cos(_lat1) * Math.cos(_lat2) * sinLambda * sinLambda); | |
_sphericalAngularDistance = 2.0 * Math.asin(z); | |
var alpha:Number = Math.cos(_lat2) * Math.sin(_dLambda) / | |
Math.sin(_sphericalAngularDistance); | |
/* This is a HACK to avoid MAPSCORE-1553! */ | |
alpha = new Range(-1, 1).restrict(alpha); | |
_angularDistance = Math.asin(alpha); | |
} | |
public function get angularDistance():Number { | |
if (isNaN(_angularDistance)) { | |
calculateAngularDistance(); | |
} | |
return _angularDistance; | |
} | |
public function get azimuth():Number { | |
if (isNaN(_azimuth)) { | |
calculateAzimuth(); | |
} | |
return _azimuth; | |
} | |
public function get distance():Number { | |
if (isNaN(_distance)) { | |
calculateDistance(); | |
} | |
return _distance; | |
} | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ru.yandex.maps.pano.engine.math.projections.view { | |
import ru.yandex.maps.pano.engine.core.SphericalCoordinates; | |
import ru.yandex.maps.pano.engine.core.ViewPoint; | |
public class RectilinearProjection implements IViewProjection { | |
public static const projection:IViewProjection = new RectilinearProjection(); | |
public function sphericalToViewport(azimuth:Number, elevation:Number, | |
cameraVector:SphericalCoordinates):ViewPoint { | |
var tmp:Number = Math.cos(elevation) * Math.cos(azimuth - cameraVector.azimuth); | |
var cosC:Number = Math.sin(cameraVector.elevation) * Math.sin(elevation) + | |
Math.cos(cameraVector.elevation) * tmp; | |
var x:Number = Math.cos(elevation) * Math.sin(azimuth - cameraVector.azimuth); | |
var y:Number = Math.cos(cameraVector.elevation) * Math.sin(elevation) - | |
Math.sin(cameraVector.elevation) * tmp; | |
x = x * cameraVector.radius / cosC; | |
y = y * cameraVector.radius / cosC; | |
return new ViewPoint(x, -y, cosC); | |
} | |
public function viewportToSpherical(x:Number, y:Number, | |
cameraVector:SphericalCoordinates):SphericalCoordinates { | |
// phi1 = -phi1; | |
// масштабируем | |
var x1:Number = x / cameraVector.radius; | |
var y1:Number = y / cameraVector.radius; | |
var x2:Number = x1 * x1; | |
var y2:Number = y1 * y1; | |
var q:Number = Math.sqrt(x2 + y2); | |
var c:Number = Math.atan(q); | |
var del:Number = x1 * Math.sin(c); | |
var num:Number = q * Math.cos(cameraVector.elevation) * Math.cos(c) | |
- y1 * Math.sin(cameraVector.elevation) * Math.sin(c); | |
var phi:Number = Math.asin(Math.cos(c) * Math.sin(cameraVector.elevation) + | |
y1 * Math.sin(c) * Math.cos(cameraVector.elevation) / q); | |
var lambda:Number = cameraVector.azimuth + Math.atan2(del, num); | |
return new SphericalCoordinates(lambda, phi); | |
} | |
public function calculatePitch(viewportY:Number, focalLength:Number, | |
pointElevation:Number):Number { | |
return pointElevation - Math.atan(viewportY / focalLength); | |
} | |
public function calculateRadius(viewportDistance:Number, angle:Number):Number { | |
return viewportDistance / Math.tan(angle); | |
} | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ru.yandex.maps.geo { | |
public class WGS84 { | |
/** | |
* Длина большой полуоси | |
*/ | |
public static const RADIUS:Number = 6378137.0; | |
/** | |
* Удвоенный коэффициент сжатия | |
*/ | |
public static const E2:Number = 2 / 298.257223563; | |
public static const AB:Number = 0.00335655146887969400; | |
public static const BB:Number = 0.00000657187271079536; | |
public static const CB:Number = 0.00000001764564338702; | |
public static const DB:Number = 0.00000000005328478445; | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment