2 #include "hillshading.h"
29 static void getConstants(double azimuth
, double elevation
, Constants
&c
)
31 double alpha
= (M_PI
/ 180.0) * azimuth
;
32 double beta
= (M_PI
/ 180.0) * elevation
;
35 c
.a2
= cos(beta
) * sin(alpha
);
36 c
.a3
= cos(beta
) * cos(alpha
);
39 static void getDerivativesHorn(const SubMatrix
&sm
, double z
, Derivatives
&d
)
41 d
.dzdx
= (z
* (sm
.z3
+ 2 * sm
.z6
+ sm
.z9
- sm
.z1
- 2 * sm
.z4
- sm
.z7
)) / 8;
42 d
.dzdy
= (z
* (sm
.z1
+ 2 * sm
.z2
+ sm
.z3
- sm
.z7
- 2 * sm
.z8
- sm
.z9
)) / 8;
45 static void getSubmatrix(int x
, int y
, const Matrix
&m
, SubMatrix
&sm
)
52 sm
.z1
= m
.m(top
, left
);
54 sm
.z3
= m
.m(top
, right
);
56 sm
.z6
= m
.m(y
, right
);
57 sm
.z7
= m
.m(bottom
, left
);
58 sm
.z8
= m
.m(bottom
, x
);
59 sm
.z9
= m
.m(bottom
, right
);
62 QImage
HillShading::render(const Matrix
&m
, quint8 alpha
, double azimuth
,
65 QImage
img(m
.w() - 2, m
.h() - 2, QImage::Format_ARGB32_Premultiplied
);
66 uchar
*bits
= img
.bits();
67 int bpl
= img
.bytesPerLine();
72 double z
= (double)alpha
/ 0xFF;
74 getConstants(azimuth
, elevation
, c
);
76 for (int y
= 1; y
< m
.h() - 1; y
++) {
77 for (int x
= 1; x
< m
.w() - 1; x
++) {
78 getSubmatrix(x
, y
, m
, sm
);
79 getDerivativesHorn(sm
, z
, d
);
81 double L
= (c
.a1
- c
.a2
* d
.dzdx
- c
.a3
* d
.dzdy
)
82 / sqrt(1.0 + d
.dzdx
* d
.dzdx
+ d
.dzdy
* d
.dzdy
);
88 quint8 val
= (L
< 0) ? 0 : L
* alpha
;
89 pixel
= alpha
<<24 | val
<<16 | val
<<8 | val
;
92 *(quint32
*)(bits
+ (y
- 1) * bpl
+ (x
- 1) * 4) = pixel
;