vgl_area.hxx
Go to the documentation of this file.
1 // This is core/vgl/vgl_area.hxx
2 #ifndef vgl_area_hxx_
3 #define vgl_area_hxx_
4 
5 #include "vgl_area.h"
6 //:
7 // \file
8 #include <vgl/vgl_polygon.h>
9 #include <vgl/vgl_point_2d.h>
10 #include <vgl/vgl_box_2d.h>
12 
13 template <class T>
15 {
16  // Compute the area using Green's theorem
17  T area = T(0);
18  for (unsigned int s = 0; s < poly.num_sheets(); ++s )
19  for (unsigned int i = 0, j = (unsigned int)(poly[s].size()-1); i < poly[s].size(); j=i++ )
20  area += poly[s][j].x() * poly[s][i].y() - poly[s][i].x() * poly[s][j].y();
21 
22  return area/2;
23 }
24 
25 //: The area weighted center of a polygon
26 // In general this is different than the mean of the polygon's vertices
27 template <class T>
29 {
30  T area = vgl_area_signed(poly);
31  T x = T(0), y = T(0);
32  for (unsigned int s = 0; s < poly.num_sheets(); ++s ){
33  for (unsigned int i = 0, j = (unsigned int)(poly[s].size()-1); i < poly[s].size(); j=i++ ){
34  T w = poly[s][j].x() * poly[s][i].y() - poly[s][i].x() * poly[s][j].y();
35  x += (poly[s][j].x() + poly[s][i].x())*w;
36  y += (poly[s][j].y() + poly[s][i].y())*w;
37  }
38  }
39  x /= 6*area;
40  y /= 6*area;
41  return vgl_point_2d<T>(x,y);
42 }
43 
44 // This function is not implemented inline because the cost of a
45 // single function call is irrelevant compared to the cost of running
46 // vgl_area_signed. It is therefore better to have fewer dependencies
47 // in the header file and implement this function here.
48 template <class T>
49 T vgl_area( const vgl_polygon<T>& poly )
50 {
51  T area = vgl_area_signed(poly);
52  return area<0 ? -area : area;
53 }
54 
55 //: The orientation enforced area of a polygon.
56 // \note This method assumes that the polygon is simple (i.e. no crossings)
57 // and the correct orientation is 'enforced' on the polygon (i.e. holes are
58 // given negative area) to ensure that the resultant area is correct
59 // \sa vgl_area
60 // \relatesalso vgl_polygon
61 template <class T> T vgl_area_enforce_orientation(vgl_polygon<T> const& poly)
62 {
63  T area = T(0);
64 
65  // now check containment and enforce correct signs
66  // if a sheet is inside an odd number of other sheets then it's a hole
67  for (unsigned int t = 0; t < poly.num_sheets(); ++t)
68  {
69  const typename vgl_polygon<T>::sheet_t & test_pgon= poly[t];
70  T t_area = T(0);
71 
72  // first calculate all test_pgon's area using Green's theorem
73  for (unsigned int i = 0, j = (unsigned int)(test_pgon.size()-1); i < test_pgon.size(); j=i++ )
74  t_area += test_pgon[j].x() * test_pgon[i].y() - test_pgon[i].x() * test_pgon[j].y();
75 
76  // test if one of t's points is inside the other sheets
77  // assume sheets don't overlap!
78  bool is_hole = false;
79  T x = test_pgon[0].x();
80  T y = test_pgon[0].y();
81  for (unsigned int s = 0; s < poly.num_sheets(); ++s)
82  {
83  // don't check a sheet against itself
84  if (s==t)
85  continue;
86 
87  typename vgl_polygon<T>::sheet_t const& pgon = poly[s];
88  unsigned int n = (unsigned int)(pgon.size());
89  bool c = false;
90  for (unsigned int i = 0, j = n-1; i < n; j = i++)
91  // invert c for each edge crossing
92  if ((((pgon[i].y() <= y) && (y < pgon[j].y())) || ((pgon[j].y() <= y) && (y < pgon[i].y()))) &&
93  (x < (pgon[j].x() - pgon[i].x()) * (y - pgon[i].y()) / (pgon[j].y() - pgon[i].y()) + pgon[i].x()))
94  c = !c;
95 
96  if (c)
97  is_hole = !is_hole;
98  }
99 
100  // if it's oriented in the wrong direction then reverse it
101  if ( (!is_hole && t_area < 0) || (is_hole && t_area > 0))
102  t_area = -t_area;
103 
104  area += t_area;
105  }
106 
107  return area/2;
108 }
109 template <class T>
110 T vgl_area( const vgl_box_2d<T>& box ){
111  return box.width()*box.height(); }
112 
113 template <class T>
115  std::pair<T,T> wh = obox.width_height();
116  return wh.first * wh.second;
117 }
118 
119 #undef VGL_AREA_INSTANTIATE
120 #define VGL_AREA_INSTANTIATE(T) \
121 template T vgl_area(vgl_polygon<T > const&); \
122 template T vgl_area_signed(vgl_polygon<T > const&); \
123 template T vgl_area_enforce_orientation(vgl_polygon<T > const&); \
124 template vgl_point_2d<T > vgl_centroid(vgl_polygon<T > const&); \
125 template T vgl_area( const vgl_box_2d<T>& box ); \
126 template T vgl_area( const vgl_oriented_box_2d<T>& obox )
127 #endif // vgl_area_hxx_
a point in 2D nonhomogeneous space
vgl_point_2d< T > vgl_centroid(vgl_polygon< T > const &poly)
The area weighted center of a polygon.
Type width() const
Get width of this box (= x dimension).
Definition: vgl_box_2d.hxx:128
std::pair< T, T > width_height() const
return width (first) and height (second).
T vgl_area_signed(vgl_polygon< T > const &poly)
Computes the signed area of a polygon.
Contains class to represent a cartesian 2D bounding box.
Type height() const
Get height of this box (= y dimension).
Definition: vgl_box_2d.hxx:134
T vgl_area_enforce_orientation(vgl_polygon< T > const &poly)
The orientation enforced area of a polygon.
Definition: vgl_area.hxx:61
std::vector< point_t > sheet_t
Definition: vgl_polygon.h:43
unsigned int num_sheets() const
Definition: vgl_polygon.h:116
Store a polygon.
Definition: vgl_area.h:6
T vgl_area(vgl_polygon< T > const &poly)
The area of a polygon.
An orienteded box in 2-d.