osgEarth 2.1.1
|
Functions | |
bool | latLonToFaceCoords (double lat_deg, double lon_deg, double &out_x, double &out_y, int &out_face, int faceHint=-1) |
bool | faceCoordsToLatLon (double x, double y, int face, double &out_lat_deg, double &out_lon_deg) |
bool | cubeToFace (double &in_out_x, double &in_out_y, int &out_face) |
bool | cubeToFace (double &in_out_xmin, double &in_out_ymin, double &in_out_xmax, double &in_out_ymax, int &out_face) |
bool | faceToCube (double &in_out_x, double &in_out_y, int face) |
Vec3d | latLon2xyz (double lat_deg, double lon_deg) |
int | getFace (const Vec3d &vec) |
Vec3d | xyz2qrs (const Vec3d &xyz, int face) |
Vec3d | face2qrs (const Vec2d &face) |
Vec3d | face2ec (int faceNum, const Vec2d &faceCoord) |
The Quadralateralized Spherical Cube.
The cube is layed out like a flattened cut-out. the x,y coordinates range from (0,0) to (4, 3). In the equatorial region, x is 0-4 and y is 1-2. North Pole is (0, 2) ->(1,3); South Pole is (0,0)->(1,1).
Face 0 is centered on lat lon (0, 0). Faces 1-3 are the equatorial faces to the East. 4 is the North Pole, 5 is the South.
Within each face, the conversion formulas assume that coordinate values range from -1 to 1.
bool seamless::qsc::cubeToFace | ( | double & | in_out_x, |
double & | in_out_y, | ||
int & | out_face | ||
) |
Converts cube coordinates (0,0=>4,3) to face coordinates (-1,-1=>1,1,F). WARNING. If the cube coordinate lies on a face boundary, this method will always return the lower-numbered face. The "extent" version of this method (below) is better b/c it's unambiguous.
Definition at line 240 of file QSC.cpp.
{ double x, y; if (in_out_x > 1.0 + 1e-11) { double face = floor(in_out_x); x = in_out_x - face; if (x < 1e-11) { face += -1.0; x += 1.0; } y = in_out_y - 1.0; out_face = static_cast<int>(face); } else { if (in_out_y > 2.0 + 1e-11) { out_face = 4; y = in_out_y - 2.0; } else if (in_out_y < 1.0 + 1e-11) { out_face = 5; y = in_out_y; } else { out_face = 0; y = in_out_y - 1.0; } x = in_out_x; } in_out_x = x * 2.0 - 1.0; in_out_y = y * 2.0 - 1.0; return true; }
bool seamless::qsc::cubeToFace | ( | double & | in_out_xmin, |
double & | in_out_ymin, | ||
double & | in_out_xmax, | ||
double & | in_out_ymax, | ||
int & | out_face | ||
) |
Converts cube coordinates (0,0=>4,3) to face coordinates (-1,-1=>1,1,F). This version takes an extent, which is better than the non-extent version since it can resolve face-border ambiguity.
Definition at line 279 of file QSC.cpp.
{ double xmin, xmax, ymin, ymax; if (in_out_ymin > 1.0 - 1e-11 && in_out_ymax < 2.0 + 1e-11) { double faceMin = floor(in_out_xmin + 1e-11); double faceMax = floor(in_out_xmax - 1e-11); if (faceMin != faceMax) { OE_WARN << LC << "Min face <> Max face!\n"; return false; } xmin = in_out_xmin - faceMin; xmax = in_out_xmax - faceMin; ymin = in_out_ymin - 1.0; ymax = in_out_ymax - 1.0; out_face = static_cast<int>(faceMin); } else if (in_out_ymin > 2.0 - 1e-11 && in_out_ymax > 2.0 + 1e-11) { out_face = 4; ymin = in_out_ymin - 2.0; ymax = in_out_ymax - 2.0; xmin = in_out_xmin; xmax = in_out_xmax; } else if (in_out_ymax < 1.0 + 1e-11) { out_face = 5; ymin = in_out_ymin; ymax = in_out_ymax; xmin = in_out_xmin; xmax = in_out_xmax; } else { OE_WARN << LC << "can't determine face for (" << in_out_xmin << ", " << in_out_ymin << "), (" << in_out_xmax << ", " << in_out_ymax << ")\n"; return false; } in_out_xmin = xmin * 2.0 - 1.0; in_out_xmax = xmax * 2.0 - 1.0; in_out_ymin = ymin * 2.0 - 1.0; in_out_ymax = ymax * 2.0 - 1.0; return true; }
Vec3d seamless::qsc::face2ec | ( | int | faceNum, |
const Vec2d & | faceCoord | ||
) |
Definition at line 204 of file QSC.cpp.
{ Vec3d local = face2qrs(faceCoord); switch (faceNum) { case 0: return Vec3d(local.x(), local.y(), local.z()); break; case 1: return Vec3d(-local.y(), local.x(), local.z()); break; case 2: return Vec3d(-local.x(), -local.y(), local.z()); case 3: return Vec3d(local.y(), -local.x(), local.z()); case 4: return Vec3d(-local.z(),local.y(), local.x()); case 5: return Vec3d(local.z(), local.y(), -local.x()); default: return Vec3d(0,0,0); } }
Vec3d seamless::qsc::face2qrs | ( | const Vec2d & | face | ) |
Definition at line 162 of file QSC.cpp.
{ // formulae assume that x is not less than y. bool swap = false; double x = face.x(), y = face.y(); if (equivalent(x, 0.0, 1e-11) && equivalent(y, 0.0, 1e-11)) return Vec3d(sqrt33, x, y); if (fabs(x) < fabs(y)) { x = face.y(); y = face.x(); swap = true; } const double yOverX = y / x; const double quo = sin(PiOver12 * yOverX) / (cos(PiOver12 * yOverX) - 1 / sqrt2); const double quo2 = quo * quo; const double q = 1 - x * x * (1 - 1 / sqrt(2 + quo2)); const double q2 = q * q; double r2 = (1 - q2) / (1 + quo2); double s2 = 1 - q2 - r2; double r = sqrt(r2); double s = sqrt(s2); Vec3d result; result[0] = q; if (x > 0) result[1] = r; else result[1] = -r; if (y > 0) result[2] = s; else result[2] = -s; if (swap) std::swap(result[1], result[2]); return result; }
bool seamless::qsc::faceCoordsToLatLon | ( | double | x, |
double | y, | ||
int | face, | ||
double & | out_lat_deg, | ||
double & | out_lon_deg | ||
) |
Converts face coordinates into lat/long.
Definition at line 228 of file QSC.cpp.
{ Vec3d geo = face2ec(face, Vec2d(x, y)); const double lon = atan2(geo.y(),geo.x()); const double lat = atan2(geo.z(), sqrt(geo.x() * geo.x() + geo.y() * geo.y())); out_lon_deg = RadiansToDegrees(lon); out_lat_deg = RadiansToDegrees(lat); return true; }
bool seamless::qsc::faceToCube | ( | double & | in_out_x, |
double & | in_out_y, | ||
int | face | ||
) |
Converts face coordinates (-1,-1=>1,1 +F) to cube coordinates (0,0=>4,3).
Definition at line 329 of file QSC.cpp.
{ double x = (in_out_x + 1.0) * .5; double y = (in_out_y + 1.0) * .5; if (face < 4) { in_out_x = x + face; in_out_y = y + 1.0; } else { in_out_x = x; if (face == 4) in_out_y = y + 2.0; else in_out_y = y; } return true; }
int seamless::qsc::getFace | ( | const Vec3d & | vec | ) | [inline] |
Definition at line 61 of file QSC.cpp.
{ double absx = fabs(vec.x()); double absy = fabs(vec.y()); double absz = fabs(vec.z()); // pole faces if (absz > (absx + 1e-11) && absz > (absy + 1e-11)) { if (vec.z() > 0.0) return 4; else return 5; } // One of the X faces, unless on a border else if (absx > absy || equivalent(absx, absy, 1e-11)) { if (vec.x() > 0.0) return 0; else if (equivalent(vec.x(), -vec.y(), 1e-11)) return 1; // Boundary between 1 and 2 else return 2; } // One of the Y faces else { if (vec.y() > 0.0) return 1; else return 3; } }
Vec3d seamless::qsc::latLon2xyz | ( | double | lat_deg, |
double | lon_deg | ||
) | [inline] |
bool seamless::qsc::latLonToFaceCoords | ( | double | lat_deg, |
double | lon_deg, | ||
double & | out_x, | ||
double & | out_y, | ||
int & | out_face, | ||
int | faceHint = -1 |
||
) |
Definition at line 118 of file QSC.cpp.
{ if (lat_deg > 90.0 || lat_deg < -90.0 || lon_deg < -180.0 || lon_deg > 180.0) return false; Vec3d xyz = latLon2xyz(lat_deg, lon_deg); out_face = faceHint >= 0 ? faceHint : getFace(xyz); Vec3d qrs = xyz2qrs(xyz, out_face); if (equivalent(qrs[1], 0.0, 1e-11) && equivalent(qrs[1], 0.0, 1e-11)) { out_x = qrs[1]; out_y = qrs[2]; return true; } bool swap = false; if (fabs(qrs[1]) < fabs(qrs[2])) { std::swap(qrs[1], qrs[2]); swap = true; } double sOverR = qrs[2] / qrs[1]; double x = sqrt((1 - qrs[0])/(1 - 1/sqrt(2 + sOverR * sOverR))); double y = x * (PiOver12Inv * atan(sOverR) - asin(qrs[2] / sqrt(2.0 * (qrs[1] * qrs[1] + qrs[2] * qrs[2])))); if (qrs[1] < 0.0) x = -x; if (qrs[2] < 0.0) y = -y; if (swap) { out_x = y; out_y = x; } else { out_x = x; out_y = y; } return true; }
Vec3d seamless::qsc::xyz2qrs | ( | const Vec3d & | xyz, |
int | face | ||
) |
Definition at line 97 of file QSC.cpp.
{ switch (face) { case 0: return Vec3d(xyz.x(), xyz.y(), xyz.z()); case 1: return Vec3d(xyz.y(), -xyz.x(), xyz.z()); case 2: return Vec3d(-xyz.x(), -xyz.y(), xyz.z()); case 3: return Vec3d(-xyz.y(), xyz.x(), xyz.z()); case 4: return Vec3d(xyz.z(), xyz.y(), -xyz.x()); case 5: return Vec3d(-xyz.z(), xyz.y(), xyz.x()); default: return Vec3d(0, 0, 0); } }