/* changes line 37 for Linux - Markus Neteler (Jan. 1998) */ /*****************************************************************************/ /*** ***/ /*** feature() ***/ /*** Returns a terrain feature based on the 6 quadratic coefficents ***/ /*** that define a local trend surface. ***/ /*** Jo Wood, Department of Geography, V2.1 30th March, 1995 ***/ /*** ***/ /*****************************************************************************/ #include "param.h" #include DCELL feature(double *coeff) { /* Set of six quadratic coefficents. */ /* Quadratic function in the form of z = ax^2 + by^2 + cxy + dx + ey +f */ double a = C_A * zscale, /* Scale parameters if necessary. */ b = C_B * zscale, c = C_C * zscale, d = C_D * zscale, e = C_E * zscale; double maxic, minic, /* Minimium and maximum curvature. */ slope, /* Slope. */ crosc; /* Cross-sectional curvature. */ minic = (-a - b - sqrt((a - b) * (a - b) + c * c)); maxic = (-a - b + sqrt((a - b) * (a - b) + c * c)); slope = RAD2DEG * atan(sqrt((d * d) + (e * e))); crosc = -2.0 * (b * d * d + a * e * e - c * d * e) / (d * d + e * e); /* Feature slope crosc maxic minic Peak 0 # +ve +ve Ridge 0 # +ve 0 +ve +ve # # Pass 0 # +ve -ve Plane 0 # 0 0 +ve 0 # # Channel 0 # 0 -ve +ve -ve # # Pit 0 # -ve -ve Table 5.3 Simplified feature classification criteria. # indicates undefined, or not part of selection criteria. http://www.geog.le.ac.uk/jwo/research/dem_char/thesis/05feat.htm */ /* Case 1: Surface is sloping. Cannot be a peak,pass or pit. Therefore calculate the cross-sectional curvature to characterise as channel, ridge or planar. */ if (slope > slope_tol) { if (crosc > curve_tol) { return (RIDGE); } else if (crosc < -curve_tol) { return (CHANNEL); } else { return (FLAT); } } else { /* Case 2: Surface has (approximately) vertical slope normal. Feature can be of any type. */ if (maxic > curve_tol) { if (minic > curve_tol) { return (PEAK); } else if (minic < -curve_tol) { return (PASS); } else { return (RIDGE); } } else if (maxic < -curve_tol) { if (minic < -curve_tol) { return (PIT); } } else { if (minic < -curve_tol) { return (CHANNEL); } else if (minic > curve_tol && minic < -curve_tol) { return (FLAT); } } } return (FLAT); }