/* * Create a default curve */ static void stpi_curve_ctor(stp_curve_t *curve, stp_curve_wrap_mode_t wrap_mode) { curve->seq = stp_sequence_create(); stp_sequence_set_bounds(curve->seq, 0.0, 1.0); curve->curve_type = STP_CURVE_TYPE_LINEAR; curve->wrap_mode = wrap_mode; curve->piecewise = 0; stpi_curve_set_points(curve, 2); curve->recompute_interval = 1; if (wrap_mode == STP_CURVE_WRAP_NONE) curve->gamma = 1.0; stp_sequence_set_point(curve->seq, 0, 0); stp_sequence_set_point(curve->seq, 1, 1); }
int stp_array_set_point(stp_array_t *array, int x, int y, double data) { check_array(array); if (((array->x_size * x) + y) >= (array->x_size * array->y_size)) return 0; return stp_sequence_set_point(array->data, (array->x_size * x) + y, data);}
int stp_curve_set_point(stp_curve_t *curve, size_t where, double data) { CHECK_CURVE(curve); if (where >= get_point_count(curve)) return 0; curve->gamma = 0.0; if (curve->piecewise) return 0; if ((stp_sequence_set_point(curve->seq, where, data)) == 0) return 0; if (where == 0 && curve->wrap_mode == STP_CURVE_WRAP_AROUND) if ((stp_sequence_set_point(curve->seq, get_point_count(curve), data)) == 0) return 0; invalidate_auxiliary_data(curve); return 1; }
int stp_curve_set_data(stp_curve_t *curve, size_t count, const double *data) { size_t i; size_t real_count = count; double low, high; CHECK_CURVE(curve); if (count < 2) return 0; if (curve->wrap_mode == STP_CURVE_WRAP_AROUND) real_count++; if (real_count > curve_point_limit) return 0; /* Validate the data before we commit to it. */ stp_sequence_get_bounds(curve->seq, &low, &high); for (i = 0; i < count; i++) if (! isfinite(data[i]) || data[i] < low || data[i] > high) { stp_deprintf(STP_DBG_CURVE_ERRORS, "stp_curve_set_data: datum out of bounds: " "%g (require %g <= x <= %g), n = %ld\n", data[i], low, high, (long)i); return 0; } /* Allocate sequence; also accounts for WRAP_MODE */ stpi_curve_set_points(curve, count); curve->gamma = 0.0; stp_sequence_set_subrange(curve->seq, 0, count, data); if (curve->wrap_mode == STP_CURVE_WRAP_AROUND) stp_sequence_set_point(curve->seq, count, data[0]); curve->recompute_interval = 1; curve->piecewise = 0; return 1; }
int stp_curve_set_data_points(stp_curve_t *curve, size_t count, const stp_curve_point_t *data) { size_t i; size_t real_count = count; double low, high; double last_x = -1; CHECK_CURVE(curve); if (count < 2) { stp_deprintf(STP_DBG_CURVE_ERRORS, "stp_curve_set_data_points: too few points %ld\n", (long)count); return 0; } if (curve->wrap_mode == STP_CURVE_WRAP_AROUND) real_count++; if (real_count > curve_point_limit) { stp_deprintf(STP_DBG_CURVE_ERRORS, "stp_curve_set_data_points: too many points %ld\n", (long)real_count); return 0; } /* Validate the data before we commit to it. */ stp_sequence_get_bounds(curve->seq, &low, &high); for (i = 0; i < count; i++) { if (! isfinite(data[i].y) || data[i].y < low || data[i].y > high) { stp_deprintf(STP_DBG_CURVE_ERRORS, "stp_curve_set_data_points: datum out of bounds: " "%g (require %g <= x <= %g), n = %ld\n", data[i].y, low, high, (long)i); return 0; } if (i == 0 && data[i].x != 0.0) { stp_deprintf(STP_DBG_CURVE_ERRORS, "stp_curve_set_data_points: first point must have x=0\n"); return 0; } if (curve->wrap_mode == STP_CURVE_WRAP_NONE && i == count - 1 && data[i].x != 1.0) { stp_deprintf(STP_DBG_CURVE_ERRORS, "stp_curve_set_data_points: last point must have x=1\n"); return 0; } if (curve->wrap_mode == STP_CURVE_WRAP_AROUND && data[i].x >= 1.0 - .000001) { stp_deprintf(STP_DBG_CURVE_ERRORS, "stp_curve_set_data_points: horizontal value must " "not exceed .99999\n"); return 0; } if (data[i].x < 0 || data[i].x > 1) { stp_deprintf(STP_DBG_CURVE_ERRORS, "stp_curve_set_data_points: horizontal position out of bounds: " "%g, n = %ld\n", data[i].x, (long)i); return 0; } if (data[i].x - .000001 < last_x) { stp_deprintf(STP_DBG_CURVE_ERRORS, "stp_curve_set_data_points: horizontal position must " "exceed previous position by .000001: %g, %g, n = %ld\n", data[i].x, last_x, (long)i); return 0; } last_x = data[i].x; } /* Allocate sequence; also accounts for WRAP_MODE */ curve->piecewise = 1; stpi_curve_set_points(curve, count); curve->gamma = 0.0; stp_sequence_set_subrange(curve->seq, 0, count * 2, (const double *) data); if (curve->wrap_mode == STP_CURVE_WRAP_AROUND) { stp_sequence_set_point(curve->seq, count * 2, data[0].x); stp_sequence_set_point(curve->seq, count * 2 + 1, data[0].y); } curve->recompute_interval = 1; return 1; }