GeoTessCPP: include/GeoTessGreatCircle.h Source File

GeoTessCPP 2.1 Software to facilitate storage and retrieval of 3D information about the Earth.

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

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
168 class GEOTESS_EXP_IMP GeoTessGreatCircle
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
230 virtual ~GeoTessGreatCircle();
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
308 GeoTessGreatCircle(GeoTessGreatCircle& other);
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
435 double getDistanceDegrees()
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_ */