1 /***************************************
  2  * Copyright 2011, 2012 GlobWeb contributors.
  3  *
  4  * This file is part of GlobWeb.
  5  *
  6  * GlobWeb is free software: you can redistribute it and/or modify
  7  * it under the terms of the GNU Lesser General Public License as published by
  8  * the Free Software Foundation, version 3 of the License, or
  9  * (at your option) any later version.
 10  *
 11  * GlobWeb is distributed in the hope that it will be useful,
 12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 14  * GNU Lesser General Public License for more details.
 15  *
 16  * You should have received a copy of the GNU General Public License
 17  * along with GlobWeb. If not, see <http://www.gnu.org/licenses/>.
 18  ***************************************/
 19 
 20 define( ['./Numeric' ], function(Numeric) {
 21  
 22 var CoordinateSystem = { radius: 1.0, heightScale: 1.0 / 6356752.3142, realEarthRadius: 6356752.3142  };
 23 
 24 /**************************************************************************************************************/
 25 
 26 /*
 27 	Convert a geographic position to 3D
 28  */
 29 CoordinateSystem.fromGeoTo3D = function(geo, dest)
 30 {
 31     if (!dest) { dest = new Array(3); }
 32 
 33 	var longInRad = Numeric.toRadian(geo[0]);
 34 	var latInRad = Numeric.toRadian(geo[1]);
 35 	var cosLat = Math.cos(latInRad);
 36 	
 37 	// Take height into account
 38 	var height = geo.length > 2 ? CoordinateSystem.heightScale * geo[2] : 0;
 39 	var radius = CoordinateSystem.radius + height;
 40 
 41     dest[0] = radius * Math.cos(longInRad) * cosLat;
 42     dest[1] = radius * Math.sin(longInRad) * cosLat;
 43     dest[2] = radius * Math.sin(latInRad);
 44 
 45     return dest;
 46 }
 47 
 48 /**************************************************************************************************************/
 49 
 50 /*
 51 	Convert a 3D position to geographic
 52     Returns 3 values [long, lat, distance from earth surface]
 53  */
 54 CoordinateSystem.from3DToGeo = function(position3d, dest)
 55 {
 56     if (!dest) { dest = new Array(3); }
 57 
 58     var r = Math.sqrt(position3d[0]*position3d[0] +
 59                       position3d[1]*position3d[1] +
 60                       position3d[2]*position3d[2]);
 61     var lon = Math.atan2(position3d[1] / r, position3d[0] / r);
 62     var lat = Math.asin(position3d[2] / r);
 63 
 64     dest[0] = Numeric.toDegree(lon);
 65     dest[1] = Numeric.toDegree(lat);
 66     dest[2] = CoordinateSystem.realEarthRadius * (r - CoordinateSystem.radius);
 67 
 68     return dest;
 69 }
 70 
 71 /**************************************************************************************************************/
 72 
 73 /*
 74 	Get local transformation
 75  */
 76 CoordinateSystem.getLocalTransform = function(geo, dest)
 77 {
 78     if (!dest) { dest = mat4.create(); }
 79 
 80 	var longitude = geo[0] * Math.PI / 180.0;
 81 	var latitude = geo[1] * Math.PI / 180.0;
 82 	
 83 	var up = [  Math.cos(longitude)*Math.cos(latitude), Math.sin(longitude)*Math.cos(latitude), Math.sin(latitude) ];
 84 	var east = [ -Math.sin(longitude), Math.cos(longitude), 0 ];
 85 	var north = vec3.create();
 86 	vec3.cross( up, east, north );
 87 	
 88 	dest[0] = east[0];
 89 	dest[1] = east[1];
 90 	dest[2] = east[2];
 91 	dest[3] = 0.0;
 92 		
 93 	dest[4] = north[0];
 94 	dest[5] = north[1];
 95 	dest[6] = north[2];
 96 	dest[7] = 0.0;
 97 		
 98 	dest[8] = up[0];
 99 	dest[9] = up[1];
100 	dest[10] = up[2];
101 	dest[11] = 0.0;
102 
103 	dest[12] = 0.0;
104 	dest[13] = 0.0;
105 	dest[14] = 0.0;
106 	dest[15] = 1.0;
107 
108 	return dest;
109 }
110 
111 /**************************************************************************************************************/
112 
113 /*
114 	Get local transformation
115  */
116 CoordinateSystem.getLHVTransform = function(geo, dest)
117 {
118     if (!dest) { dest = mat4.create(); }
119 
120 	var longitude = geo[0] * Math.PI / 180.0;
121 	var latitude = geo[1] * Math.PI / 180.0;
122 	
123 	var up = [  Math.cos(longitude)*Math.cos(latitude), Math.sin(longitude)*Math.cos(latitude), Math.sin(latitude) ];
124 	var east = [ -Math.sin(longitude), Math.cos(longitude), 0 ];
125 	var north = vec3.create();
126 	vec3.cross( up, east, north );
127 	
128 	var pt = CoordinateSystem.fromGeoTo3D(geo);
129 	
130 	dest[0] = east[0];
131 	dest[1] = east[1];
132 	dest[2] = east[2];
133 	dest[3] = 0.0;
134 		
135 	dest[4] = north[0];
136 	dest[5] = north[1];
137 	dest[6] = north[2];
138 	dest[7] = 0.0;
139 		
140 	dest[8] = up[0];
141 	dest[9] = up[1];
142 	dest[10] = up[2];
143 	dest[11] = 0.0;
144 
145 	dest[12] = pt[0];
146 	dest[13] = pt[1];
147 	dest[14] = pt[2];
148 	dest[15] = 1.0;
149 
150 	return dest;
151 }
152 
153 /**************************************************************************************************************/
154 
155 /*
156 	Get the side (i.e. X) vector from a local transformation
157  */
158 CoordinateSystem.getSideVector = function( matrix, v )
159 {
160 	v[0] = matrix[0];
161 	v[1] = matrix[1];
162 	v[2] = matrix[2];
163 	
164     return v;
165 }
166 
167 /**************************************************************************************************************/
168 
169 /*
170 	Get the front (i.e. Y) vector from a local transformation
171  */
172 CoordinateSystem.getFrontVector = function( matrix, v )
173 {
174 	v[0] = matrix[4];
175 	v[1] = matrix[5];
176 	v[2] = matrix[6];
177 	
178     return v;
179 }
180 
181 /**************************************************************************************************************/
182 
183 /*
184 	Get the up (i.e. Z) vector from a local transformation
185  */
186 CoordinateSystem.getUpVector = function( matrix, v )
187 {
188 	v[0] = matrix[8];
189 	v[1] = matrix[9];
190 	v[2] = matrix[10];
191 	
192     return v;
193 }
194 
195 /**************************************************************************************************************/
196 
197 return CoordinateSystem;
198 
199 });