1 // This is core/vgl/algo/vgl_rtree_c.h 2 #ifndef vgl_rtree_c_h_ 3 #define vgl_rtree_c_h_ 4 //: 5 // \file 6 // \brief C helper classes for vgl_rtree 7 // \author J.L. Mundy 8 // \date November 14, 2008 9 // \verbatim 10 // Modifications 11 // <None yet> 12 // \endverbatim 13 // 14 // vgl_rtree stores elements of type V with regions described by 15 // bounds type B. The C helper class implements the bounding predicates 16 // between V and B. Thus V and B remain independent of each other. 17 // 18 #include <vgl/vgl_point_2d.h> 19 #include <vgl/vgl_box_2d.h> 20 #include <vgl/vgl_polygon.h> 21 #include <vgl/vgl_intersection.h> 22 #include <vgl/vgl_area.h> 23 template <class V, class B, class C> class vgl_rtree_probe; 24 25 //: vgl_rtree Class C for V=vgl_point_2d<T>, B = vgl_box_2d<T> 26 template <class T> 27 class vgl_rtree_point_box_2d 28 { 29 // only static methods 30 vgl_rtree_point_box_2d() = delete; 31 ~vgl_rtree_point_box_2d() = delete; 32 33 public: 34 typedef vgl_point_2d<T> v_type; 35 typedef vgl_box_2d<T> b_type; 36 typedef T t_type; 37 // Operations------ init(vgl_box_2d<T> & b,vgl_point_2d<T> const & p)38 static void init (vgl_box_2d<T>& b, vgl_point_2d<T> const& p) 39 { b = vgl_box_2d<T>(); b.add(p); } 40 update(vgl_box_2d<T> & b,vgl_point_2d<T> const & p)41 static void update(vgl_box_2d<T>& b, vgl_point_2d<T> const& p) 42 { b.add(p); } 43 update(vgl_box_2d<T> & b0,vgl_box_2d<T> const & b1)44 static void update(vgl_box_2d<T>& b0, vgl_box_2d<T> const &b1) 45 { b0.add(b1.min_point()); b0.add(b1.max_point()); } 46 meet(vgl_box_2d<T> const & b,vgl_point_2d<T> const & p)47 static bool meet(vgl_box_2d<T> const& b, vgl_point_2d<T> const& p) 48 { return b.contains(p); } 49 meet(vgl_box_2d<T> const & b0,vgl_box_2d<T> const & b1)50 static bool meet(vgl_box_2d<T> const& b0, vgl_box_2d<T> const& b1) { 51 vgl_box_2d<T> bint = vgl_intersection<T>(b0, b1); 52 return !bint.is_empty(); 53 } 54 volume(vgl_box_2d<T> const & b)55 static float volume(vgl_box_2d<T> const& b) 56 { return static_cast<float>(vgl_area(b)); } 57 58 // point meets for a polygon, used by generic rtree probe meets(vgl_point_2d<T> const & v,vgl_polygon<T> poly)59 static bool meets(vgl_point_2d<T> const& v, vgl_polygon<T> poly) 60 { return poly.contains(v); } 61 62 // box meets for a polygon, used by generic rtree probe meets(vgl_box_2d<T> const & b,vgl_polygon<T> poly)63 static bool meets(vgl_box_2d<T> const& b, vgl_polygon<T> poly) 64 { return vgl_intersection<T>(b, poly); } 65 }; 66 67 68 //: vgl_rtree Class C for V=vgl_box_2d<T>, B = vgl_rbox_2d<T> 69 // Need to distinguish bounds type from stored element type, 70 // so create minimal subclass of vgl_box_2d 71 template <class Type> 72 class vgl_bbox_2d : public vgl_box_2d<Type> 73 { 74 public: 75 //: Default constructor (creates empty box) 76 vgl_bbox_2d() = default; 77 78 //: Construct using two corner points vgl_bbox_2d(Type const min_position[2],Type const max_position[2])79 vgl_bbox_2d(Type const min_position[2], 80 Type const max_position[2]) 81 : vgl_box_2d<Type>(min_position[2], max_position[2]) {} 82 83 //: Construct using two corner points vgl_bbox_2d(vgl_point_2d<Type> const & min_pos,vgl_point_2d<Type> const & max_pos)84 vgl_bbox_2d(vgl_point_2d<Type> const& min_pos, 85 vgl_point_2d<Type> const& max_pos) 86 : vgl_box_2d<Type>(min_pos, max_pos) {} 87 88 //: Construct using ranges in \a x (first two args) and \a y (last two) vgl_bbox_2d(Type xmin,Type xmax,Type ymin,Type ymax)89 vgl_bbox_2d(Type xmin, Type xmax, Type ymin, Type ymax) 90 : vgl_box_2d<Type>(xmin, xmax, ymin, ymax) {} 91 92 //: Equality test 93 inline bool operator==(vgl_bbox_2d<Type> const& b) const { 94 // All empty boxes are equal: 95 if (b.is_empty()) return this->is_empty(); 96 return this->min_x() == b.min_x() && this->min_y() == b.min_y() 97 && this->max_x() == b.max_x() && this->max_y() == b.max_y(); 98 } 99 }; 100 101 template <class T> 102 class vgl_rtree_box_box_2d 103 { 104 // only static methods 105 vgl_rtree_box_box_2d() = delete; 106 ~vgl_rtree_box_box_2d() = delete; 107 108 public: 109 typedef vgl_box_2d<T> v_type; 110 typedef vgl_bbox_2d<T> b_type; 111 typedef T t_type; 112 // Operations------ init(vgl_bbox_2d<T> & b,vgl_box_2d<T> const & v)113 static void init (vgl_bbox_2d<T>& b, vgl_box_2d<T> const& v) 114 { b = vgl_bbox_2d<T>(); b.add(v.min_point()); b.add(v.max_point()); } 115 update(vgl_bbox_2d<T> & b,vgl_box_2d<T> const & v)116 static void update(vgl_bbox_2d<T>& b, vgl_box_2d<T> const& v) 117 { b.add(v.min_point()); b.add(v.max_point()); } 118 update(vgl_bbox_2d<T> & b0,vgl_bbox_2d<T> const & b1)119 static void update(vgl_bbox_2d<T>& b0, vgl_bbox_2d<T> const &b1) 120 { b0.add(b1.min_point()); b0.add(b1.max_point()); } 121 meet(vgl_bbox_2d<T> const & b0,vgl_box_2d<T> const & v)122 static bool meet(vgl_bbox_2d<T> const& b0, vgl_box_2d<T> const& v) { 123 bool resultf =(b0.contains(v.min_point()) || b0.contains(v.max_point())); 124 bool resultr =(v.contains(b0.min_point()) || v.contains(b0.max_point())); 125 return resultf||resultr; 126 } 127 meet(vgl_bbox_2d<T> const & b0,vgl_bbox_2d<T> const & b1)128 static bool meet(vgl_bbox_2d<T> const& b0, vgl_bbox_2d<T> const& b1) { 129 bool resultf =(b0.contains(b1.min_point()) || b0.contains(b1.max_point())); 130 bool resultr =(b1.contains(b0.min_point()) || b1.contains(b0.max_point())); 131 return resultf||resultr; 132 } 133 volume(vgl_box_2d<T> const & b)134 static float volume(vgl_box_2d<T> const& b) 135 { return static_cast<float>(vgl_area(b)); } 136 137 // box_2d meets for a polygon, used by generic rtree probe meets(vgl_box_2d<T> const & b,vgl_polygon<T> poly)138 static bool meets(vgl_box_2d<T> const& b, vgl_polygon<T> poly) 139 { return vgl_rtree_point_box_2d<T>::meets(b, poly); } 140 meets(vgl_bbox_2d<T> const & b,vgl_polygon<T> poly)141 static bool meets(vgl_bbox_2d<T> const& b, vgl_polygon<T> poly) 142 { return vgl_rtree_point_box_2d<T>::meets(b, poly); } 143 }; 144 145 template <class V, class B, class C> 146 class vgl_rtree_polygon_probe : public vgl_rtree_probe<V, B, C> 147 { 148 typedef typename C::t_type T; 149 vgl_polygon<T> poly_; 150 public: vgl_rtree_polygon_probe(vgl_polygon<T> const & poly)151 vgl_rtree_polygon_probe(vgl_polygon<T> const& poly): poly_(poly) {} 152 153 //: return true if the probe "meets" the given object. meets(V const & v)154 bool meets(V const &v) const override {return C::meets(v, poly_); } meets(B const & b)155 bool meets(B const &b) const override {return C::meets(b, poly_); } 156 }; 157 158 #endif // vgl_rtree_c_h_ 159