20 SurfacePoint::SurfacePoint() {
30 p_localRadius = other.p_localRadius;
54 p_rectCovar =
new symmetric_matrix<double, upper>(*other.
p_rectCovar);
61 p_sphereCovar =
new symmetric_matrix<double, upper>(*other.
p_sphereCovar);
80 SetSphericalPoint(lat, lon, radius);
104 SetSpherical(lat, lon, radius, latSigma, lonSigma, radiusSigma);
114 const Distance &radius,
const symmetric_matrix<double, upper> &covar) {
117 SetSpherical(lat, lon, radius, covar);
132 SetRectangular(x, y, z);
155 SetRectangular(x, y, z, xSigma, ySigma, zSigma);
169 const Displacement &z,
const symmetric_matrix<double, upper> &covar) {
172 SetRectangular(x, y, z, covar);
180 SurfacePoint::~SurfacePoint() {
181 FreeAllocatedMemory();
189 void SurfacePoint::InitCovariance() {
191 p_sphereCovar = NULL;
199 void SurfacePoint::InitPoint() {
223 IString msg =
"x, y, and z must be set to valid displacements. One or " 224 "more coordinates have been set to an invalid displacement.";
256 if (!p_localRadius.isValid()) {
257 ComputeLocalRadius();
258 p_localRadius = GetLocalRadius();
284 SetRectangularPoint(x, y, z);
287 SetRectangularSigmas(xSigma, ySigma, zSigma);
303 const symmetric_matrix<double,upper>& covar) {
307 SetRectangularPoint(x, y, z);
308 SetRectangularMatrix(covar);
327 SetRectangularPoint(x, y, z);
344 void SurfacePoint::SetRectangularSigmas(
const Distance &xSigma,
348 IString msg =
"x sigma, y sigma , and z sigma must be set to valid " 349 "distances. One or more sigmas have been set to an invalid distance.";
353 symmetric_matrix<double,upper> covar(3);
358 SetRectangularMatrix(covar, Meters);
370 void SurfacePoint::SetRectangularMatrix(
const symmetric_matrix<double, upper> &covar,
371 SurfacePoint::CoordUnits units) {
375 IString msg =
"A point must be set before a variance/covariance matrix " 381 if (units != Kilometers && units != Meters) {
382 IString msg =
"Units must be Kilometers or Meters";
388 *p_rectCovar = covar;
391 p_rectCovar =
new symmetric_matrix<double, upper>(covar);
394 if (units == Meters) {
396 (*p_rectCovar)(0,0) = covar(0,0)/1.0e6;
397 (*p_rectCovar)(0,1) = covar(0,1)/1.0e6;
398 (*p_rectCovar)(0,2) = covar(0,2)/1.0e6;
399 (*p_rectCovar)(1,1) = covar(1,1)/1.0e6;
400 (*p_rectCovar)(1,2) = covar(1,2)/1.0e6;
401 (*p_rectCovar)(2,2) = covar(2,2)/1.0e6;
404 SpiceDouble rectMat[3][3];
407 double x2 = p_x->meters() * p_x->meters();
408 double y2 = p_y->meters() * p_y->meters();
409 double z = p_z->meters();
410 double radius = sqrt(x2 + y2 + z*z);
413 rectMat[0][0] = covar(0,0);
414 rectMat[0][1] = rectMat[1][0] = covar(0,1);
415 rectMat[0][2] = rectMat[2][0] = covar(0,2);
416 rectMat[1][1] = covar(1,1);
417 rectMat[1][2] = rectMat[2][1] = covar(1,2);
418 rectMat[2][2] = covar(2,2);
422 double zOverR = p_z->meters() / radius;
423 double r2 = radius*radius;
424 double denom = r2*radius*sqrt(1.0 - (zOverR*zOverR));
425 J[0][0] = -p_x->meters() * p_z->meters() / denom;
426 J[0][1] = -p_y->meters() * p_z->meters() / denom;
427 J[0][2] = (r2 - p_z->meters() * p_z->meters()) / denom;
428 J[1][0] = -p_y->meters() / (x2 + y2);
429 J[1][1] = p_x->meters() / (x2 + y2);
431 J[2][0] = p_x->meters() / radius;
432 J[2][1] = p_y->meters() / radius;
433 J[2][2] = p_z->meters() / radius;
436 p_sphereCovar =
new symmetric_matrix<double, upper>(3);
438 SpiceDouble mat[3][3];
439 mxm_c (J, rectMat, mat);
440 mxmt_c (mat, J, mat);
441 if (units == Kilometers) {
443 (*p_sphereCovar)(0,0) = mat[0][0] * 1.0e6;
444 (*p_sphereCovar)(0,1) = mat[0][1] * 1.0e6;
445 (*p_sphereCovar)(0,2) = mat[0][2] * 1000.0;
446 (*p_sphereCovar)(1,1) = mat[1][1] * 1.0e6;
448 (*p_sphereCovar)(1,2) = mat[1][2] * 1000.0;
449 (*p_sphereCovar)(2,2) = mat[2][2];
453 (*p_sphereCovar)(0,0) = mat[0][0];
454 (*p_sphereCovar)(0,1) = mat[0][1];
455 (*p_sphereCovar)(0,2) = mat[0][2] / 1000.0;
456 (*p_sphereCovar)(1,1) = mat[1][1];
457 (*p_sphereCovar)(1,2) = mat[1][2] / 1000.0;
458 (*p_sphereCovar)(2,2) = mat[2][2] / 1.0e6;
474 void SurfacePoint::SetSphericalPoint(
const Latitude &lat,
479 IString msg =
"Latitude, longitude, or radius is an invalid value.";
483 SpiceDouble dlat = (double) lat.
radians();
484 SpiceDouble dlon = (double) lon.
radians();
488 latrec_c ( dradius, dlon, dlat, rect);
491 p_localRadius = radius;
493 SetRectangularPoint(
Displacement(rect[0], Displacement::Kilometers),
516 SetSphericalPoint(lat, lon, radius);
519 SetSphericalSigmas(latSigma, lonSigma, radiusSigma);
533 const Distance &radius,
const symmetric_matrix<double, upper> &covar) {
534 SetSphericalPoint(lat, lon, radius);
535 SetSphericalMatrix(covar);
547 void SurfacePoint::SetSphericalCoordinates(
const Latitude &lat,
549 SetSphericalPoint(lat, lon, radius);
567 void SurfacePoint::SetSphericalSigmas(
const Angle &latSigma,
568 const Angle &lonSigma,
571 symmetric_matrix<double,upper> covar(3);
574 double sphericalCoordinate;
575 sphericalCoordinate = (double) latSigma.
radians();
576 covar(0,0) = sphericalCoordinate*sphericalCoordinate;
577 sphericalCoordinate = (double) lonSigma.
radians();
578 covar(1,1) = sphericalCoordinate*sphericalCoordinate;
579 sphericalCoordinate = (double) radiusSigma.
meters();
580 covar(2,2) = sphericalCoordinate*sphericalCoordinate;
583 SetSphericalMatrix(covar);
586 delete p_sphereCovar;
587 p_sphereCovar = NULL;
611 void SurfacePoint::SetSphericalSigmasDistance(
const Distance &latSigma,
615 IString msg =
"Cannot set spherical sigmas on an invalid surface point";
619 SetSphericalSigmas(
Angle(MetersToLatitude(latSigma.
meters()),Angle::Radians),
620 Angle(MetersToLongitude(lonSigma.
meters()), Angle::Radians), radiusSigma);
631 void SurfacePoint::SetSphericalMatrix(
632 const symmetric_matrix<double, upper> & covar,
633 SurfacePoint::CoordUnits units) {
637 IString msg =
"A point must be set before a variance/covariance matrix " 643 if (units != Kilometers && units != Meters) {
644 IString msg =
"Units must be Kilometers or Meters";
649 double radius = (double) GetLocalRadius().kilometers();
653 *p_sphereCovar = covar;
656 p_sphereCovar =
new symmetric_matrix<double, upper>(covar);
659 if (units == Meters) {
661 (*p_sphereCovar)(0,0) = covar(0,0);
662 (*p_sphereCovar)(0,1) = covar(0,1);
663 (*p_sphereCovar)(0,2) = covar(0,2) / 1000.;
664 (*p_sphereCovar)(1,1) = covar(1,1);
665 (*p_sphereCovar)(1,2) = covar(1,2) / 1000.;
666 (*p_sphereCovar)(2,2) = covar(2,2) / 1.0e6;
667 radius = (double) GetLocalRadius().meters();
671 SpiceDouble sphereMat[3][3];
673 sphereMat[0][0] = covar(0,0);
674 sphereMat[0][1] = sphereMat[1][0] = covar(0,1);
675 sphereMat[0][2] = sphereMat[2][0] = covar(0,2);
676 sphereMat[1][1] = covar(1,1);
677 sphereMat[1][2] = sphereMat[2][1] = covar(1,2);
678 sphereMat[2][2] = covar(2,2);
685 double lat = (double) GetLatitude().radians();
686 double lon = (double) GetLongitude().radians();
690 double cosPhi = cos(lat);
691 double sinPhi = sin(lat);
692 double cosLamda = cos(lon);
693 double sinLamda = sin(lon);
694 double rcosPhi = radius*cosPhi;
695 double rsinPhi = radius*sinPhi;
696 J[0][0] = -rsinPhi * cosLamda;
697 J[0][1] = -rcosPhi * sinLamda;
698 J[0][2] = cosPhi * cosLamda;
699 J[1][0] = -rsinPhi * sinLamda;
700 J[1][1] = rcosPhi * cosLamda;
701 J[1][2] = cosPhi * sinLamda;
707 p_rectCovar =
new symmetric_matrix<double, upper>(3);
709 SpiceDouble mat[3][3];
710 mxm_c (J, sphereMat, mat);
711 mxmt_c (mat, J, mat);
713 if (units == Kilometers) {
714 (*p_rectCovar)(0,0) = mat[0][0];
715 (*p_rectCovar)(0,1) = mat[0][1];
716 (*p_rectCovar)(0,2) = mat[0][2];
717 (*p_rectCovar)(1,1) = mat[1][1];
718 (*p_rectCovar)(1,2) = mat[1][2];
719 (*p_rectCovar)(2,2) = mat[2][2];
723 (*p_rectCovar)(0,0) = mat[0][0]/1.0e6;
724 (*p_rectCovar)(0,1) = mat[0][1]/1.0e6;
725 (*p_rectCovar)(0,2) = mat[0][2]/1.0e6;
726 (*p_rectCovar)(1,1) = mat[1][1]/1.0e6;
727 (*p_rectCovar)(1,2) = mat[1][2]/1.0e6;
728 (*p_rectCovar)(2,2) = mat[2][2]/1.0e6;
743 void SurfacePoint::SetMatrix(
CoordinateType type,
const symmetric_matrix<double, upper>& covar) {
747 SetSphericalMatrix(covar, SurfacePoint::Kilometers);
750 SetRectangularMatrix(covar, SurfacePoint::Kilometers);
753 IString msg =
"Unknown surface point coordinate type enum [" +
toString(type) +
"]." ;
767 std::vector<double> SurfacePoint::Partial(
CoordinateType type, CoordIndex index) {
768 std::vector<double> derivative(3);
771 derivative = LatitudinalDerivative(index);
774 derivative = RectangularDerivative(index);
777 IString msg =
"Unknown surface point coordinate type enum [" +
toString(type) +
"]." ;
792 std::vector<double> SurfacePoint::LatitudinalDerivative(CoordIndex index) {
793 std::vector<double> derivative(3);
794 double rlat = GetLatitude().radians();
795 double rlon = GetLongitude().radians();
796 double sinLon = sin(rlon);
797 double cosLon = cos(rlon);
798 double sinLat = sin(rlat);
799 double cosLat = cos(rlat);
800 double radkm = GetLocalRadius().kilometers();
804 derivative[0] = -radkm * sinLat * cosLon;
805 derivative[1] = -radkm * sinLon * sinLat;
806 derivative[2] = radkm * cosLat;
809 derivative[0] = -radkm * cosLat * sinLon;
810 derivative[1] = radkm * cosLat * cosLon;
814 derivative[0] = cosLon * cosLat;
815 derivative[1] = sinLon * cosLat;
816 derivative[2] = sinLat;
819 IString msg =
"Invalid coordinate index (must be less than 3).";
834 std::vector<double> SurfacePoint::RectangularDerivative(CoordIndex index) {
835 std::vector<double> derivative(3,0.0);
848 IString msg =
"Invalid coordinate index (must be less than 3).";
864 void SurfacePoint::ToNaifArray(
double naifOutput[3])
const {
866 naifOutput[0] = p_x->kilometers();
867 naifOutput[1] = p_y->kilometers();
868 naifOutput[2] = p_z->kilometers();
871 IString msg =
"Cannot convert an invalid surface point to a naif array";
885 void SurfacePoint::FromNaifArray(
const double naifValues[3]) {
886 if(p_x && p_y && p_z) {
887 p_x->setKilometers(naifValues[0]);
888 p_y->setKilometers(naifValues[1]);
889 p_z->setKilometers(naifValues[2]);
892 p_x =
new Displacement(naifValues[0], Displacement::Kilometers);
893 p_y =
new Displacement(naifValues[1], Displacement::Kilometers);
894 p_z =
new Displacement(naifValues[2], Displacement::Kilometers);
897 ComputeLocalRadius();
898 p_localRadius = GetLocalRadius();
908 void SurfacePoint::ResetLocalRadius(
const Distance &radius) {
911 IString msg =
"Radius value must be a valid Distance.";
915 if (!p_x || !p_y || !p_z || !p_x->isValid() || !p_y->isValid() ||
917 IString msg =
"In order to reset the local radius, a Surface Point must " 923 SpiceDouble lat = (double) GetLatitude().radians();
924 SpiceDouble lon = (double) GetLongitude().radians();
926 p_localRadius = radius;
930 latrec_c ((SpiceDouble) radius.
kilometers(), lon, lat, rect);
932 p_y->setKilometers(rect[1]);
933 p_z->setKilometers(rect[2]);
941 bool SurfacePoint::Valid()
const {
942 static const Displacement zero(0, Displacement::Meters);
943 return p_x && p_y && p_z && p_x->isValid() && p_y->isValid() && p_z->isValid() &&
944 (*p_x != zero || *p_y != zero || *p_z != zero);
956 double SurfacePoint::GetCoord(
CoordinateType type, CoordIndex index, CoordUnits units) {
968 value = LatToDouble(GetLatitude(), units);
972 value = LonToDouble(GetLongitude(), units);
976 value = DistanceToDouble(GetLocalRadius(), units);
980 IString msg =
"Invalid coordinate index (must be less than 3).";
990 value = DisplacementToDouble(GetX(), units);
994 value = DisplacementToDouble(GetY(), units);
998 value = DisplacementToDouble(GetZ(), units);
1002 IString msg =
"Invalid coordinate index enum (must be less than 3).";
1008 IString msg =
"Unknown surface point coordinate type enum [" +
toString(type) +
"]." ;
1023 double SurfacePoint::GetSigma(
CoordinateType type, CoordIndex index, CoordUnits units) {
1033 value = DistanceToDouble(GetLatSigmaDistance(), units);
1037 value = DistanceToDouble(GetLonSigmaDistance(), units);
1041 value = DistanceToDouble(GetLocalRadiusSigma(), units);
1045 IString msg =
"Invalid coordinate index (must be less than 3).";
1055 value = DistanceToDouble(GetXSigma(), units);
1059 value = DistanceToDouble(GetYSigma(), units);
1063 value = DistanceToDouble(GetZSigma(), units);
1067 IString msg =
"Invalid coordinate index (must be less than 3).";
1073 IString msg =
"Unknown surface point coordinate type enum [" +
toString(type) +
"]." ;
1099 dist = GetLatSigmaDistance();
1103 dist = GetLonSigmaDistance();
1107 dist = GetLocalRadiusSigma();
1111 IString msg =
"Invalid coordinate index (must be less than 3).";
1133 IString msg =
"Invalid coordinate index (must be less than 3).";
1139 IString msg =
"Unknown surface point coordinate type enum [" +
toString(type) +
"]." ;
1154 double SurfacePoint::DisplacementToDouble(
Displacement disp, CoordUnits units) {
1168 IString msg =
"Unrecognized unit for a Displacement (must be meters or kilometers).";
1182 double SurfacePoint::DistanceToDouble(
Distance dist, CoordUnits units) {
1196 IString msg =
"Unrecognized unit for a Distance (not meters or kilometers).";
1210 double SurfacePoint::LatToDouble(
Latitude lat, CoordUnits units) {
1216 value = GetLatitude().radians();
1220 value = GetLatitude().degrees();
1224 IString msg =
"Invalid unit for latitude (must be Radians or Degrees).";
1242 double SurfacePoint::MetersToLatitude(
double latLength) {
1245 return latLength / GetLocalRadius().meters();
1270 double SurfacePoint::MetersToLongitude(
double deltaLonMeters) {
1272 if (Valid() && !
IsSpecial(deltaLonMeters)) {
1273 double convFactor = cos((
double)GetLatitude().radians());
1274 double deltaLonRadians;
1277 if (convFactor > 1.0e-50) {
1278 deltaLonRadians = deltaLonMeters / (convFactor*GetLocalRadius().meters());
1282 deltaLonRadians =
PI;
1284 return deltaLonRadians;
1304 double SurfacePoint::LatitudeToMeters(
double relativeLat)
const {
1306 if (relativeLat == 0.) {
1309 else if (Valid() && !
IsSpecial(relativeLat) && GetLocalRadius().isValid() ) {
1310 return relativeLat * GetLocalRadius().meters();
1330 double SurfacePoint::LongitudeToMeters(
double deltaLonRadians)
const{
1334 if (deltaLonRadians == 0.) {
1335 deltaLonMeters = 0.;
1337 else if (Valid() && !
IsSpecial(deltaLonRadians) && GetLocalRadius().isValid() ) {
1339 double scalingRadius = cos(GetLatitude().radians()) * GetLocalRadius().meters();
1340 deltaLonMeters = deltaLonRadians * scalingRadius;
1343 return deltaLonMeters;
1357 SurfacePoint::stringToCoordinateType(QString type) {
1358 if (type.compare(
"LATITUDINAL", Qt::CaseInsensitive) == 0) {
1359 return SurfacePoint::Latitudinal;
1361 else if (type.compare(
"RECTANGULAR", Qt::CaseInsensitive) == 0) {
1362 return SurfacePoint::Rectangular;
1366 "Unknown coordinate type for a SurfacePoint [" + type +
"].",
1383 QString SurfacePoint::coordinateTypeToString(
1388 return "Latitudinal";
1392 return "Rectangular";
1396 IString msg =
"Unknown surface point coordinate type enum [" +
toString(type) +
"]." ;
1409 double SurfacePoint::LonToDouble(
Longitude lon, CoordUnits units) {
1415 value = GetLongitude().radians();
1419 value = GetLongitude().degrees();
1423 IString msg =
"Invalid unit for longitude (must be Radians of Degrees).";
1437 Displacement SurfacePoint::GetY()
const {
1438 if(!p_y)
return Displacement();
1444 Displacement SurfacePoint::GetZ()
const {
1445 if(!p_z)
return Displacement();
1451 Distance SurfacePoint::GetXSigma()
const {
1452 if(!p_rectCovar)
return Distance();
1454 return Distance(sqrt((*p_rectCovar)(0, 0)), Distance::Kilometers);
1458 Distance SurfacePoint::GetYSigma()
const {
1459 if(!p_rectCovar)
return Distance();
1461 return Distance(sqrt((*p_rectCovar)(1, 1)), Distance::Kilometers);
1465 Distance SurfacePoint::GetZSigma()
const {
1466 if(!p_rectCovar)
return Distance();
1468 return Distance(sqrt((*p_rectCovar)(2, 2)), Distance::Kilometers);
1495 value = GetLatWeight();
1499 value = GetLonWeight();
1503 value = GetLocalRadiusWeight();
1507 IString msg =
"Invalid coordinate index (must be less than 3).";
1517 value = GetXWeight();
1521 value = GetYWeight();
1525 value = GetZWeight();
1529 IString msg =
"Invalid coordinate index (must be less than 3).";
1535 IString msg =
"Unknown surface point coordinate type enum [" +
toString(type) +
"]." ;
1547 double SurfacePoint::GetXWeight()
const {
1549 double dXSigma = GetXSigma().kilometers();
1551 if (dXSigma <= 0.0 ) {
1552 IString msg =
"SurfacePoint::GetXWeight(): Sigma <= 0.0";
1556 return 1.0/(dXSigma*dXSigma);
1565 double SurfacePoint::GetYWeight()
const {
1567 double dYSigma = GetYSigma().kilometers();
1569 if (dYSigma <= 0.0 ) {
1570 IString msg =
"SurfacePoint::GetYWeight(): Sigma <= 0.0";
1574 return 1.0/(dYSigma*dYSigma);
1583 double SurfacePoint::GetZWeight()
const {
1585 double dZSigma = GetZSigma().kilometers();
1587 if (dZSigma <= 0.0 ) {
1588 IString msg =
"SurfacePoint::GetZWeight(): Sigma <= 0.0";
1592 return 1.0/(dZSigma*dZSigma);
1596 symmetric_matrix<double, upper> SurfacePoint::GetRectangularMatrix
1597 (SurfacePoint::CoordUnits units)
const {
1599 symmetric_matrix<double, upper> tmp(3);
1605 if (units != Kilometers && units != Meters) {
1606 IString msg =
"Units must be Kilometers or Meters";
1607 throw IException(IException::Programmer, msg,
_FILEINFO_);
1610 symmetric_matrix<double, upper> covar(3);
1617 covar(0,0) = (*p_rectCovar)(0,0)*1.0e6;
1618 covar(0,1) = (*p_rectCovar)(0,1)*1.0e6;
1619 covar(0,2) = (*p_rectCovar)(0,2)*1.0e6;
1620 covar(1,1) = (*p_rectCovar)(1,1)*1.0e6;
1621 covar(1,2) = (*p_rectCovar)(1,2)*1.0e6;
1622 covar(2,2) = (*p_rectCovar)(2,2)*1.0e6;
1627 return *p_rectCovar;
1631 IString msg =
"Unrecognized unit for a Displacement (must be meters or kilometers).";
1632 throw IException(IException::Programmer, msg,
_FILEINFO_);
1635 return *p_rectCovar;
1639 Angle SurfacePoint::GetLatSigma()
const {
1643 return Angle(sqrt((*p_sphereCovar)(0, 0)), Angle::Radians);
1647 Angle SurfacePoint::GetLonSigma()
const {
1651 return Angle(sqrt((*p_sphereCovar)(1, 1)), Angle::Radians);
1664 double x = p_x->meters();
1665 double y = p_y->meters();
1666 double z = p_z->meters();
1668 if (x != 0. || y != 0. || z != 0.)
1669 return Latitude(atan2(z, sqrt(x*x + y*y) ), Angle::Radians);
1683 double x = p_x->meters();
1684 double y = p_y->meters();
1686 if(x == 0.0 && y == 0.0) {
1690 double lon = atan2(y, x);
1703 void SurfacePoint::ComputeLocalRadius() {
1704 static const Displacement zero(0, Displacement::Meters);
1706 double x = p_x->meters();
1707 double y = p_y->meters();
1708 double z = p_z->meters();
1710 p_localRadius =
Distance(sqrt(x*x + y*y + z*z), Distance::Meters);
1712 else if (*p_x == zero && *p_y == zero && *p_z == zero) {
1713 p_localRadius =
Distance(0., Distance::Meters);
1716 IString msg =
"SurfacePoint::Can't compute local radius on invalid point";
1727 return p_localRadius;
1742 double d = LatitudeToMeters(GetLatSigma().radians());
1745 return Distance(d, Distance::Meters);
1759 double d = LongitudeToMeters(GetLonSigma().radians());
1762 return Distance(d, Distance::Meters);
1770 Distance SurfacePoint::GetLocalRadiusSigma()
const {
1774 return Distance(sqrt((*p_sphereCovar)(2, 2)), Distance::Kilometers);
1778 symmetric_matrix<double, upper> SurfacePoint::GetSphericalMatrix
1779 (SurfacePoint::CoordUnits units)
const {
1780 if(!p_sphereCovar) {
1781 symmetric_matrix<double, upper> tmp(3);
1787 if (units != Kilometers && units != Meters) {
1788 IString msg =
"Units must be Kilometers or Meters";
1789 throw IException(IException::Programmer, msg,
_FILEINFO_);
1792 symmetric_matrix<double, upper> covar(3);
1799 covar(0,0) = (*p_sphereCovar)(0,0);
1800 covar(0,1) = (*p_sphereCovar)(0,1);
1801 covar(0,2) = (*p_sphereCovar)(0,2)*1000.;
1802 covar(1,1) = (*p_sphereCovar)(1,1);
1803 covar(1,2) = (*p_sphereCovar)(1,2)*1000.;
1804 covar(2,2) = (*p_sphereCovar)(2,2)*1.0e6;
1809 return *p_sphereCovar;
1813 IString msg =
"Unrecognized unit for a Displacement (must be meters or kilometers).";
1814 throw IException(IException::Programmer, msg,
_FILEINFO_);
1817 return *p_sphereCovar;
1826 double SurfacePoint::GetLatWeight()
const {
1827 double dlatSigma = GetLatSigma().radians();
1829 if( dlatSigma <= 0.0 ) {
1830 IString msg =
"SurfacePoint::GetLatWeight(): Sigma <= 0.0";
1834 return 1.0/(dlatSigma*dlatSigma);
1842 double SurfacePoint::GetLonWeight()
const {
1843 double dlonSigma = GetLonSigma().radians();
1845 if( dlonSigma <= 0.0 ) {
1846 IString msg =
"SurfacePoint::GetLonWeight(): Sigma <= 0.0";
1850 return 1.0/(dlonSigma*dlonSigma);
1858 double SurfacePoint::GetLocalRadiusWeight()
const {
1860 double dlocalRadiusSigma = GetLocalRadiusSigma().kilometers();
1862 if (dlocalRadiusSigma <= 0.0 ) {
1863 IString msg =
"SurfacePoint::GetRadWeight(): Sigma <= 0.0";
1867 return 1.0/(dlocalRadiusSigma*dlocalRadiusSigma);
1876 if(!Valid() || !other.Valid())
1879 return GetDistanceToPoint(other,
1892 const Distance &sphereRadius)
const {
1893 if(!Valid() || !other.Valid())
1897 const Angle &latitude = GetLatitude();
1898 const Angle &longitude = GetLongitude();
1904 Angle deltaLat = latitude - otherLatitude;
1905 Angle deltaLon = longitude - otherLongitude;
1907 double haversinLat = sin(deltaLat.
radians() / 2.0);
1908 haversinLat *= haversinLat;
1910 double haversinLon = sin(deltaLon.
radians() / 2.0);
1911 haversinLon *= haversinLon;
1913 double a = haversinLat + cos(latitude.
radians()) *
1914 cos(otherLatitude.radians()) *
1917 double c = 2 * atan(sqrt(a) / sqrt(1 - a));
1919 return sphereRadius * c;
1923 bool SurfacePoint::operator==(
const SurfacePoint &other)
const {
1926 if(equal && p_x && p_y && p_z && other.p_x && other.p_y && other.p_z) {
1927 equal = equal && *p_x == *other.p_x;
1928 equal = equal && *p_y == *other.p_y;
1929 equal = equal && *p_z == *other.p_z;
1932 equal = equal && p_x == NULL && other.p_x == NULL;
1933 equal = equal && p_y == NULL && other.p_y == NULL;
1934 equal = equal && p_z == NULL && other.p_z == NULL;
1937 if(equal && p_rectCovar) {
1938 equal = equal && (*p_rectCovar)(0, 0) == (*other.
p_rectCovar)(0, 0);
1939 equal = equal && (*p_rectCovar)(0, 1) == (*other.
p_rectCovar)(0, 1);
1940 equal = equal && (*p_rectCovar)(0, 2) == (*other.
p_rectCovar)(0, 2);
1941 equal = equal && (*p_rectCovar)(1, 1) == (*other.
p_rectCovar)(1, 1);
1942 equal = equal && (*p_rectCovar)(1, 2) == (*other.
p_rectCovar)(1, 2);
1943 equal = equal && (*p_rectCovar)(2, 2) == (*other.
p_rectCovar)(2, 2);
1946 equal = equal && p_rectCovar == NULL && other.
p_rectCovar == NULL;
1949 if(equal && p_sphereCovar) {
1950 equal = equal && (*p_sphereCovar)(0, 0) == (*other.
p_sphereCovar)(0, 0);
1951 equal = equal && (*p_sphereCovar)(0, 1) == (*other.
p_sphereCovar)(0, 1);
1952 equal = equal && (*p_sphereCovar)(0, 2) == (*other.
p_sphereCovar)(0, 2);
1953 equal = equal && (*p_sphereCovar)(1, 1) == (*other.
p_sphereCovar)(1, 1);
1954 equal = equal && (*p_sphereCovar)(1, 2) == (*other.
p_sphereCovar)(1, 2);
1955 equal = equal && (*p_sphereCovar)(2, 2) == (*other.
p_sphereCovar)(2, 2);
1958 equal = equal && p_sphereCovar == NULL && other.
p_sphereCovar == NULL;
1964 SurfacePoint &SurfacePoint::operator=(
const SurfacePoint &other) {
1967 if(p_x && other.p_x &&
1970 !p_rectCovar && !other.p_rectCovar &&
1971 !p_sphereCovar && !other.p_sphereCovar) {
1977 FreeAllocatedMemory();
1980 p_x =
new Displacement(*other.p_x);
1984 p_y =
new Displacement(*other.p_y);
1988 p_z =
new Displacement(*other.p_z);
1991 if(other.p_rectCovar) {
1992 p_rectCovar =
new symmetric_matrix<double, upper>(*other.p_rectCovar);
1995 if(other.p_sphereCovar) {
1996 p_sphereCovar =
new symmetric_matrix<double, upper>(*other.p_sphereCovar);
2001 p_localRadius = other.GetLocalRadius();
2006 void SurfacePoint::FreeAllocatedMemory() {
2028 delete p_sphereCovar;
2029 p_sphereCovar = NULL;
This class defines a body-fixed surface point.
double meters() const
Get the distance in meters.
boost::numeric::ublas::symmetric_matrix< double, boost::numeric::ublas::upper > * p_sphereCovar
3x3 upper triangular covariance matrix ocentric coordinates
const double Null
Value for an Isis Null pixel.
boost::numeric::ublas::symmetric_matrix< double, boost::numeric::ublas::upper > * p_rectCovar
3x3 upper triangular covariance matrix rectangular coordinates
const double PI
The mathematical constant PI.
double radians() const
Convert an angle to a double.
double meters() const
Get the displacement in meters.
bool isValid() const
Test if this displacement has been initialized or not.
Namespace for the standard library.
This class is designed to encapsulate the concept of a Latitude.
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
double kilometers() const
Get the distance in kilometers.
Distance measurement, usually in meters.
Latitude GetLatitude() const
Return the body-fixed latitude for the surface point.
This class is designed to encapsulate the concept of a Longitude.
#define _FILEINFO_
Macro for the filename and line number.
void setKilometers(double distanceInKilometers)
Set the distance in kilometers.
bool IsSpecial(const double d)
Returns if the input pixel is special.
bool isValid() const
Test if this distance has been initialized or not.
CoordinateType
Defines the coordinate typ, units, and coordinate index for some of the output methods.
Defines an angle and provides unit conversions.
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
Longitude GetLongitude() const
Return the body-fixed longitude for the surface point.
Displacement is a signed length, usually in meters.
Adds specific functionality to C++ strings.
Namespace for ISIS/Bullet specific routines.
bool isValid() const
This indicates whether we have a legitimate angle stored or are in an unset, or invalid, state.
double kilometers() const
Get the displacement in kilometers.
Distance GetLocalRadius() const
Return the radius of the surface point.
Unless noted otherwise, the portions of Isis written by the USGS are public domain.