src/PolygonArea.cpp
Go to the documentation of this file.
1 
11 
12 namespace GeographicLib {
13 
14  using namespace std;
15 
16  template <class GeodType>
18  lat = Math::LatFix(lat);
19  lon = Math::AngNormalize(lon);
20  if (_num == 0) {
21  _lat0 = _lat1 = lat;
22  _lon0 = _lon1 = lon;
23  } else {
24  real s12, S12, t;
25  _earth.GenInverse(_lat1, _lon1, lat, lon, _mask,
26  s12, t, t, t, t, t, S12);
27  _perimetersum += s12;
28  if (!_polyline) {
29  _areasum += S12;
30  _crossings += transit(_lon1, lon);
31  }
32  _lat1 = lat; _lon1 = lon;
33  }
34  ++_num;
35  }
36 
37  template <class GeodType>
39  if (_num) { // Do nothing if _num is zero
40  real lat, lon, S12, t;
41  _earth.GenDirect(_lat1, _lon1, azi, false, s, _mask,
42  lat, lon, t, t, t, t, t, S12);
43  _perimetersum += s;
44  if (!_polyline) {
45  _areasum += S12;
46  _crossings += transitdirect(_lon1, lon);
47  lon = Math::AngNormalize(lon);
48  }
49  _lat1 = lat; _lon1 = lon;
50  ++_num;
51  }
52  }
53 
54  template <class GeodType>
56  real& perimeter, real& area) const
57  {
58  real s12, S12, t;
59  if (_num < 2) {
60  perimeter = 0;
61  if (!_polyline)
62  area = 0;
63  return _num;
64  }
65  if (_polyline) {
66  perimeter = _perimetersum();
67  return _num;
68  }
69  _earth.GenInverse(_lat1, _lon1, _lat0, _lon0, _mask,
70  s12, t, t, t, t, t, S12);
71  perimeter = _perimetersum(s12);
72  Accumulator<> tempsum(_areasum);
73  tempsum += S12;
74  int crossings = _crossings + transit(_lon1, _lon0);
75  if (crossings & 1)
76  tempsum += (tempsum < 0 ? 1 : -1) * _area0/2;
77  // area is with the clockwise sense. If !reverse convert to
78  // counter-clockwise convention.
79  if (!reverse)
80  tempsum *= -1;
81  // If sign put area in (-area0/2, area0/2], else put area in [0, area0)
82  if (sign) {
83  if (tempsum > _area0/2)
84  tempsum -= _area0;
85  else if (tempsum <= -_area0/2)
86  tempsum += _area0;
87  } else {
88  if (tempsum >= _area0)
89  tempsum -= _area0;
90  else if (tempsum < 0)
91  tempsum += _area0;
92  }
93  area = 0 + tempsum();
94  return _num;
95  }
96 
97  template <class GeodType>
99  bool reverse, bool sign,
100  real& perimeter, real& area) const
101  {
102  if (_num == 0) {
103  perimeter = 0;
104  if (!_polyline)
105  area = 0;
106  return 1;
107  }
108  perimeter = _perimetersum();
109  real tempsum = _polyline ? 0 : _areasum();
110  int crossings = _crossings;
111  unsigned num = _num + 1;
112  for (int i = 0; i < (_polyline ? 1 : 2); ++i) {
113  real s12, S12, t;
114  _earth.GenInverse(i == 0 ? _lat1 : lat, i == 0 ? _lon1 : lon,
115  i != 0 ? _lat0 : lat, i != 0 ? _lon0 : lon,
116  _mask, s12, t, t, t, t, t, S12);
117  perimeter += s12;
118  if (!_polyline) {
119  tempsum += S12;
120  crossings += transit(i == 0 ? _lon1 : lon,
121  i != 0 ? _lon0 : lon);
122  }
123  }
124 
125  if (_polyline)
126  return num;
127 
128  if (crossings & 1)
129  tempsum += (tempsum < 0 ? 1 : -1) * _area0/2;
130  // area is with the clockwise sense. If !reverse convert to
131  // counter-clockwise convention.
132  if (!reverse)
133  tempsum *= -1;
134  // If sign put area in (-area0/2, area0/2], else put area in [0, area0)
135  if (sign) {
136  if (tempsum > _area0/2)
137  tempsum -= _area0;
138  else if (tempsum <= -_area0/2)
139  tempsum += _area0;
140  } else {
141  if (tempsum >= _area0)
142  tempsum -= _area0;
143  else if (tempsum < 0)
144  tempsum += _area0;
145  }
146  area = 0 + tempsum;
147  return num;
148  }
149 
150  template <class GeodType>
152  bool reverse, bool sign,
153  real& perimeter, real& area) const
154  {
155  if (_num == 0) { // we don't have a starting point!
156  perimeter = Math::NaN();
157  if (!_polyline)
158  area = Math::NaN();
159  return 0;
160  }
161  unsigned num = _num + 1;
162  perimeter = _perimetersum() + s;
163  if (_polyline)
164  return num;
165 
166  real tempsum = _areasum();
167  int crossings = _crossings;
168  {
169  real lat, lon, s12, S12, t;
170  _earth.GenDirect(_lat1, _lon1, azi, false, s, _mask,
171  lat, lon, t, t, t, t, t, S12);
172  tempsum += S12;
173  crossings += transitdirect(_lon1, lon);
174  lon = Math::AngNormalize(lon);
175  _earth.GenInverse(lat, lon, _lat0, _lon0, _mask,
176  s12, t, t, t, t, t, S12);
177  perimeter += s12;
178  tempsum += S12;
179  crossings += transit(lon, _lon0);
180  }
181 
182  if (crossings & 1)
183  tempsum += (tempsum < 0 ? 1 : -1) * _area0/2;
184  // area is with the clockwise sense. If !reverse convert to
185  // counter-clockwise convention.
186  if (!reverse)
187  tempsum *= -1;
188  // If sign put area in (-area0/2, area0/2], else put area in [0, area0)
189  if (sign) {
190  if (tempsum > _area0/2)
191  tempsum -= _area0;
192  else if (tempsum <= -_area0/2)
193  tempsum += _area0;
194  } else {
195  if (tempsum >= _area0)
196  tempsum -= _area0;
197  else if (tempsum < 0)
198  tempsum += _area0;
199  }
200  area = 0 + tempsum;
201  return num;
202  }
203 
207 
208 } // namespace GeographicLib
static T AngNormalize(T x)
Definition: Math.hpp:440
unsigned TestEdge(real azi, real s, bool reverse, bool sign, real &perimeter, real &area) const
static T NaN()
Definition: Math.hpp:830
unsigned TestPoint(real lat, real lon, bool reverse, bool sign, real &perimeter, real &area) const
#define GEOGRAPHICLIB_EXPORT
Definition: Constants.hpp:91
static const double lat
static T LatFix(T x)
Definition: Math.hpp:467
Definition: Half.h:150
void AddEdge(real azi, real s)
An accumulator for sums.
Definition: Accumulator.hpp:40
EIGEN_DEVICE_FUNC const SignReturnType sign() const
unsigned Compute(bool reverse, bool sign, real &perimeter, real &area) const
Namespace for GeographicLib.
RealScalar s
void AddPoint(real lat, real lon)
Header for GeographicLib::PolygonAreaT class.
void reverse(const MatrixType &m)
static const double lon
Point2 t(10, 10)


gtsam
Author(s):
autogenerated on Sat May 8 2021 02:43:27