source: tags/arb_5.0/WINDOW/AW_position.cxx

Last change on this file was 5675, checked in by westram, 15 years ago
  • removed automatic timestamps (the best they were good for, were vc-conflicts)
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 3.9 KB
Line 
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 <arb_assert.h>
13#define aw_assert(cond) arb_assert(cond)
14
15#include "aw_position.hxx"
16
17using namespace std;
18using namespace AW;
19
20const Position AW::Origin(0, 0);
21const Vector   AW::ZeroVector(0, 0, 0);
22
23const double AW::Angle::rad2deg = 180/M_PI;
24const double AW::Angle::deg2rad = M_PI/180;
25
26void LineVector::standardize() {
27    // make diagonal positive (i.e. make it a Vector which contains width and height of a Rectangle)
28    // this changes the start position to the upper-left corner
29
30    double dx = ToEnd.x();
31    double dy = ToEnd.y();
32
33    if (dx<0) {
34        if (dy<0) {
35            Start += ToEnd; // lower-right to upper-left
36            ToEnd.rotate180deg();
37        }
38        else {
39            Start.movex(dx); // upper-right to upper-left
40            ToEnd.negx();
41        }
42    }
43    else if (dy<0) {
44        Start.movey(dy); // lower-left to upper-left
45        ToEnd.negy();
46    }
47}
48
49Vector& Vector::rotate45deg() {
50    static double inv_sqrt2 = 1/sqrt(2.0);
51
52    *this = (*this+Vector(*this).rotate90deg()) * inv_sqrt2;
53    return *this;
54}
55
56void Angle::recalcRadian() const {
57    Radian = atan2(Normal.y(), Normal.x());
58}
59
60void Angle::recalcNormal() const {
61    Normal = Vector(std::cos(Radian), std::sin(Radian));
62    aw_assert(Normal.is_normalized());
63}
64
65// --------------------------------------------------------------------------------
66
67namespace AW {
68    Position crosspoint(const LineVector& l1, const LineVector& l2, double& factor_l1, double& factor_l2) {
69        // calculates the crossing point of the two staight lines defined by l1 and l2.
70        // sets two factors, so that
71        // crosspoint == l1.start()+factor_l1*l1.line_vector();
72        // crosspoint == l2.start()+factor_l2*l2.line_vector();
73
74        // Herleitung:
75        // x1+g*sx = x2+h*tx
76        // y1+g*sy = y2+h*ty
77        //
78        // h = -(x2-sx*g-x1)/tx                                       
79        // h = (y1-y2+sy*g)/ty                                        (h is factor_l2)
80        //
81        // -(x2-sx*g-x1)/tx = (y1-y2+sy*g)/ty
82        //
83        // g = (tx*y1+ty*x2-tx*y2-ty*x1)/(sx*ty-sy*tx)               
84        //
85        // g = (tx*(y1-y2)+ty*(x2-x1))/(sx*ty-sy*tx)                  (g is factor_l1)
86
87        const Position& p1 = l1.start();
88        const Position& p2 = l2.start();
89
90        const Vector& s = l1.line_vector();
91        const Vector& t = l2.line_vector();
92
93        factor_l1 = ( t.x()*(p1.ypos()-p2.ypos()) + t.y()*(p2.xpos()-p1.xpos()) )
94            / (s.x()*t.y() - s.y()*t.x());
95
96        factor_l2 = (p1.ypos()-p2.ypos()+s.y()*factor_l1) / t.y();
97
98        return p1 + factor_l1*s;
99    }
100
101    double Distance(const AW::Position pos, const AW::LineVector line) {
102        Vector upright(line.line_vector());
103        upright.rotate90deg();
104
105        LineVector pos2line(pos, upright);
106
107        double f1, f2;
108        Position cross = crosspoint(line, pos2line, f1, f2);
109
110        double dist;
111        if (f1 >= 0 && f1 <= 1) { // 'cross' is at 'line'
112            dist = Distance(pos, cross);
113        }
114        else if (f1<0) {
115            dist = Distance(pos, line.start());
116        }
117        else {
118            aw_assert(f1>1);
119            dist = Distance(pos, line.head());
120        }
121   
122        return dist;
123    }
124
125};
Note: See TracBrowser for help on using the repository browser.