GeoTessCPP  2.0.0
Software to facilitate storage and retrieval of 3D information about the Earth.
 All Classes Namespaces Files Functions Variables Typedefs Friends Defines
include/GeoTessGreatCircle.h
Go to the documentation of this file.
00001 //- ****************************************************************************
00002 //- 
00003 //- Copyright 2009 Sandia Corporation. Under the terms of Contract
00004 //- DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
00005 //- retains certain rights in this software.
00006 //- 
00007 //- BSD Open Source License.
00008 //- All rights reserved.
00009 //- 
00010 //- Redistribution and use in source and binary forms, with or without
00011 //- modification, are permitted provided that the following conditions are met:
00012 //- 
00013 //-    * Redistributions of source code must retain the above copyright notice,
00014 //-      this list of conditions and the following disclaimer.
00015 //-    * Redistributions in binary form must reproduce the above copyright
00016 //-      notice, this list of conditions and the following disclaimer in the
00017 //-      documentation and/or other materials provided with the distribution.
00018 //-    * Neither the name of Sandia National Laboratories nor the names of its
00019 //-      contributors may be used to endorse or promote products derived from
00020 //-      this software without specific prior written permission.
00021 //- 
00022 //- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00023 //- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024 //- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025 //- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00026 //- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00027 //- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00028 //- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00029 //- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00030 //- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00031 //- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032 //- POSSIBILITY OF SUCH DAMAGE.
00033 //-
00034 //- ****************************************************************************
00035 
00036 #ifndef GREATCIRCLE_H_
00037 #define GREATCIRCLE_H_
00038 
00039 // **** _SYSTEM INCLUDES_ ******************************************************
00040 
00041 //#include <cstdio>
00042 #include <iostream>
00043 #include <string>
00044 
00045 // use standard library objects
00046 using namespace std;
00047 
00048 // **** _LOCAL INCLUDES_ *******************************************************
00049 
00050 #include "CPPUtils.h"
00051 #include "GeoTessUtils.h"
00052 
00053 // **** _BEGIN GEOTESS NAMESPACE_ **********************************************
00054 
00055 namespace geotess {
00056 
00057 // **** _FORWARD REFERENCES_ ***************************************************
00058 
00059 // **** _CLASS DEFINITION_ *****************************************************
00060 
00168 class GEOTESS_EXP_IMP GeoTessGreatCircle
00169 {
00170   private:
00171 
00178         double distance;
00179 
00183         double* firstPoint;
00184 
00188         double* lastPoint;
00189 
00194         double normal[3];
00195 
00201         double moveDirection[3];
00202 
00206         bool deleteFirst;
00207 
00211         bool deleteLast;
00212 
00222         double** trnsfrm;
00223 
00224         void initialize(const double* intermediatePoint, const bool &shortestPath);
00225 
00226         void clear();
00227 
00228   public:
00229 
00230         virtual ~GeoTessGreatCircle();
00231 
00235         GeoTessGreatCircle() : firstPoint(NULL), lastPoint(NULL), deleteFirst(true), deleteLast(true), trnsfrm(NULL)
00236         {}
00237 
00250         GeoTessGreatCircle(const double* firstPoint, const double& distance, const double& direction);
00251 
00283         GeoTessGreatCircle(const double* firstPoint, const double* intermediatePoint, const double* lastPoint,
00284                         const bool &shortestPath=true);
00285 
00302         GeoTessGreatCircle(const double* firstPoint, const double* lastPoint, const bool &shortestPath=true);
00303 
00308         GeoTessGreatCircle(GeoTessGreatCircle& other);
00309 
00314         void operator= (GeoTessGreatCircle& other);
00315 
00320         bool operator == (const GeoTessGreatCircle& other) const
00321                 {
00322                 return firstPoint[0] == other.firstPoint[0]
00323                 && firstPoint[1] == other.firstPoint[1]
00324                 && firstPoint[2] == other.firstPoint[2]
00325                 && lastPoint[0] == other.lastPoint[0]
00326                 && lastPoint[1] == other.lastPoint[1]
00327                 && lastPoint[2] == other.lastPoint[2]
00328                 && normal[0] == other.normal[0]
00329                 && normal[1] == other.normal[1]
00330                 && normal[2] == other.normal[2];
00331                 };
00332 
00333 
00368         void set(double* firstPoint, double* intermediatePoint, double* lastPoint,
00369                         const bool& shortestPath=true, const bool& deleteWhenDone=false);
00370 
00392         void set(double* frstPoint, double* lstPoint,
00393                         const bool& shortestPath=true, const bool& deleteWhenDone=false)
00394         { set (frstPoint, NULL, lstPoint, shortestPath, deleteWhenDone); }
00395 
00411         void set(double* firstPoint, const double& distance, const double& azimuth,
00412                         const bool& deleteWhenDone=false);
00413 
00419         double getDistance()
00420         {
00421                 if (distance < 0.)
00422                 {
00423                         distance = GeoTessUtils::angle(firstPoint, lastPoint);
00424                         if (GeoTessUtils::scalarTripleProduct(firstPoint, lastPoint, normal) < 0.)
00425                                 distance = 2*PI - distance;
00426                 }
00427                 return distance;
00428         }
00429 
00435         double getDistanceDegrees()
00436         {
00437                 return CPPUtils::toDegrees(getDistance());
00438         }
00439 
00449         double getDistance(const double *position)
00450         {
00451                 // find the shortest distance from firstPoint to unit vector
00452                 double d = GeoTessUtils::angle(firstPoint, position);
00453 
00454                 if (GeoTessUtils::scalarTripleProduct(firstPoint, position, normal) < 0.)
00455                         d = 2 * PI - d;
00456 
00457                 return d;
00458         }
00459 
00470         double getDistanceDegrees(const double *position)
00471         {
00472                 return CPPUtils::toDegrees(getDistance(position));
00473         }
00474 
00482         double* getFirst()
00483         {
00484                 return firstPoint;
00485         }
00486 
00494         double* getLast()
00495         {
00496                 return lastPoint;
00497         }
00498 
00508         const double* getNormal()
00509         {
00510                 return normal;
00511         }
00512 
00524         double* getPoint(const double &dist)
00525         {
00526                 double* location = new double[3];
00527                 GeoTessUtils::move(firstPoint, moveDirection, dist, location);
00528                 return location;
00529         }
00530 
00540         void getPoint(const double &dist, double* location)
00541         {
00542                 GeoTessUtils::move(firstPoint, moveDirection, dist, location);
00543         }
00544 
00559         static int getNPoints(const double& dist, const double& spacing, const bool& onCenters=false)
00560         {
00561                 if (dist <= 0.) return onCenters ? 1 : 2;
00562                 return onCenters ? (int)ceil(dist/spacing) : ((int)ceil(dist/spacing))+1;
00563         }
00564 
00578         int getNPoints(const double& spacing, const bool& onCenters=false)
00579         {
00580                 return getNPoints(getDistance(), spacing, onCenters);
00581         }
00582 
00601         double getPoints(double** points, const int &npoints, const bool& onCenters=false)
00602         {
00603                 double dx;
00604                 if (onCenters)
00605                 {
00606                         dx = getDistance()/npoints;
00607                         for (int i=0; i<npoints; ++i) getPoint((i+0.5)*dx, points[i]);
00608                 }
00609                 else
00610                 {
00611                         dx = getDistance()/(npoints-1);
00612                         for (int i=0; i<npoints; ++i) getPoint(i*dx, points[i]);
00613                 }
00614                 return dx;
00615         }
00616 
00638         double getPoints(const double &spacing, double** points, int &npoints, const bool& onCenters=false)
00639         {
00640                 npoints = getNPoints(spacing, onCenters);
00641 
00642                 double dx;
00643                 if (onCenters)
00644                 {
00645                         dx = getDistance()/npoints;
00646                         for (int i=0; i<npoints; ++i) getPoint((i+0.5)*dx, points[i]);
00647                 }
00648                 else
00649                 {
00650                         dx = getDistance()/(npoints-1);
00651                         for (int i=0; i<npoints; ++i) getPoint(i*dx, points[i]);
00652                 }
00653                 return dx;
00654         }
00655 
00681         bool getIntersection(GeoTessGreatCircle& other, const bool& inRange, double* intersection)
00682         {
00683                 if (GeoTessUtils::crossNormal(normal, other.normal, intersection) == 0.)
00684                 {
00685                         intersection[0] = intersection[1] = intersection[2] = NaN_DOUBLE;
00686                         return false;
00687                 }
00688 
00689                 if (GeoTessUtils::scalarTripleProduct(firstPoint, intersection, normal) < 0.)
00690                 {
00691                         intersection[0] = -intersection[0];
00692                         intersection[1] = -intersection[1];
00693                         intersection[2] = -intersection[2];
00694                 }
00695 
00696                 if (inRange && (getDistance(intersection) >= getDistance()
00697                                 || other.getDistance(intersection) >= other.getDistance()))
00698                 {
00699                         intersection[0] = intersection[1] = intersection[2] = NaN_DOUBLE;
00700                         return false;
00701                 }
00702 
00703                 return true;
00704         }
00705 
00720         double** getTransform();
00721 
00742         void transform(const double* x, double* v)
00743         {
00744                 // make sure that trnsfrm has been calculated
00745                 getTransform();
00746                 v[0] = x[0] * trnsfrm[0][0] + x[1] * trnsfrm[0][1] + x[2]
00747                                 * trnsfrm[0][2];
00748                 v[1] = x[0] * trnsfrm[1][0] + x[1] * trnsfrm[1][1] + x[2]
00749                                 * trnsfrm[1][2];
00750                 v[2] = x[0] * trnsfrm[2][0] + x[1] * trnsfrm[2][1] + x[2]
00751                                         * trnsfrm[2][2];
00752         }
00753 
00775         double* transform(const double* x)
00776         {
00777                 double* v = new double[3];
00778                 transform(x, v);
00779                 return v;
00780         }
00781 
00782         string toString();
00783 
00784 }; // end class GreatCircle
00785 
00786 } // end namespace geotess
00787 
00788 #endif /* GREATCIRCLE_H_ */