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