GeoTessCPP
2.0.0
Software to facilitate storage and retrieval of 3D information about the Earth.
|
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_ */