/*
 * - Stefano Menegon/Lorenzo Potrich: curvatures fixed Jan 2002 
 * - FP update Lorenzo Potrich/Markus Neteler Jan 2002
 * - Changes line 59 for Linux - Markus Neteler Jan 1998 
 */
/*****************************************************************************/
/***                                                                       ***/
/***                                param()                                ***/
/***     Returns a terrain parameter based on the 6 quadratic coefficents  ***/
/***	 that define a local trend surface. 			    	   ***/
/***     Jo Wood, Department of Geography, V2.0 15th December, 1994        ***/
/***                                                                       ***/
/*****************************************************************************/

#include "param.h"
#include <math.h>


DCELL param(int ptype,		/* Type of terrain parameter to calculate */
	   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,		/* Rescale coefficients if a 	  */
		b=C_B*zscale,		/* Z scaling is required.	  */
		c=C_C*zscale,
		d=C_D*zscale,
		e=C_E*zscale,
		f=C_F;			/* f does not need rescaling as   */
					/* it is only used for smoothing. */

    switch(ptype)
    {
	case ELEV:
		return(f);
		break;

	case SLOPE:
		return(atan(sqrt(d*d + e*e))*RAD2DEG);
		break;

	case ASPECT:
		return(atan2(e,d)*RAD2DEG);
		break;

	case PROFC:
		if ((d == 0) && (e == 0))
		    return(0.0);
		else
  		    return(-2.0*(a*d*d + b*e*e + c*e*d) / 
  			   	      ((e*e + d*d) * pow(1.0 + d*d + e*e,1.5))); 
		break;

	case PLANC:
		if ((d == 0) && (e == 0))
		    return(0.0);
		else
		    return(2.0*(b*d*d + a*e*e - c*d*e) /
		 		        pow(e*e + d*d,1.5));
		break;

	case LONGC:
		if ((d == 0) && (e ==0))
		    return(0.0);
		else	
		    return(-2.0*(a*d*d + b*e*e + c*d*e)/(d*d + e*e));
	case CROSC:
		if ((d == 0) && (e ==0))
		    return(0.0);
		else	
		    return(-2.0*(b*d*d + a*e*e - c*d*e)/(d*d + e*e));

	case MINIC:
		return(-a-b-sqrt((a-b)*(a-b) + c*c));

	case MAXIC:
		return(-a-b+sqrt((a-b)*(a-b) + c*c));

	default:
		return(0.0);
    }
}
