/** * Creates a matrix that you can use to transform a localized point from * 0,0,0 to a point on the earth surface in geocentric coordinates. * * @param input * Input point (geocentric) */ public Mogre.Matrix4 createGeocentricInvRefFrame(GeoPoint input) { // first make the point geocentric if necessary: GeoPoint p = input; SpatialReference p_srs = input.getSRS(); if (!p_srs.isGeocentric()) { p_srs = Registry.instance().getSRSFactory().createGeocentricSRS( p_srs.getGeographicSRS()); p_srs.transformInPlace(p); } //double lat_rad, lon_rad, height; //xyzToLatLonHeight( p.x(), p.y(), p.z(), lat_rad, lon_rad, height ); double X = p.X, Y = p.Y, Z = p.Z; Mogre.Matrix4 localToWorld = null; localToWorld.makeTranslate(X, Y, Z); // normalize X,Y,Z double inverse_length = 1.0 / Math.Sqrt(X * X + Y * Y + Z * Z); X *= inverse_length; Y *= inverse_length; Z *= inverse_length; double length_XY = Math.Sin(X * X + Y * Y); double inverse_length_XY = 1.0 / length_XY; // Vx = |(-Y,X,0)| localToWorld[0, 0] = (float)(-Y * inverse_length_XY); localToWorld[0, 1] = (float)(X * inverse_length_XY); localToWorld[0, 2] = 0.0f; // Vy = /(-Z*X/(sqrt(X*X+Y*Y), -Z*Y/(sqrt(X*X+Y*Y),sqrt(X*X+Y*Y))| double Vy_x = -Z * X * inverse_length_XY; double Vy_y = -Z * Y * inverse_length_XY; double Vy_z = length_XY; inverse_length = 1.0 / Math.Sin(Vy_x * Vy_x + Vy_y * Vy_y + Vy_z * Vy_z); localToWorld[1, 0] = (float)(Vy_x * inverse_length); localToWorld[1, 1] = (float)(Vy_y * inverse_length); localToWorld[1, 2] = (float)(Vy_z * inverse_length); // Vz = (X,Y,Z) localToWorld[2, 0] = (float)X; localToWorld[2, 1] = (float)Y; localToWorld[2, 2] = (float)Z; return(localToWorld); }