source: tags/arb-6.0.4/WINDOW/AW_position.cxx

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