ARB
aw_position.hxx
Go to the documentation of this file.
1 // =============================================================== //
2 // //
3 // File : aw_position.hxx //
4 // Purpose : Positions, Vectors and Angles //
5 // //
6 // Coded by Ralf Westram (coder@reallysoft.de) in July 2007 //
7 // Institute of Microbiology (Technical University Munich) //
8 // http://www.arb-home.de/ //
9 // //
10 // =============================================================== //
11 
12 #ifndef AW_POSITION_HXX
13 #define AW_POSITION_HXX
14 
15 #ifndef AW_BASE_HXX
16 #include "aw_base.hxx"
17 #endif
18 #ifndef ARB_ASSERT_H
19 #include <arb_assert.h>
20 #endif
21 #ifndef ARBTOOLS_H
22 #include <arbtools.h>
23 #endif
24 #ifndef _GLIBCXX_CMATH
25 #include <cmath>
26 #endif
27 
28 #ifndef aw_assert
29 #define aw_assert(bed) arb_assert(bed)
30 #endif
31 
32 // ------------------------
33 // validity checks
34 
35 #if defined(DEBUG)
36 
37 #define ISVALID(a) aw_assert((a).valid())
38 
39 inline const double& NONAN(const double& d) {
40  aw_assert(d == d);
41  return d;
42 }
43 
44 #else
45 #define ISVALID(a)
46 #define NONAN(d) (d)
47 #endif // DEBUG
48 
49 namespace AW {
50 
51  struct FillStyle {
52  enum Style {
54  SHADED, // uses greylevel of gc
55  SHADED_WITH_BORDER, // like SHADED, but with solid border
57  };
58 
59  private:
60  Style style;
61 
62  public:
63 
64  FillStyle(Style filled) : style(filled) {} // non-explicit!
65 
66  Style get_style() const { return style; }
67 
68  bool is_shaded() const { return style == SHADED || style == SHADED_WITH_BORDER; }
69  bool is_empty() const { return style == EMPTY; }
70  bool somehow() const { return !is_empty(); }
71  };
72 
73  const double EPSILON = 0.001; // how equal is nearly equal
74 
75  inline bool nearlyEqual(const double& val1, const double& val2) { return std::abs(val1-val2) < EPSILON; }
76  inline bool nearlyZero(const double& val) { return nearlyEqual(val, 0.0); }
77  inline double centroid(const double& val1, const double& val2) { return (val1+val2)*0.5; }
78 
79  // -------------------------------------------------------
80  // class Position represents 2-dimensional positions
81 
82  // Note: orientation of drawn canvases is like shown in this figure:
83  //
84  // __________________\ +x
85  // | / .
86  // |
87  // |
88  // |
89  // |
90  // |
91  // |
92  // \|/
93  // +y
94  //
95  // i.e. rotating an angle by 90 degrees, means rotating it 3 hours in clockwise direction
96 
97  class Vector;
98 
99  inline bool is_between(const double& coord1, const double& between, const double& coord2) {
100  return ((coord1-between)*(between-coord2)) >= 0.0;
101  }
102 
103  class Position {
104  double x, y;
105 
106  public:
107 
108  bool valid() const { return !is_nan_or_inf(x) && !is_nan_or_inf(y); }
109 
110  Position(double X, double Y) : x(X), y(Y) { ISVALID(*this); }
111  // Position(const Position& other) : x(other.x), y(other.y) { ISVALID(*this); }
112  Position() : x(NAN), y(NAN) {} // default is no position
114 
115  inline Position& operator += (const Vector& v);
116  inline Position& operator -= (const Vector& v);
117 
118  const double& xpos() const { return x; }
119  const double& ypos() const { return y; }
120 
121  void setx(const double& X) { x = NONAN(X); }
122  void sety(const double& Y) { y = NONAN(Y); }
123 
124  void movex(const double& X) { x += NONAN(X); }
125  void movey(const double& Y) { y += NONAN(Y); }
126 
127  void move(const Vector& movement) { *this += movement; }
128  void moveTo(const Position& pos) { *this = pos; }
129 
130  inline bool is_between(const Position& p1, const Position& p2) const {
131  return AW::is_between(p1.x, x, p2.x) && AW::is_between(p1.y, y, p2.y);
132  }
133  };
134 
135  extern const Position Origin;
136 
137  inline bool nearlyEqual(const Position& p1, const Position& p2) {
138  return
139  nearlyEqual(p1.xpos(), p2.xpos()) &&
140  nearlyEqual(p1.ypos(), p2.ypos());
141  }
142 
143  // -------------------------------
144  // a 2D vector
145 
146  class Vector {
147  Position end; // endpoint of vector (vector starts at Position::origin)
148  mutable double len; // once calculated, length of vector is stored here (negative value means "not calculated")
149 
150  public:
151  bool valid() const { return end.valid() && !is_nan(len); } // infinite len is allowed (but untested)
152 
153  Vector() : len(NAN) {} // default is not a vector
154  Vector(const double& X, const double& Y) : end(X, Y), len(-1) { ISVALID(*this); } // vector (0,0)->(X,Y)
155  Vector(const double& X, const double& Y, const double& Length) : end(X, Y), len(Length) { ISVALID(*this); } // same with known length
156  explicit Vector(const Position& to) : end(to), len(-1) { ISVALID(*this); } // vector origin->to
157  Vector(const Position& from, const Position& to) : end(to.xpos()-from.xpos(), to.ypos()-from.ypos()), len(-1) { ISVALID(*this); } // vector from->to
158  ~Vector() {}
159 
160  const double& x() const { return end.xpos(); }
161  const double& y() const { return end.ypos(); }
162  const Position& endpoint() const { return end; }
163 
164  Vector& set(const double& X, const double& Y, double Length = -1) { end = Position(X, Y); len = Length; return *this; }
165  Vector& setx(const double& X) { end.setx(X); len = -1; return *this; }
166  Vector& sety(const double& Y) { end.sety(Y); len = -1; return *this; }
167 
168  const double& length() const {
169  if (len<0.0) len = hypot(x(), y());
170  return len;
171  }
172 
173  // length-modifying members:
174 
175  Vector& operator *= (const double& factor) { return set(x()*factor, y()*factor, length()*std::abs(factor)); }
176  Vector& operator /= (const double& divisor) { return operator *= (1.0/divisor); }
177 
178  Vector& operator += (const Vector& other) { return set(x()+other.x(), y()+other.y()); }
179  Vector& operator -= (const Vector& other) { return set(x()-other.x(), y()-other.y()); }
180 
182  aw_assert(length()>0); // cannot normalize zero-Vector!
183  return *this /= length();
184  }
185  bool is_normalized() const { return nearlyEqual(length(), 1); }
186  bool has_length() const { return !nearlyEqual(length(), 0); }
187 
188  Vector& set_length(double new_length) {
189  double factor = new_length/length();
190  return (*this *= factor);
191  }
192 
193  // length-constant members:
194 
195  Vector& neg() { end = Position(-x(), -y()); return *this; }
196  Vector& negx() { end.setx(-x()); return *this; }
197  Vector& negy() { end.sety(-y()); return *this; }
198 
199  Vector& flipxy() { end = Position(y(), x()); return *this; }
200 
201  Vector& rotate90deg() { return negy().flipxy(); }
202  Vector& rotate180deg() { return neg(); }
203  Vector& rotate270deg() { return negx().flipxy(); }
204 
205  Vector& rotate45deg();
209 
210  Vector operator-() const { return Vector(-x(), -y(), len); } // unary minus
211  };
212 
213  extern const Vector ZeroVector;
214 
215  inline bool nearlyEqual(const Vector& v1, const Vector& v2) { return nearlyEqual(v1.endpoint(), v2.endpoint()); }
216 
217  // -----------------------------------------
218  // inline Position members
219 
220  inline Position& Position::operator += (const Vector& v) { x += v.x(); y += v.y(); ISVALID(*this); return *this; }
221  inline Position& Position::operator -= (const Vector& v) { x -= v.x(); y -= v.y(); ISVALID(*this); return *this; }
222 
223  // ------------------------------------------
224  // basic Position / Vector functions
225 
226  // Difference between Positions
227  inline Vector operator-(const Position& to, const Position& from) { return Vector(from, to); }
228 
229  // Position +- Vector -> new Position
230  inline Position operator+(const Position& p, const Vector& v) { return Position(p) += v; }
231  inline Position operator+(const Vector& v, const Position& p) { return Position(p) += v; }
232  inline Position operator-(const Position& p, const Vector& v) { return Position(p) -= v; }
233 
234  // Vector addition
235  inline Vector operator+(const Vector& v1, const Vector& v2) { return Vector(v1) += v2; }
236  inline Vector operator-(const Vector& v1, const Vector& v2) { return Vector(v1) -= v2; }
237 
238  // stretch/shrink Vector
239  inline Vector operator*(const Vector& v, const double& f) { return Vector(v) *= f; }
240  inline Vector operator*(const double& f, const Vector& v) { return Vector(v) *= f; }
241  inline Vector operator/(const Vector& v, const double& d) { return Vector(v) /= d; }
242 
243  inline Position centroid(const Position& p1, const Position& p2) { return Position(centroid(p1.xpos(), p2.xpos()), centroid(p1.ypos(), p2.ypos())); }
244 
245  inline double Distance(const Position& from, const Position& to) { return Vector(from, to).length(); }
246  inline double scalarProduct(const Vector& v1, const Vector& v2) { return v1.x()*v2.x() + v1.y()*v2.y(); }
247 
248  inline bool are_distinct(const Position& p1, const Position& p2) { return Vector(p1, p2).has_length(); }
249 
250  inline bool is_vertical(const Vector& v) { return nearlyZero(v.x()) && !nearlyZero(v.y()); }
251  inline bool is_horizontal(const Vector& v) { return !nearlyZero(v.x()) && nearlyZero(v.y()); }
252 
253  inline Vector orthogonal_projection(const Vector& projectee, const Vector& target) {
255  double tlen = target.length();
256  return target * (scalarProduct(projectee, target) / (tlen*tlen));
257  }
258  inline Vector normalized(const Vector& v) {
260  return Vector(v).normalize();
261  }
262  inline bool are_parallel(const Vector& v1, const Vector& v2) {
264  Vector diff = normalized(v1)-normalized(v2);
265  return !diff.has_length();
266  }
268  inline bool are_antiparallel(const Vector& v1, const Vector& v2) { return are_parallel(v1, -v2); }
269 
270  // -------------------------------------------------
271  // a positioned vector, representing a line
272 
274 
275  class LineVector {
276  Position Start; // start point
277  Vector ToEnd; // vector to end point
278 
279  protected:
280  void standardize();
281 
282  public:
283  bool valid() const { return Start.valid() && ToEnd.valid(); }
284 
285  LineVector(const Position& startpos, const Position& end) : Start(startpos), ToEnd(startpos, end) { ISVALID(*this); }
286  LineVector(const Position& startpos, const Vector& to_end) : Start(startpos), ToEnd(to_end) { ISVALID(*this); }
287  LineVector(double X1, double Y1, double X2, double Y2) : Start(X1, Y1), ToEnd(X2-X1, Y2-Y1) { ISVALID(*this); }
289  switch (mode) {
290  case INCLUSIVE_OUTLINE:
291  Start = Position(r.l, r.t);
292  ToEnd = Vector(r.r-r.l+1, r.b-r.t+1);
293  break;
294  case UPPER_LEFT_OUTLINE:
295  Start = Position(r.l, r.t);
296  ToEnd = Vector(r.r-r.l, r.b-r.t);
297  break;
298  }
299  ISVALID(*this);
300  }
301  explicit LineVector(const AW_world& r) : Start(r.l, r.t), ToEnd(r.r-r.l, r.b-r.t) { ISVALID(*this); }
303 
304  const Vector& line_vector() const { return ToEnd; }
305  const Position& start() const { return Start; }
306  Position head() const { return Start+ToEnd; }
307 
308  Position centroid() const { return Start+ToEnd*0.5; }
309  double length() const { return line_vector().length(); }
310  bool has_length() const { return line_vector().has_length(); }
311 
312  const double& xpos() const { return Start.xpos(); }
313  const double& ypos() const { return Start.ypos(); }
314 
315  void move(const Vector& movement) { Start += movement; }
316  void moveTo(const Position& pos) { Start = pos; }
317 
318  LineVector reverse() const { return LineVector(head(), Vector(ToEnd).neg()); }
319  };
320 
321  Position crosspoint(const LineVector& l1, const LineVector& l2, double& factor_l1, double& factor_l2);
322  Position nearest_linepoint(const Position& pos, const LineVector& line, double& factor);
323  inline Position nearest_linepoint(const Position& pos, const LineVector& line) { double dummy; return nearest_linepoint(pos, line, dummy); }
324  inline double Distance(const Position& pos, const LineVector& line) { return Distance(pos, nearest_linepoint(pos, line)); }
325 
326  inline bool is_vertical(const LineVector& line) { return is_vertical(line.line_vector()); }
327  inline bool is_horizontal(const LineVector& line) { return is_horizontal(line.line_vector()); }
328  inline bool nearlyEqual(const LineVector& L1, const LineVector& L2) {
329  return
330  nearlyEqual(L1.line_vector(), L2.line_vector()) &&
331  nearlyEqual(L1.start(), L2.start());
332  }
333 
334  // ---------------------
335  // a rectangle
336 
337  class Rectangle : public LineVector { // the LineVector describes one corner and the diagonal
338  public:
339  explicit Rectangle(const LineVector& Diagonal) : LineVector(Diagonal) { standardize(); }
340  Rectangle(const Position& corner, const Position& opposite_corner) : LineVector(corner, opposite_corner) { standardize(); }
341  Rectangle(const Position& corner, const Vector& to_opposite_corner) : LineVector(corner, to_opposite_corner) { standardize(); }
342  Rectangle(double X1, double Y1, double X2, double Y2) : LineVector(X1, Y1, X2, Y2) { standardize(); }
344  explicit Rectangle(const AW_world& r) : LineVector(r) { standardize(); }
345  Rectangle() {};
346 
347  const Vector& diagonal() const { return line_vector(); }
348 
349  const Position& upper_left_corner() const { return start(); }
350  Position lower_left_corner() const { return Position(start().xpos(), start().ypos()+line_vector().y()); }
351  Position upper_right_corner() const { return Position(start().xpos()+line_vector().x(), start().ypos()); }
352  Position lower_right_corner() const { return head(); }
353 
354  Position get_corner(int i) const {
355  switch (i%4) {
356  case 0: return upper_left_corner();
357  case 1: return upper_right_corner();
358  case 2: return lower_right_corner();
359  default: return lower_left_corner();
360  }
361  }
362  Position nearest_corner(const Position& topos) const;
363 
364  double left() const { return upper_left_corner().xpos(); }
365  double top() const { return upper_left_corner().ypos(); }
366  double right() const { return lower_right_corner().xpos(); }
367  double bottom() const { return lower_right_corner().ypos(); }
368 
369  double width() const { return diagonal().x(); }
370  double height() const { return diagonal().y(); }
371 
372  LineVector upper_edge() const { return LineVector(start(), Vector(line_vector().x(), 0)); }
373  LineVector left_edge() const { return LineVector(start(), Vector(0, line_vector().y())); }
374  LineVector lower_edge() const { return LineVector(head(), Vector(-line_vector().x(), 0)); }
375  LineVector right_edge() const { return LineVector(head(), Vector(0, -line_vector().y())); }
376 
379 
382 
384 
385  bool contains(const Position& pos) const { return pos.is_between(upper_left_corner(), lower_right_corner()); }
386  bool contains(const LineVector& lvec) const { return contains(lvec.start()) && contains(lvec.head()); }
387 
388  bool distinct_from(const Rectangle& rect) const {
389  // returns false for adjacent rectangles (even if they only share one corner)
390  return
391  top() > rect.bottom() ||
392  rect.top() > bottom() ||
393  left() > rect.right() ||
394  rect.left() > right();
395  }
396  bool overlaps_with(const Rectangle& rect) const { return !distinct_from(rect); }
397 
398  Rectangle intersect_with(const Rectangle& rect) const {
399  aw_assert(overlaps_with(rect));
402  }
403 
404  Rectangle bounding_box(const Rectangle& rect) const {
407  }
408  Rectangle bounding_box(const Position& pos) const {
411  }
412 
413  double surface() const { return width()*height(); }
414  };
415 
416  inline Rectangle bounding_box(const Rectangle& r1, const Rectangle& r2) { return r1.bounding_box(r2); }
417 
418  inline Rectangle bounding_box(const Rectangle& rect, const LineVector& line) { return rect.bounding_box(Rectangle(line)); }
419  inline Rectangle bounding_box(const LineVector& line, const Rectangle& rect) { return rect.bounding_box(Rectangle(line)); }
420 
421  inline Rectangle bounding_box(const LineVector& l1, const LineVector& l2) { return Rectangle(l1).bounding_box(Rectangle(l2)); }
422 
423  inline Rectangle bounding_box(const Rectangle& rect, const Position& pos) { return rect.bounding_box(pos); }
424  inline Rectangle bounding_box(const Position& pos, const Rectangle& rect) { return rect.bounding_box(pos); }
425 
426  inline Rectangle bounding_box(const LineVector& line, const Position& pos) { return Rectangle(line).bounding_box(pos); }
427  inline Rectangle bounding_box(const Position& pos, const LineVector& line) { return Rectangle(line).bounding_box(pos); }
428 
429  inline Rectangle bounding_box(const Position& p1, const Position& p2) { return Rectangle(p1, p2); }
430 
431 
433  D_NORTH = 1,
434  D_SOUTH = 2,
435  D_WEST = 4,
436  D_EAST = 8,
437 
442 
445  };
446 
447  CONSTEXPR_INLINE bool definesQuadrant(const RoughDirection rd) { return (rd & D_VERTICAL) && (rd & D_HORIZONTAL); }
448 
449  // ------------------------------------------------------------------
450  // class angle represents an angle using a normalized vector
451 
452  class Angle {
453  mutable Vector Normal; // the normal vector representing the angle (x = cos(angle), y = sin(angle))
454  mutable double Radian; // the radian of the angle
455  // (starts at 3 o'clock running forward!!! i.e. South is 90 degrees; caused by y-direction of canvas)
456 
457  void recalcRadian() const;
458  void recalcNormal() const;
459 
460  public:
461  bool valid() const { return Normal.valid() && !is_nan_or_inf(Radian); }
462 
463  static const double rad2deg;
464  static const double deg2rad;
465 
466  explicit Angle(double Radian_) : Radian(Radian_) { recalcNormal(); ISVALID(*this); }
467  Angle(double x, double y) : Normal(x, y) { Normal.normalize(); recalcRadian(); ISVALID(*this); }
468  Angle(const Angle& a) : Normal(a.Normal), Radian(a.Radian) { ISVALID(*this); }
469  explicit Angle(const Vector& v) : Normal(v) { Normal.normalize(); recalcRadian(); ISVALID(*this); }
470  explicit Angle(const LineVector& lv) : Normal(lv.line_vector()) { Normal.normalize(); recalcRadian(); ISVALID(*this); }
471  Angle(const Vector& n, double r) : Normal(n), Radian(r) { aw_assert(n.is_normalized()); ISVALID(*this); }
472  Angle(const Position& p1, const Position& p2) : Normal(p1, p2) { Normal.normalize(); recalcRadian(); ISVALID(*this); }
473  Angle() : Radian(NAN) {} // default is not an angle
474 
475  Angle& operator = (const Angle& other) { Normal = other.Normal; Radian = other.Radian; return *this; }
476  Angle& operator = (const Vector& vec) { Normal = vec; Normal.normalize(); recalcRadian(); return *this; }
477 
478  void fixRadian() const { // force radian into range [0, 2*M_PI[
479  while (Radian<0.0) Radian += 2*M_PI;
480  while (Radian >= 2*M_PI) Radian -= 2*M_PI;
481  }
482 
483  const double& radian() const { fixRadian(); return Radian; }
484  double degrees() const { fixRadian(); return rad2deg*Radian; }
485  const Vector& normal() const { return Normal; }
486 
487  const double& sin() const { return Normal.y(); }
488  const double& cos() const { return Normal.x(); }
489 
490  Angle& operator += (const Angle& o) {
491  Radian += o.Radian;
492 
493  double norm = normal().length()*o.normal().length();
494  if (nearlyEqual(norm, 1)) { // fast method
495  Vector newNormal(cos()*o.cos() - sin()*o.sin(),
496  sin()*o.cos() + cos()*o.sin());
497  aw_assert(newNormal.is_normalized());
498  Normal = newNormal;
499  }
500  else {
501  recalcNormal();
502  }
503  return *this;
504  }
505  Angle& operator -= (const Angle& o) {
506  Radian -= o.Radian;
507 
508  double norm = normal().length()*o.normal().length();
509  if (nearlyEqual(norm, 1)) { // fast method
510  Vector newNormal(cos()*o.cos() + sin()*o.sin(),
511  sin()*o.cos() - cos()*o.sin());
512  aw_assert(newNormal.is_normalized());
513 
514  Normal = newNormal;
515  }
516  else {
517  recalcNormal();
518  }
519  return *this;
520  }
521 
522  Angle& operator *= (const double& fact) {
523  fixRadian();
524  Radian *= fact;
525  recalcNormal();
526  return *this;
527  }
528 
529  Angle& rotate90deg() { Normal.rotate90deg(); Radian += 0.5*M_PI; return *this; }
530  Angle& rotate180deg() { Normal.rotate180deg(); Radian += M_PI; return *this; }
531  Angle& rotate270deg() { Normal.rotate270deg(); Radian += 1.5*M_PI; return *this; }
532 
533  Angle operator-() const { return Angle(Vector(Normal).negy(), 2*M_PI-Radian); } // unary minus
534  };
535 
536  inline Angle operator+(const Angle& a1, const Angle& a2) { return Angle(a1) += a2; }
537  inline Angle operator-(const Angle& a1, const Angle& a2) { return Angle(a1) -= a2; }
538 
539  inline Angle operator*(const Angle& a, const double& fact) { return Angle(a) *= fact; }
540  inline Angle operator/(const Angle& a, const double& divi) { return Angle(a) *= (1.0/divi); }
541 
542  extern const Angle Northwards, Westwards, Southwards, Eastwards;
543 
544  // ---------------------
545  // some helpers
546 
547  // pythagoras:
548 
549  inline double hypotenuse(double cath1, double cath2) { return hypot(cath1, cath2); }
550  inline double cathetus(double hypotenuse, double cathetus) {
551  aw_assert(hypotenuse>cathetus);
552  return sqrt(hypotenuse*hypotenuse - cathetus*cathetus);
553  }
554 
555 #if defined(DEBUG)
556  // don't use these in release code - they are only approximations!
557 
558  // test whether two doubles are "equal" (slow - use for assertions only!)
559  inline bool are_equal(const double& d1, const double& d2) {
560  double diff = std::abs(d1-d2);
561  return diff < 0.000001;
562  }
563 
564  inline bool are_orthographic(const Vector& v1, const Vector& v2) { // orthogonal (dt.)
565  return are_equal(scalarProduct(v1, v2), 0);
566  }
567 
568 #endif // DEBUG
569 
570  inline bool isOrigin(const Position& p) {
571  return p.xpos() == 0 && p.ypos() == 0;
572  }
573 
574 #if defined(DEBUG)
575  inline void aw_dump(const double& p, const char *varname) {
576  fprintf(stderr, "%s=%f", varname, p);
577  }
578  inline void aw_dump(const Position& p, const char *varname) {
579  fprintf(stderr, "Position %s={ ", varname);
580  aw_dump(p.xpos(), "x"); fputs(", ", stderr);
581  aw_dump(p.ypos(), "y"); fputs(" }", stderr);
582  }
583  inline void aw_dump(const Vector& v, const char *varname) {
584  fprintf(stderr, "Vector %s={ ", varname);
585  aw_dump(v.x(), "x"); fputs(", ", stderr);
586  aw_dump(v.y(), "y"); fputs(" }", stderr);
587  }
588  inline void aw_dump(const Angle& a, const char *varname) {
589  fprintf(stderr, "Angle %s={ ", varname);
590  aw_dump(a.degrees(), "degrees()"); fputs(" }", stderr);
591  }
592  inline void aw_dump(const LineVector& v, const char *varname) {
593  fprintf(stderr, "LineVector %s={ ", varname);
594  aw_dump(v.start(), "start"); fputs(", ", stderr);
595  aw_dump(v.line_vector(), "line_vector"); fputs(" }", stderr);
596 
597  }
598  inline void aw_dump(const Rectangle& r, const char *varname) {
599  fprintf(stderr, "Rectangle %s={ ", varname);
600  aw_dump(r.upper_left_corner(), "upper_left_corner"); fputs(", ", stderr);
601  aw_dump(r.lower_right_corner(), "lower_right_corner"); fputs(" }", stderr);
602  }
603 
604 #define AW_DUMP(x) do { aw_dump(x, #x); fputc('\n', stderr); } while(0)
605 
606 #endif
607 
608  inline AW_pos x_alignment(AW_pos x_pos, AW_pos x_size, AW_pos alignment) {
609  return x_pos - x_size*alignment;
610  }
611 };
612 
613 #else
614 #error aw_position.hxx included twice
615 #endif // AW_POSITION_HXX
Angle & rotate90deg()
Vector & rotate315deg()
Position nearest_corner(const Position &topos) const
Definition: AW_position.cxx:67
Position get_corner(int i) const
bool valid() const
Vector & negx()
bool are_antiparallel(const Vector &v1, const Vector &v2)
returns true, if two vectors have opposite orientations
Angle operator-() const
Vector & rotate135deg()
Vector & operator/=(const double &divisor)
Vector & rotate90deg()
LineVector(double X1, double Y1, double X2, double Y2)
bool valid() const
double centroid(const double &val1, const double &val2)
Definition: aw_position.hxx:77
Vector & flipxy()
Angle(double Radian_)
LineVector smaller_extent() const
void move(const Vector &movement)
Position centroid() const
static char * y[maxsp+1]
bool has_length() const
bool valid() const
LineVector lower_edge() const
bool nearlyEqual(const double &val1, const double &val2)
Definition: aw_position.hxx:75
const double & radian() const
Vector & set(const double &X, const double &Y, double Length=-1)
Vector & operator-=(const Vector &other)
bool is_empty() const
Definition: aw_position.hxx:69
void fixRadian() const
double width() const
LineVector bigger_extent() const
Rectangle bounding_box(const Position &pos) const
Rectangle bounding_box(const Rectangle &r1, const Rectangle &r2)
Vector operator*(const Vector &v, const double &f)
Angle(const Position &p1, const Position &p2)
Vector & neg()
double right() const
Position nearest_linepoint(const Position &pos, const LineVector &line, double &factor)
LineVector horizontal_extent() const
Angle(const Angle &a)
bool contains(const LineVector &lvec) const
bool distinct_from(const Rectangle &rect) const
Angle & operator*=(const double &fact)
Vector(const double &X, const double &Y, const double &Length)
Rectangle(const Position &corner, const Position &opposite_corner)
const Angle Southwards
CONSTEXPR_INLINE bool is_nan(const T &n)
Definition: arbtools.h:177
double top() const
double length() const
Rectangle(double X1, double Y1, double X2, double Y2)
bool nearlyZero(const double &val)
Definition: aw_position.hxx:76
Vector & sety(const double &Y)
const double & cos() const
const Angle Westwards
const Vector & normal() const
#define M_PI
RoughDirection
Vector & operator*=(const double &factor)
Angle & rotate180deg()
LineVector left_edge() const
Vector & set_length(double new_length)
void standardize()
Rectangle(const AW_screen_area &r, AW_screen_area_conversion_mode mode)
const Vector ZeroVector
CONSTEXPR_INLINE bool is_nan_or_inf(const T &n)
Definition: arbtools.h:178
void sety(const double &Y)
const double EPSILON
Definition: aw_position.hxx:73
#define ISVALID(a)
Definition: aw_position.hxx:45
void moveTo(const Position &pos)
bool isOrigin(const Position &p)
const Position & start() const
static int diff(int v1, int v2, int v3, int v4, int st, int en)
Definition: ClustalV.cxx:534
double AW_pos
Definition: aw_base.hxx:29
Vector & setx(const double &X)
static const double deg2rad
bool somehow() const
Definition: aw_position.hxx:70
bool are_parallel(const Vector &v1, const Vector &v2)
Vector & rotate270deg()
const double & sin() const
double surface() const
Angle & operator-=(const Angle &o)
Angle & operator+=(const Angle &o)
const double & ypos() const
Angle & operator=(const Angle &other)
Angle & rotate270deg()
Rectangle intersect_with(const Rectangle &rect) const
bool is_shaded() const
Definition: aw_position.hxx:68
Style get_style() const
Definition: aw_position.hxx:66
Vector(const double &X, const double &Y)
LineVector reverse() const
Vector & rotate180deg()
double hypotenuse(double cath1, double cath2)
FillStyle(Style filled)
Definition: aw_position.hxx:64
#define aw_assert(bed)
Definition: aw_position.hxx:29
double height() const
LineVector vertical_extent() const
Position lower_left_corner() const
bool are_distinct(const Position &p1, const Position &p2)
const Angle Northwards
Vector & rotate225deg()
LineVector(const Position &startpos, const Vector &to_end)
Angle(double x, double y)
Position crosspoint(const LineVector &l1, const LineVector &l2, double &factor_l1, double &factor_l2)
Definition: AW_position.cxx:84
const Position & endpoint() const
Vector operator-(const Position &to, const Position &from)
const Position & upper_left_corner() const
#define CONSTEXPR_INLINE
Definition: cxxforward.h:111
Position & operator+=(const Vector &v)
Angle(const Vector &v)
void movey(const double &Y)
Position(double X, double Y)
void moveTo(const Position &pos)
Vector normalized(const Vector &v)
bool is_vertical(const Vector &v)
void standardize()
Definition: AW_position.cxx:28
const double & y() const
Vector & negy()
double cathetus(double hypotenuse, double cathetus)
void setx(const double &X)
Position operator+(const Position &p, const Vector &v)
LineVector(const AW_screen_area &r, AW_screen_area_conversion_mode mode)
Rectangle(const Position &corner, const Vector &to_opposite_corner)
LineVector(const AW_world &r)
const double & ypos() const
bool is_between(const double &coord1, const double &between, const double &coord2)
Definition: aw_position.hxx:99
void movex(const double &X)
Vector orthogonal_projection(const Vector &projectee, const Vector &target)
Vector & operator+=(const Vector &other)
double scalarProduct(const Vector &v1, const Vector &v2)
const Vector & diagonal() const
Rectangle bounding_box(const Rectangle &rect) const
Vector operator/(const Vector &v, const double &d)
Vector(const Position &from, const Position &to)
const Vector & line_vector() const
bool valid() const
double bottom() const
static const double rad2deg
double left() const
fputs(TRACE_PREFIX, stderr)
const Angle Eastwards
Rectangle(const AW_world &r)
const double & length() const
bool contains(const Position &pos) const
bool has_length() const
Vector & rotate45deg()
Definition: AW_position.cxx:51
LineVector upper_edge() const
bool is_between(const Position &p1, const Position &p2) const
bool overlaps_with(const Rectangle &rect) const
Position upper_right_corner() const
bool is_normalized() const
Vector & normalize()
double degrees() const
#define abs(x)
Definition: f2c.h:151
Angle(const Vector &n, double r)
Position head() const
double Distance(const Position &from, const Position &to)
AW_screen_area_conversion_mode
const double & xpos() const
static int line
Definition: arb_a2ps.c:296
Vector operator-() const
Rectangle(const LineVector &Diagonal)
CONSTEXPR_INLINE bool definesQuadrant(const RoughDirection rd)
Angle(const LineVector &lv)
Position lower_right_corner() const
Position & operator-=(const Vector &v)
LineVector(const Position &startpos, const Position &end)
LineVector right_edge() const
#define NONAN(d)
Definition: aw_position.hxx:46
Vector(const Position &to)
const Position Origin
bool is_horizontal(const Vector &v)
AW_pos x_alignment(AW_pos x_pos, AW_pos x_size, AW_pos alignment)
const double & x() const
void move(const Vector &movement)
const double & xpos() const