KJB
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
pixpoint.h
Go to the documentation of this file.
1 
6 /*
7  * $Id: pixpoint.h 18278 2014-11-25 01:42:10Z ksimek $
8  */
9 
10 #ifndef PIXPOINT_H_UOFARIZONAVISION
11 #define PIXPOINT_H_UOFARIZONAVISION 1
12 
13 #include <l_cpp/l_exception.h>
14 #include <m_cpp/m_vector_d.h>
15 
16 #include <limits>
17 #include <string>
18 #include <sstream>
19 #include <cmath>
20 #include <algorithm>
21 
22 
23 namespace kjb
24 {
25 
27 namespace qd
28 {
29 
30 
31 #ifdef TEST
32 const bool TEST_PIXPOINT_UNUSED = true;
33 #else
34 const bool TEST_PIXPOINT_UNUSED = false;
35 #endif
36 
57 struct PixPoint
58 {
59 
60  typedef int Integer;
61 
63  struct Unused : public kjb::Result_error
64  {
65  Unused( const std::string& m, const char* f, int l )
66  : kjb::Result_error( m, f, l )
67  {}
68  };
69 
71  static void fault_if( bool b )
72  {
73  if ( TEST_PIXPOINT_UNUSED && b )
74  {
75  KJB_THROW_2( Unused, "Unused PixPoint" );
76  }
77  }
78 
80  y;
81 
84  : x( std::numeric_limits< Integer >::max() ),
85  y( std::numeric_limits< Integer >::max() )
86  {}
87 
90  : x( xx ),
91  y( yy )
92  {}
93 
95  void swap( PixPoint& that )
96  {
97  std::swap( x, that.x );
98  std::swap( y, that.y );
99  }
100 
102  bool is_unused() const
103  {
106  }
107 
109  bool is_not_unused() const
110  {
111  return ! is_unused();
112  }
113 
115  bool is_used() const
116  {
117  return ! is_unused();
118  }
119 
129  bool operator<( const PixPoint& pp ) const
130  {
131  fault_if( is_unused() || pp.is_unused() );
132  return y < pp.y
133  || ( y == pp.y && x < pp.x ); // unnecessary parentheses grr
134  }
135 
137  bool operator==( const PixPoint& pp ) const
138  {
139  fault_if( is_unused() || pp.is_unused() );
140  return x == pp.x && y == pp.y;
141  }
142 
144  bool operator!=( const PixPoint& pp ) const
145  {
146  return ! operator==( pp );
147  }
148 
151  {
152  fault_if( is_unused() || pp.is_unused() );
153  return operator=( operator+( pp ) );
154  }
155 
157  PixPoint operator+( const PixPoint& pp ) const
158  {
159  fault_if( is_unused() || pp.is_unused() );
160  return PixPoint( x+pp.x, y+pp.y );
161  }
162 
164  PixPoint operator-( const PixPoint& pp ) const
165  {
166  fault_if( is_unused() || pp.is_unused() );
167  return PixPoint( x-pp.x, y-pp.y );
168  }
169 
171  PixPoint operator*( int factor ) const
172  {
173  fault_if( is_unused() );
174  return PixPoint( factor * x, factor * y );
175  }
176 
178  PixPoint operator/( int divisor ) const
179  {
180  fault_if( is_unused() );
181  return PixPoint( x / divisor, y / divisor );
182  }
183 
185  Integer idot( const PixPoint& pp ) const
186  {
187  fault_if( is_unused() || pp.is_unused() );
188  return x * pp.x + y * pp.y;
189  }
190 
207  float dist2( const PixPoint& pp = PixPoint( 0, 0 ) ) const
208  {
209  fault_if( is_unused() || pp.is_unused() );
210  float dx = x-pp.x, dy = y-pp.y;
211  return dx*dx + dy*dy;
212  }
213 
227  float dist( const PixPoint& pp = PixPoint( 0, 0 ) ) const
228  {
229  fault_if( is_unused() || pp.is_unused() );
230  return sqrt( dist2(pp) );
231  }
232 
252  {
253  fault_if( is_unused() || pp.is_unused() );
254 
255  Integer dxs = x-pp.x, dx = std::max( dxs, -dxs ),
256  dys = y-pp.y, dy = std::max( dys, -dys );
257  return std::max( dx, dy );
258  }
259 
268  bool adjacent8( const PixPoint& pp ) const
269  {
270  fault_if( is_unused() || pp.is_unused() );
271  return L_infinity_distance( pp ) <= 1;
272  }
273 
275  std::string str( const std::string& sep = ", " ) const
276  {
277  if ( is_unused() )
278  return std::string( "UNUSED" );
279 
280  std::ostringstream ss;
281  ss << x << sep << y;
282  return ss.str();
283  }
284 
295  bool in_quadrant_I() const
296  {
297  return 0 <= x && 0 <= y && is_not_unused();
298  }
299 
307  bool is_poz_poz() const
308  {
309  return 0 < x && 0 < y && is_not_unused();
310  }
311 
312  // forward declaration
313  struct Is_inbounds;
314 
327  Integer cross( const PixPoint& pp ) const
328  {
329  fault_if( is_unused() || pp.is_unused() );
330  return x * pp.y - pp.x * y;
331  }
332 
333 
335  bool is_collinear( const PixPoint& p1, const PixPoint& p2 ) const
336  {
337  return 0 == operator-( p1 ).cross( operator-( p2 ) );
338  }
339 };
340 
341 
351 struct PixPoint::Is_inbounds : public std::unary_function< PixPoint, bool >
352 {
353 
356 
375  Is_inbounds( PixPoint min_min, PixPoint width_height )
376  : m_min_min( min_min ),
377  m_width_height( width_height )
378  {}
379 
381  bool operator()( PixPoint querypoint ) const
382  {
383  PixPoint qp2 = querypoint - m_min_min;
384  return qp2.in_quadrant_I() && (m_width_height - qp2).is_poz_poz();
385  }
386 
388  bool operator!=( const Is_inbounds& that_functor ) const
389  {
390  return m_min_min != that_functor.m_min_min
391  || m_width_height != that_functor.m_width_height;
392  }
393 };
394 
395 
398 {
400  return kjb::Vector2(p.x, p.y);
401 }
402 
403 
406 {
407  // It is reckless because the value might not fit in an integer,
408  // and we don't even bother to check.
409  return PixPoint(static_cast<PixPoint::Integer>(std::floor(v.x() + 0.5)),
410  static_cast<PixPoint::Integer>(std::floor(v.y() + 0.5)));
411 }
412 
415 {
416  // It is reckless because the value might not fit in an integer,
417  // and we don't even bother to check.
418  return PixPoint(static_cast<PixPoint::Integer>(std::floor(v.x())),
419  static_cast<PixPoint::Integer>(std::floor(v.y())));
420 }
421 
424 {
425  // It is reckless because the value might not fit in an integer,
426  // and we don't even bother to check.
427  return PixPoint(static_cast<PixPoint::Integer>(std::ceil(v.x())),
428  static_cast<PixPoint::Integer>(std::ceil(v.y())));
429 }
430 
431 
432 
433 
434 // The code for this function lives in pixpath.cpp (at this writing).
435 PixPoint str_to_PixPoint( std::istream& iss, const std::string& sep="," );
436 
438 inline
439 PixPoint str_to_PixPoint( const std::string& spp, const std::string& sep="," )
440 {
441  std::istringstream iss( spp );
442  return str_to_PixPoint( iss, sep );
443 }
444 
445 }
446 }
447 
448 namespace std
449 {
450 
451 
453  template<>
454  inline void swap(
455  kjb::qd::PixPoint& p1,
457  )
458  {
459  p1.swap( p2 );
460  }
461 }
462 
463 #endif
static void fault_if(bool b)
throw exception if we try to operate on an unused point
Definition: pixpoint.h:71
Int_matrix::Value_type max(const Int_matrix &mat)
Return the maximum value in this matrix.
Definition: l_int_matrix.h:1397
PixPoint reckless_round(const kjb::Vector2 &v)
round to near integers, disregarding overrange values
Definition: pixpoint.h:405
bool operator!=(const Is_inbounds &that_functor) const
test whether this functor differs from another
Definition: pixpoint.h:388
PixPoint operator-(const PixPoint &pp) const
subtract two PixPoints when they are interpreted as 2-vectors
Definition: pixpoint.h:164
PixPoint operator+(const PixPoint &pp) const
add two PixPoints when they are interpreted as 2-vectors
Definition: pixpoint.h:157
float dist(const PixPoint &pp=PixPoint(0, 0)) const
Return distance between points, using the L2 norm.
Definition: pixpoint.h:227
PixPoint operator*(int factor) const
multiply components of a PixPoint by a factor (like 2-vector)
Definition: pixpoint.h:171
PixPoint reckless_ceil(const kjb::Vector2 &v)
round the vector contents to integers, disregarding overrange values
Definition: pixpoint.h:423
double y() const
Definition: m_vector_d.impl.h:169
float dist2(const PixPoint &pp=PixPoint(0, 0)) const
Distance squared between PixPoint objects, or from the origin.
Definition: pixpoint.h:207
Is_inbounds(PixPoint min_min, PixPoint width_height)
Establish the boundaries of the box: LL corner and size.
Definition: pixpoint.h:375
bool is_collinear(const PixPoint &p1, const PixPoint &p2) const
return true iff this point lies on the same line as line(p1,p2).
Definition: pixpoint.h:335
Object thrown when a function cannot generate a valid result.
Definition: l_exception.h:516
kjb::Vector2 to_vector2(const PixPoint &p)
convert the PixPoint to a floating point format
Definition: pixpoint.h:397
Integer cross(const PixPoint &pp) const
return cross product of two PixPoints interpreted as 2-vectors.
Definition: pixpoint.h:327
double x() const
Definition: m_vector_d.impl.h:134
bool is_poz_poz() const
Test whether a PixPoint has strictly positive x and y coords.
Definition: pixpoint.h:307
Integer idot(const PixPoint &pp) const
interp as 2-vec, compute dot prod as integer (beware overflow)
Definition: pixpoint.h:185
function straight edges straight lines(nlines,[x1 x2 y1 y2 theta r])%%To display result ss
Definition: APPgetLargeConnectedEdges.m:20
std::string str(const std::string &sep=", ") const
Express a PixPoint as a string (ascii coordinate values)
Definition: pixpoint.h:275
exception thrown if the PixPoint is used while uninitialized
Definition: pixpoint.h:63
PixPoint()
ctor sets fields to sentinel values to indicated "unused."
Definition: pixpoint.h:83
const bool TEST_PIXPOINT_UNUSED
extra test for unused PixPoint
Definition: pixpoint.h:34
void swap(PixPoint &that)
swap state of two pixpoints
Definition: pixpoint.h:95
Int_matrix floor(const Matrix &m)
Definition: m_matrix.cpp:2026
PixPoint operator/(int divisor) const
integer-divide components of a PixPoint (like a 2-vector)
Definition: pixpoint.h:178
bool operator!=(const PixPoint &pp) const
test whether two points differ (different integer coords)
Definition: pixpoint.h:144
bool operator==(const PixPoint &pp) const
test whether two points are equivalent (same integer coords)
Definition: pixpoint.h:137
bool adjacent8(const PixPoint &pp) const
test adjacency using eight-connectivity (or identity).
Definition: pixpoint.h:268
#define KJB_THROW_2(ex, msg)
Definition: l_exception.h:48
Integer L_infinity_distance(const PixPoint &pp) const
Definition: pixpoint.h:251
Integer x
x coordinate of the pixel
Definition: pixpoint.h:79
PixPoint & operator+=(const PixPoint &pp)
add a PixPoint to this PixPoint, when interpreted as 2-vectors
Definition: pixpoint.h:150
void swap(kjb::Gsl_Multimin_fdf &m1, kjb::Gsl_Multimin_fdf &m2)
Swap two wrapped multimin objects.
Definition: gsl_multimin.h:693
Unused(const std::string &m, const char *f, int l)
Definition: pixpoint.h:65
PixPoint str_to_PixPoint(std::istream &iss, const std::string &sep)
scan a string value into a PixPoint
Definition: pixpath.cpp:1607
bool in_quadrant_I() const
Test whether a PixPoint has nonnegative x and y coordinates.
Definition: pixpoint.h:295
bool operator()(PixPoint querypoint) const
Predicate test: is it inside the established boundaries?
Definition: pixpoint.h:381
const PixPoint m_width_height
dimensions of bounding box
Definition: pixpoint.h:354
bool operator<(const PixPoint &pp) const
This operator imposes a total order on PixPoints.
Definition: pixpoint.h:129
Representation of an (x,y) pair of pixel coordinates.
Definition: pixpoint.h:57
PixPoint reckless_floor(const kjb::Vector2 &v)
truncate towards negative infinity, disregarding overrange values
Definition: pixpoint.h:414
for m
Definition: APPgetLargeConnectedEdges.m:64
Support for error handling exception classes in libKJB.
bool is_not_unused() const
convenience inline for better readability
Definition: pixpoint.h:109
bool is_used() const
another convenience inline that is not so unpositive.
Definition: pixpoint.h:115
Vector_d< 2 > Vector2
Definition: gr_opengl.h:35
const PixPoint m_min_min
minimum in-bounds x and y coordinates
Definition: pixpoint.h:354
bool is_unused() const
Test whether a PixPoint is unused (untouched since default ctor)
Definition: pixpoint.h:102
Integer y
y coordinate of the pixel
Definition: pixpoint.h:79
Predicate functor tests whether a PixPoint is in a bounding box.
Definition: pixpoint.h:351
PixPoint(Integer xx, Integer yy)
Basic ctor builds from two coordinates.
Definition: pixpoint.h:89
int Integer
any signed integer valued type is fine
Definition: pixpoint.h:60