GeoTessCPP  2.6.1
Software to facilitate storage and retrieval of 3D information about the Earth.
All Classes Namespaces Files Functions Variables Typedefs Friends Macros
GeoTessGreatCircle.h
Go to the documentation of this file.
1 //- ****************************************************************************
2 //-
3 //- Copyright 2009 Sandia Corporation. Under the terms of Contract
4 //- DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
5 //- retains certain rights in this software.
6 //-
7 //- BSD Open Source License.
8 //- All rights reserved.
9 //-
10 //- Redistribution and use in source and binary forms, with or without
11 //- modification, are permitted provided that the following conditions are met:
12 //-
13 //- * Redistributions of source code must retain the above copyright notice,
14 //- this list of conditions and the following disclaimer.
15 //- * Redistributions in binary form must reproduce the above copyright
16 //- notice, this list of conditions and the following disclaimer in the
17 //- documentation and/or other materials provided with the distribution.
18 //- * Neither the name of Sandia National Laboratories nor the names of its
19 //- contributors may be used to endorse or promote products derived from
20 //- this software without specific prior written permission.
21 //-
22 //- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 //- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 //- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 //- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
26 //- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 //- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 //- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 //- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 //- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 //- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 //- POSSIBILITY OF SUCH DAMAGE.
33 //-
34 //- ****************************************************************************
35 
36 #ifndef GREATCIRCLE_H_
37 #define GREATCIRCLE_H_
38 
39 // **** _SYSTEM INCLUDES_ ******************************************************
40 
41 //#include <cstdio>
42 #include <iostream>
43 #include <string>
44 
45 // use standard library objects
46 using namespace std;
47 
48 // **** _LOCAL INCLUDES_ *******************************************************
49 
50 #include "CPPUtils.h"
51 #include "GeoTessUtils.h"
52 
53 // **** _BEGIN GEOTESS NAMESPACE_ **********************************************
54 
55 namespace geotess {
56 
57 // **** _FORWARD REFERENCES_ ***************************************************
58 
59 // **** _CLASS DEFINITION_ *****************************************************
60 
169 {
170  private:
171 
178  double distance;
179 
183  double* firstPoint;
184 
188  double* lastPoint;
189 
194  double normal[3];
195 
201  double moveDirection[3];
202 
206  bool deleteFirst;
207 
211  bool deleteLast;
212 
222  double** trnsfrm;
223 
224  void initialize(const double* intermediatePoint, const bool &shortestPath);
225 
226  void clear();
227 
228  public:
229 
231 
235  GeoTessGreatCircle() : firstPoint(NULL), lastPoint(NULL), deleteFirst(true), deleteLast(true), trnsfrm(NULL)
236  {}
237 
250  GeoTessGreatCircle(const double* firstPoint, const double& distance, const double& direction);
251 
283  GeoTessGreatCircle(const double* firstPoint, const double* intermediatePoint, const double* lastPoint,
284  const bool &shortestPath=true);
285 
302  GeoTessGreatCircle(const double* firstPoint, const double* lastPoint, const bool &shortestPath=true);
303 
309 
314  void operator= (GeoTessGreatCircle& other);
315 
320  bool operator == (const GeoTessGreatCircle& other) const
321  {
322  return firstPoint[0] == other.firstPoint[0]
323  && firstPoint[1] == other.firstPoint[1]
324  && firstPoint[2] == other.firstPoint[2]
325  && lastPoint[0] == other.lastPoint[0]
326  && lastPoint[1] == other.lastPoint[1]
327  && lastPoint[2] == other.lastPoint[2]
328  && normal[0] == other.normal[0]
329  && normal[1] == other.normal[1]
330  && normal[2] == other.normal[2];
331  };
332 
333 
368  void set(double* firstPoint, double* intermediatePoint, double* lastPoint,
369  const bool& shortestPath=true, const bool& deleteWhenDone=false);
370 
392  void set(double* frstPoint, double* lstPoint,
393  const bool& shortestPath=true, const bool& deleteWhenDone=false)
394  { set (frstPoint, NULL, lstPoint, shortestPath, deleteWhenDone); }
395 
411  void set(double* firstPoint, const double& distance, const double& azimuth,
412  const bool& deleteWhenDone=false);
413 
419  double getDistance()
420  {
421  if (distance < 0.)
422  {
423  distance = GeoTessUtils::angle(firstPoint, lastPoint);
424  if (GeoTessUtils::scalarTripleProduct(firstPoint, lastPoint, normal) < 0.)
425  distance = 2*PI - distance;
426  }
427  return distance;
428  }
429 
436  {
437  return CPPUtils::toDegrees(getDistance());
438  }
439 
449  double getDistance(const double *position)
450  {
451  // find the shortest distance from firstPoint to unit vector
452  double d = GeoTessUtils::angle(firstPoint, position);
453 
454  if (GeoTessUtils::scalarTripleProduct(firstPoint, position, normal) < 0.)
455  d = 2 * PI - d;
456 
457  return d;
458  }
459 
470  double getDistanceDegrees(const double *position)
471  {
472  return CPPUtils::toDegrees(getDistance(position));
473  }
474 
482  double* getFirst()
483  {
484  return firstPoint;
485  }
486 
494  double* getLast()
495  {
496  return lastPoint;
497  }
498 
508  const double* getNormal()
509  {
510  return normal;
511  }
512 
524  double* getPoint(const double &dist)
525  {
526  double* location = new double[3];
527  GeoTessUtils::move(firstPoint, moveDirection, dist, location);
528  return location;
529  }
530 
540  void getPoint(const double &dist, double* location)
541  {
542  GeoTessUtils::move(firstPoint, moveDirection, dist, location);
543  }
544 
559  static int getNPoints(const double& dist, const double& spacing, const bool& onCenters=false)
560  {
561  if (dist <= 0.) return onCenters ? 1 : 2;
562  return onCenters ? (int)ceil(dist/spacing) : ((int)ceil(dist/spacing))+1;
563  }
564 
578  int getNPoints(const double& spacing, const bool& onCenters=false)
579  {
580  return getNPoints(getDistance(), spacing, onCenters);
581  }
582 
601  double getPoints(double** points, const int &npoints, const bool& onCenters=false)
602  {
603  double dx;
604  if (onCenters)
605  {
606  dx = getDistance()/npoints;
607  for (int i=0; i<npoints; ++i) getPoint((i+0.5)*dx, points[i]);
608  }
609  else
610  {
611  dx = getDistance()/(npoints-1);
612  for (int i=0; i<npoints; ++i) getPoint(i*dx, points[i]);
613  }
614  return dx;
615  }
616 
638  double getPoints(const double &spacing, double** points, int &npoints, const bool& onCenters=false)
639  {
640  npoints = getNPoints(spacing, onCenters);
641 
642  double dx;
643  if (onCenters)
644  {
645  dx = getDistance()/npoints;
646  for (int i=0; i<npoints; ++i) getPoint((i+0.5)*dx, points[i]);
647  }
648  else
649  {
650  dx = getDistance()/(npoints-1);
651  for (int i=0; i<npoints; ++i) getPoint(i*dx, points[i]);
652  }
653  return dx;
654  }
655 
681  bool getIntersection(GeoTessGreatCircle& other, const bool& inRange, double* intersection)
682  {
683  if (GeoTessUtils::crossNormal(normal, other.normal, intersection) == 0.)
684  {
685  intersection[0] = intersection[1] = intersection[2] = NaN_DOUBLE;
686  return false;
687  }
688 
689  if (GeoTessUtils::scalarTripleProduct(firstPoint, intersection, normal) < 0.)
690  {
691  intersection[0] = -intersection[0];
692  intersection[1] = -intersection[1];
693  intersection[2] = -intersection[2];
694  }
695 
696  if (inRange && (getDistance(intersection) >= getDistance()
697  || other.getDistance(intersection) >= other.getDistance()))
698  {
699  intersection[0] = intersection[1] = intersection[2] = NaN_DOUBLE;
700  return false;
701  }
702 
703  return true;
704  }
705 
720  double** getTransform();
721 
742  void transform(const double* x, double* v)
743  {
744  // make sure that trnsfrm has been calculated
745  getTransform();
746  v[0] = x[0] * trnsfrm[0][0] + x[1] * trnsfrm[0][1] + x[2]
747  * trnsfrm[0][2];
748  v[1] = x[0] * trnsfrm[1][0] + x[1] * trnsfrm[1][1] + x[2]
749  * trnsfrm[1][2];
750  v[2] = x[0] * trnsfrm[2][0] + x[1] * trnsfrm[2][1] + x[2]
751  * trnsfrm[2][2];
752  }
753 
775  double* transform(const double* x)
776  {
777  double* v = new double[3];
778  transform(x, v);
779  return v;
780  }
781 
782  string toString();
783 
784 }; // end class GreatCircle
785 
786 } // end namespace geotess
787 
788 #endif /* GREATCIRCLE_H_ */
#define GEOTESS_EXP_IMP
Definition: CPPGlobals.h:71
Manages information about a great circle path that extends from one point to another point,...
int getNPoints(const double &spacing, const bool &onCenters=false)
GeoTessGreatCircle(const double *firstPoint, const double *intermediatePoint, const double *lastPoint, const bool &shortestPath=true)
void set(double *firstPoint, const double &distance, const double &azimuth, const bool &deleteWhenDone=false)
void set(double *frstPoint, double *lstPoint, const bool &shortestPath=true, const bool &deleteWhenDone=false)
double getDistanceDegrees(const double *position)
GeoTessGreatCircle(const double *firstPoint, const double &distance, const double &direction)
double * transform(const double *x)
double * getPoint(const double &dist)
bool getIntersection(GeoTessGreatCircle &other, const bool &inRange, double *intersection)
void getPoint(const double &dist, double *location)
static int getNPoints(const double &dist, const double &spacing, const bool &onCenters=false)
GeoTessGreatCircle(const double *firstPoint, const double *lastPoint, const bool &shortestPath=true)
double getDistance(const double *position)
double getPoints(double **points, const int &npoints, const bool &onCenters=false)
void transform(const double *x, double *v)
GeoTessGreatCircle(GeoTessGreatCircle &other)
double getPoints(const double &spacing, double **points, int &npoints, const bool &onCenters=false)
void set(double *firstPoint, double *intermediatePoint, double *lastPoint, const bool &shortestPath=true, const bool &deleteWhenDone=false)