Subversion Repositories public iLand

Rev

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
}