source: tags/svn.1.5.4/WINDOW/AW_position.cxx

Last change on this file was 7622, checked in by westram, 14 years ago
  • merge from dev [7434] [7435] [7436] [7437] [7438] [7439] [7440] [7441] [7442] [7443] [7444]
    • AW_device
      • removed some derived-class-specific functions
      • virtual functions
        • removed default parameters, renamed them to XXX_impl, made them private and added missing variants to replace direct calls to renamed functions
      • added AW_simple_device as base for AW_device_click and AW_device_size
      • do not pass AW_CL/AW_CL for AW_device_click down through all paint functions, instead create instances of AW_click_cd
      • devirtualized ready_to_draw + cursor
      • added default for filter to all paint functions (removed default from calls)
      • XXX_impl functions use Position, Rectangle, Vector etc. instead of AW_pos
    • AW_common
      • removed unneccessary members; made members private
      • moved some code between AW_gc, AW_GC_Xm and AW_common
      • global data (color tables) now referenced by references instead of pointers
      • made independent member function x_alignment() global
      • no longer install resize callback from ctor
    • AW_clicked_line (renamed some members; removed distanceTo)
    • fixed possible return of temporaries
    • AW_root
      • made independent member functions font_2_ascii() and font_2_xfig() global (AW_font_2_ascii AW_font_2_xfig)
    • Tree display
      • client data changed (bootstrap text and vertical lines starting at bifurcation belong to son now)
  • 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()) return line.start();
107
108        Vector upright(line.line_vector());
109        upright.rotate90deg();
110
111        LineVector pos2line(pos, upright);
112
113        double   unused;
114        Position nearest = crosspoint(line, pos2line, factor, unused);
115
116        if (factor<0) {
117            nearest = line.start();
118            factor  = 0;
119        }
120        else if (factor>1) {
121            nearest = line.head();
122            factor  = 1;
123        }
124        return nearest;
125    }
126};
Note: See TracBrowser for help on using the repository browser.