osgEarth 2.1.1
Functions

seamless::qsc Namespace Reference

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)

Detailed Description

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.


Function Documentation

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);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

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;
}

Here is the call graph for this function:

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]

Definition at line 49 of file QSC.cpp.

{
    Vec3d result;
    result.z() = sin(DegreesToRadians(lat_deg));
    double hyp = sqrt(1 - result.z() * result.z());
    double long_rad = DegreesToRadians(lon_deg);
    result.x() = hyp * cos(long_rad);
    result.y() = hyp * sin(long_rad);
    return result;
}
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;
}

Here is the call graph for this function:

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);
    }
}
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines