void miaux_piecewise_sinusoid( miScalar result[], int result_count, int key_count, miScalar key_positions[], miScalar key_values[]) { int key, i; for (key = 1; key < key_count; key++) { int start = (int)(key_positions[key-1] * result_count); int end = (int)(key_positions[key] * result_count) - 1; for (i = start; i <= end; i++) { result[i] = miaux_sinusoid_fit( i, start, end, key_values[key-1], key_values[key]); } } } double miaux_sinusoid_fit( double v, double oldmin, double oldmax, double newmin, double newmax) { return miaux_fit(sin(miaux_fit(v, oldmin, oldmax, -M_PI_2, M_PI_2)), -1, 1, newmin, newmax); } double miaux_fit( double v, double oldmin, double oldmax, double newmin, double newmax) { return newmin + ((v - oldmin) / (oldmax - oldmin)) * (newmax - newmin); } float miaux_altitude(miState *state) { miVector ray; mi_vector_to_world(state, &ray, &state->dir); mi_vector_normalize(&ray); return miaux_fit(asin(ray.y), -M_PI_2, M_PI_2, 0.0, 1.0); } miScalar miaux_interpolated_lookup(miScalar lookup_table[], int table_size, miScalar t) { int lower_index = (int)(t * (table_size - 1)); miScalar lower_value = lookup_table[lower_index]; int upper_index = lower_index + 1; miScalar upper_value = lookup_table[upper_index]; return miaux_fit( t * table_size, lower_index, upper_index, lower_value, upper_value); }