123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- #include "local_proto.h"
- /* static double dirs[8] = { 0.7854, 0., 5.4978, 4.7124, 3.9270, 3.1416, 2.3562, 1.5708 };*/ /* radians */
- static double sins[8] = { 0.7071067812, 0, -0.7071067812, -1, -0.7071067812, 0, 0.7071067812, 1 }; /* sinus */
- static double coss[8] = { 0.7071067812, 1, 0.7071067812, 0, -0.7071067812, -1, -0.7071067812, 0 }; /* cosinus */
- /* DIRS in DEGREES from NORTH: 45,0,315,270,225,180,135,90 */
- unsigned int ternary_rotate(unsigned int value)
- {
- /* this function returns rotated and mirrored
- * ternary code from any number
- * function is used to create lookup table with original
- * terrain patterns (6561) and its rotated and mirrored counterparts (498)*/
- unsigned char pattern[8];
- unsigned char rev_pattern[8];
- unsigned char tmp_pattern[8];
- unsigned char tmp_rev_pattern[8];
- unsigned int code = 10000, tmp_code, rev_code = 10000, tmp_rev_code;
- int power = 1;
- int i, j, k;
- for (i = 0; i < 8; i++) {
- pattern[i] = value % 3;
- rev_pattern[7 - i] = value % 3;
- value /= 3;
- }
- for (j = 0; j < 8; j++) {
- power = 1;
- tmp_code = 0;
- tmp_rev_code = 0;
- for (i = 0; i < 8; i++) {
- k = (i - j) < 0 ? j - 8 : j;
- tmp_pattern[i] = pattern[i - k];
- tmp_rev_pattern[i] = rev_pattern[i - k];
- tmp_code += tmp_pattern[i] * power;
- tmp_rev_code += tmp_rev_pattern[i] * power;
- power *= 3;
- }
- code = tmp_code < code ? tmp_code : code;
- rev_code = tmp_rev_code < rev_code ? tmp_rev_code : rev_code;
- }
- return code < rev_code ? code : rev_code;
- }
- int determine_form(int num_minus, int num_plus)
- {
- /* determine form according number of positives and negatives
- * simple approach to determine form pattern */
- const FORMS forms[9][9] = {
- /* minus ------------- plus ---------------- */
- /* 0 1 2 3 4 5 6 7 8 */
- /* 0 */ {FL, FL, FL, FS, FS, VL, VL, VL, PT},
- /* 1 */ {FL, FL, FS, FS, FS, VL, VL, VL, __},
- /* 2 */ {FL, SH, SL, SL, CN, CN, VL, __, __},
- /* 3 */ {SH, SH, SL, SL, SL, CN, __, __, __},
- /* 4 */ {SH, SH, CV, SL, SL, __, __, __, __},
- /* 5 */ {RI, RI, CV, CV, __, __, __, __, __},
- /* 6 */ {RI, RI, RI, __, __, __, __, __, __},
- /* 7 */ {RI, RI, __, __, __, __, __, __, __},
- /* 8 */ {PK, __, __, __, __, __, __, __, __},
- };
- /* legend:
- FL, flat
- PK, peak, summit
- RI, ridge
- SH, shoulder
- CV, convex
- SL, slope
- CN, concave
- FS, footslope
- VL, valley
- PT, pit, depression
- __ error, impossible
- */
- return forms[num_minus][num_plus];
- }
- int determine_binary(int *pattern, int sign)
- {
- /* extract binary pattern for zenith (+) or nadir (-) from unrotated ternary pattern */
- int n, i;
- unsigned char binary = 0, result = 255, test = 0;
- for (i = 0, n = 1; i < 8; i++, n *= 2)
- binary += (pattern[i] == sign) ? n : 0;
- /* rotate */
- for (i = 0; i < 8; ++i) {
- if ((i &= 7) == 0)
- test = binary;
- else
- test = (binary << i) | (binary >> (8 - i));
- result = (result < test) ? result : test;
- }
- return (int)result;
- }
- int rotate(unsigned char binary)
- {
- int i;
- unsigned char result = 255, test = 0;
- /* rotate */
- for (i = 0; i < 8; ++i) {
- if ((i &= 7) == 0)
- test = binary;
- else
- test = (binary << i) | (binary >> (8 - i));
- result = (result < test) ? result : test;
- }
- return (int)result;
- }
- int determine_ternary(int *pattern)
- {
- /* extract rotated and mirrored ternary pattern form unrotated ternary pattern */
- unsigned ternary_code = 0;
- int power, i;
- for (i = 0, power = 1; i < 8; ++i, power *= 3)
- ternary_code += (pattern[i] + 1) * power;
- return global_ternary_codes[ternary_code];
- }
- float intensity(float *elevation, int pattern_size)
- {
- /* calculate relative elevation of the central cell against its visibility surround */
- float sum_elevation = 0.;
- int i;
- for (i = 0; i < 8; i++)
- sum_elevation -= elevation[i];
- return sum_elevation / (float)pattern_size;
- }
- float exposition(float *elevation)
- {
- /* calculate relative elevation of the central cell against its visibility */
- float max = 0.;
- int i;
- for (i = 0; i < 8; i++)
- max = fabs(elevation[i]) > fabs(max) ? elevation[i] : max;
- return -max;
- }
- float range(float *elevation)
- {
- /* calculate relative difference in visible range of central cell */
- float max = -90000000000., min = 9000000000000.; /* should be enough */
- int i;
- for (i = 0; i < 8; i++) {
- max = elevation[i] > max ? elevation[i] : max;
- min = elevation[i] < min ? elevation[i] : min;
- }
- return max - min;
- }
- float variance(float *elevation, int pattern_size)
- {
- /* calculate relative variation of the visible neighbourhood of the cell */
- float sum_elevation = 0;
- float variance = 0;
- int i;
- for (i = 0; i < 8; i++)
- sum_elevation += elevation[i];
- sum_elevation /= (float)pattern_size;
- for (i = 0; i < 8; i++)
- variance +=
- ((sum_elevation - elevation[i]) * (sum_elevation - elevation[i]));
- return variance / (float)pattern_size;
- }
- int radial2cartesian(PATTERN * pattern)
- {
- /* this function converts radial coordinates of geomorphon
- * (assuming center as 0,0) to cartezian coordinates
- * with the beginning in the central cell of geomorphon */
- int i;
- for (i = 0; i < 8; ++i)
- if (pattern->distance > 0) {
- pattern->x[i] = pattern->distance[i] * sins[i];
- pattern->y[i] = pattern->distance[i] * coss[i];
- }
- else {
- pattern->x[i] = 0;
- pattern->y[i] = 0;
- }
- return 0;
- }
- float extends(PATTERN * pattern, int pattern_size)
- {
- int i, j;
- float area = 0;
- for (i = 0, j = 1; i < 8; ++i, ++j) {
- j = j < 8 ? j : 0;
- area +=
- (pattern->x[i] * pattern->y[j] - pattern->x[j] * pattern->y[i]);
- }
- return fabs(area) / 2.;
- }
- int shape(PATTERN * pattern, int pattern_size, float *azimuth,
- float *elongation, float *width)
- {
- /* calculates azimuth, elongation and width of geomorphon's polygon */
- int i;
- double avg_x = 0, avg_y = 0;
- double avg_x_y = 0;
- double avg_x_square;
- double rx, ry;
- double sine, cosine;
- double result;
- double rxmin, rxmax, rymin, rymax;
- for (i = 0; i < 8; ++i) {
- avg_y += pattern->y[i];
- avg_x += pattern->x[i];
- avg_x_square += pattern->x[i] * pattern->x[i];
- avg_x_y += pattern->x[i] * pattern->y[i];
- }
- avg_y /= (float)pattern_size;
- avg_x /= (float)pattern_size;
- avg_x_y /= (float)pattern_size;
- avg_x_square /= (float)pattern_size;
- result = (avg_x_y - avg_x * avg_y) / (avg_x_square - avg_x * avg_x);
- result = atan(result);
- *azimuth = (float)RAD2DEGREE(PI2 - result);
- /* rotation */
- sine = sin(result);
- cosine = cos(result);
- for (i = 0; i < 8; ++i) {
- rx = pattern->x[i] * cosine - pattern->y[i] * sine;
- ry = pattern->x[i] * sine + pattern->y[i] * cosine;
- rxmin = rx < rxmin ? rx : rxmin;
- rxmax = rx > rxmax ? rx : rxmax;
- rymin = ry < rymin ? ry : rymin;
- rymax = ry > rymax ? ry : rymax;
- }
- rx = (rxmax - rxmin);
- ry = (rymax - rymin);
- *elongation = rx > ry ? (float)rx / ry : (float)ry / rx;
- *width = rx > ry ? ry : rx;
- return 0;
- }
|