ARB
AW_position.cxx
Go to the documentation of this file.
1 // =============================================================== //
2 // //
3 // File : AW_position.cxx //
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 #include "aw_position.hxx"
13 
14 using namespace std;
15 using namespace AW;
16 
17 const Position AW::Origin(0, 0);
18 const Vector AW::ZeroVector(0, 0, 0);
19 
20 const double AW::Angle::rad2deg = 180/M_PI;
21 const double AW::Angle::deg2rad = M_PI/180;
22 
23 const Angle AW::Eastwards ( 0*Angle::deg2rad);
24 const Angle AW::Southwards( 90*Angle::deg2rad);
25 const Angle AW::Westwards (180*Angle::deg2rad);
26 const Angle AW::Northwards(270*Angle::deg2rad);
27 
28 void LineVector::standardize() {
29  // make diagonal positive (i.e. make it a Vector which contains width and height of a Rectangle)
30  // this changes the start position to the upper-left corner
31 
32  double dx = ToEnd.x();
33  double dy = ToEnd.y();
34 
35  if (dx<0) {
36  if (dy<0) {
37  Start += ToEnd; // lower-right to upper-left
38  ToEnd.rotate180deg();
39  }
40  else {
41  Start.movex(dx); // upper-right to upper-left
42  ToEnd.negx();
43  }
44  }
45  else if (dy<0) {
46  Start.movey(dy); // lower-left to upper-left
47  ToEnd.negy();
48  }
49 }
50 
51 Vector& Vector::rotate45deg() {
52  static double inv_sqrt2 = 1/sqrt(2.0);
53 
54  *this = (*this+Vector(*this).rotate90deg()) * inv_sqrt2;
55  return *this;
56 }
57 
58 void Angle::recalcRadian() const {
59  Radian = atan2(Normal.y(), Normal.x());
60 }
61 
62 void Angle::recalcNormal() const {
63  Normal = Vector(std::cos(Radian), std::sin(Radian));
64  aw_assert(Normal.is_normalized());
65 }
66 
67 Position Rectangle::nearest_corner(const Position& topos) const {
68  Position nearest = get_corner(0);
69  double mindist = Distance(nearest, topos);
70  for (int i = 1; i<4; ++i) {
71  Position c = get_corner(i);
72  double dist = Distance(c, topos);
73  if (dist<mindist) {
74  mindist = dist;
75  nearest = c;
76  }
77  }
78  return nearest;
79 }
80 
81 // --------------------------------------------------------------------------------
82 
83 namespace AW {
84  Position crosspoint(const LineVector& l1, const LineVector& l2, double& factor_l1, double& factor_l2) {
85  // calculates the crossing point of the two straight lines defined by l1 and l2.
86  // sets two factors, so that
87  // crosspoint == l1.start()+factor_l1*l1.line_vector();
88  // crosspoint == l2.start()+factor_l2*l2.line_vector();
89 
90  // Herleitung:
91  // x1+g*sx = x2+h*tx
92  // y1+g*sy = y2+h*ty
93  //
94  // h = -(x2-sx*g-x1)/tx
95  // h = (y1-y2+sy*g)/ty (h is factor_l2)
96  //
97  // -(x2-sx*g-x1)/tx = (y1-y2+sy*g)/ty
98  //
99  // g = (tx*y1+ty*x2-tx*y2-ty*x1)/(sx*ty-sy*tx)
100  //
101  // g = (tx*(y1-y2)+ty*(x2-x1))/(sx*ty-sy*tx) (g is factor_l1)
102 
103  const Position& p1 = l1.start();
104  const Position& p2 = l2.start();
105 
106  const Vector& s = l1.line_vector();
107  const Vector& t = l2.line_vector();
108 
109  aw_assert(s.has_length() && t.has_length());
110 
111  factor_l1 = (t.x()*(p1.ypos()-p2.ypos()) + t.y()*(p2.xpos()-p1.xpos()))
112  / (s.x()*t.y() - s.y()*t.x());
113 
114  factor_l2 = (p1.ypos()-p2.ypos()+s.y()*factor_l1) / t.y();
115 
116  return p1 + factor_l1*s;
117  }
118 
119  Position nearest_linepoint(const Position& pos, const LineVector& line, double& factor) {
120  // returns the Position on 'line' with minimum distance to 'pos'
121  // factor is set to [0.0 .. 1.0],
122  // where 0.0 means "at line.start()"
123  // and 1.0 means "at line.head()"
124 
125  if (!line.has_length()) {
126  factor = 0.5;
127  return line.start();
128  }
129 
130  Vector upright(line.line_vector());
131  upright.rotate90deg();
132 
133  LineVector pos2line(pos, upright);
134 
135  double unused;
136  Position nearest = crosspoint(line, pos2line, factor, unused);
137 
138  if (factor<0) {
139  nearest = line.start();
140  factor = 0;
141  }
142  else if (factor>1) {
143  nearest = line.head();
144  factor = 1;
145  }
146  return nearest;
147  }
148 };
149 
Vector & rotate90deg()
bool has_length() const
Position nearest_linepoint(const Position &pos, const LineVector &line, double &factor)
STL namespace.
const Angle Southwards
const Angle Westwards
#define M_PI
const Vector ZeroVector
const Position & start() const
static const double deg2rad
const double & ypos() const
ValueCounter< double > Distance
Definition: AP_Tree.cxx:1315
#define aw_assert(bed)
Definition: aw_position.hxx:29
const Angle Northwards
Position crosspoint(const LineVector &l1, const LineVector &l2, double &factor_l1, double &factor_l2)
Definition: AW_position.cxx:84
const double & y() const
const Vector & line_vector() const
static const double rad2deg
const Angle Eastwards
bool has_length() const
Position head() const
const double & xpos() const
static int line
Definition: arb_a2ps.c:296
const Position Origin
const double & x() const
GB_write_int const char s
Definition: AW_awar.cxx:154