Rev 38 | Rev 40 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1 | |||
3 | Werner | 2 | |
3 | #include "tree.h" |
||
16 | Werner | 4 | #include "core/grid.h" |
30 | Werner | 5 | #include "imagestamp.h" |
3 | Werner | 6 | |
38 | Werner | 7 | #include "core/stamp.h" |
8 | #include "treespecies.h" |
||
9 | |||
13 | Werner | 10 | Expression Tree::rScale=Expression(); |
11 | Expression Tree::hScale=Expression(); |
||
39 | Werner | 12 | FloatGrid *Tree::m_grid = 0; |
3 | Werner | 13 | Tree::Tree() |
14 | { |
||
38 | Werner | 15 | m_Dbh = 0; |
16 | m_Height = 0; |
||
17 | m_species = 0; |
||
3 | Werner | 18 | } |
38 | Werner | 19 | |
15 | Werner | 20 | /** get distance and direction between two points. |
38 | Werner | 21 | returns the distance (m), and the angle between PStart and PEnd (radians) in referenced param rAngle. */ |
3 | Werner | 22 | float dist_and_direction(const QPointF &PStart, const QPointF &PEnd, float &rAngle) |
23 | { |
||
24 | float dx = PEnd.x() - PStart.x(); |
||
25 | float dy = PEnd.y() - PStart.y(); |
||
26 | float d = sqrt(dx*dx + dy*dy); |
||
27 | // direction: |
||
28 | rAngle = atan2(dx, dy); |
||
29 | return d; |
||
30 | } |
||
31 | |||
30 | Werner | 32 | void Tree::stampOnGrid(ImageStamp& stamp, FloatGrid& grid) |
3 | Werner | 33 | { |
34 | |||
35 | // use formulas to derive scaling values... |
||
38 | Werner | 36 | rScale.setVar("height", m_Height); |
37 | rScale.setVar("dbh", m_Dbh); |
||
38 | hScale.setVar("height", m_Height); |
||
39 | hScale.setVar("dbh", m_Dbh); |
||
3 | Werner | 40 | |
41 | double r = rScale.execute(); |
||
42 | double h = hScale.execute(); |
||
43 | stamp.setScale(r, h); // stamp uses scaling values to calculate impact |
||
15 | Werner | 44 | mImpactRadius = r; |
3 | Werner | 45 | |
46 | float cell_value, r_cell, phi_cell; |
||
38 | Werner | 47 | QPoint ul = grid.indexAt(QPointF(m_Position.x()-r, m_Position.y()-r) ); |
48 | QPoint lr = grid.indexAt( QPointF(m_Position.x()+r, m_Position.y()+r) ); |
||
9 | Werner | 49 | QPoint centercell=grid.indexAt(position()); |
3 | Werner | 50 | grid.validate(ul); grid.validate(lr); |
51 | QPoint cell; |
||
52 | QPointF cellcoord; |
||
53 | int ix, iy; |
||
54 | mOwnImpact=0.f; |
||
6 | Werner | 55 | mImpactArea=0.f; |
3 | Werner | 56 | for (ix=ul.x(); ix<lr.x(); ix++) |
57 | for (iy=ul.y(); iy<lr.y(); iy++) { |
||
58 | cell.setX(ix); cell.setY(iy); |
||
32 | Werner | 59 | cellcoord = grid.cellCoordinates(cell); |
38 | Werner | 60 | r_cell = dist_and_direction(m_Position, cellcoord, phi_cell); |
9 | Werner | 61 | if (r_cell > r && cell!=centercell) |
3 | Werner | 62 | continue; |
63 | // get value from stamp at this location (given by radius and angle) |
||
64 | cell_value = stamp.get(r_cell, phi_cell); |
||
65 | // add value to cell |
||
6 | Werner | 66 | mOwnImpact+=(1. - cell_value); |
67 | mImpactArea++; |
||
68 | grid.valueAtIndex(cell)*=cell_value; |
||
3 | Werner | 69 | } |
70 | } |
||
71 | |||
30 | Werner | 72 | float Tree::retrieveValue(ImageStamp& stamp, FloatGrid& grid) |
3 | Werner | 73 | { |
74 | |||
38 | Werner | 75 | rScale.setVar("height", m_Height); |
76 | rScale.setVar("dbh", m_Dbh); |
||
77 | hScale.setVar("height", m_Height); |
||
78 | hScale.setVar("dbh", m_Dbh); |
||
3 | Werner | 79 | double r = rScale.execute(); |
80 | double h = hScale.execute(); |
||
81 | stamp.setScale(r, h); // stamp uses scaling values to calculate impact |
||
82 | |||
7 | Werner | 83 | float stamp_value, cell_value, r_cell, phi_cell; |
38 | Werner | 84 | QPoint ul = grid.indexAt(QPointF(m_Position.x()-r, m_Position.y()-r) ); |
85 | QPoint lr = grid.indexAt( QPointF(m_Position.x()+r, m_Position.y()+r) ); |
||
9 | Werner | 86 | QPoint centercell=grid.indexAt(position()); |
3 | Werner | 87 | grid.validate(ul); grid.validate(lr); |
88 | QPoint cell; |
||
89 | QPointF cellcoord; |
||
90 | int ix, iy; |
||
91 | float value=0.f; |
||
92 | |||
93 | int counting_cells=0; |
||
94 | for (ix=ul.x(); ix<lr.x(); ix++) |
||
95 | for (iy=ul.y(); iy<lr.y(); iy++) { |
||
96 | |||
97 | cell.setX(ix); cell.setY(iy); |
||
32 | Werner | 98 | cellcoord = grid.cellCoordinates(cell); |
38 | Werner | 99 | r_cell = dist_and_direction(m_Position, cellcoord, phi_cell); |
9 | Werner | 100 | if (r_cell>r && cell!=centercell) |
3 | Werner | 101 | continue; |
102 | counting_cells++; |
||
103 | // get value from stamp at this location (given by radius and angle) |
||
7 | Werner | 104 | stamp_value = stamp.get(r_cell, phi_cell); |
105 | cell_value = grid.valueAtIndex(QPoint(ix,iy)); |
||
106 | if (stamp_value>0.) |
||
107 | value += cell_value / stamp_value; |
||
3 | Werner | 108 | // sum up values of cell |
109 | //value += cell_value; |
||
7 | Werner | 110 | //value += grid.valueAtIndex(QPoint(ix,iy)); // - cell_value; |
3 | Werner | 111 | } |
9 | Werner | 112 | if (counting_cells>0) |
113 | mImpact = value / float(counting_cells); |
||
114 | else |
||
115 | mImpact=1; |
||
3 | Werner | 116 | return mImpact; |
117 | } |
||
118 | |||
38 | Werner | 119 | |
120 | void Tree::setup() |
||
121 | { |
||
122 | if (m_Dbh<=0 || m_Height<=0) |
||
123 | return; |
||
124 | // check stamp |
||
125 | Q_ASSERT_X(m_species!=0, "Tree::setup()", "species is NULL"); |
||
126 | m_stamp = m_species->stamp(m_Dbh, m_Height); |
||
127 | } |
||
39 | Werner | 128 | |
129 | void Tree::applyStamp() |
||
130 | { |
||
131 | Q_ASSERT(m_grid!=0); |
||
132 | if (!m_stamp) |
||
133 | return; |
||
134 | |||
135 | } |