From 62e02582a41424625d2253b22055ccf36c78e4c6 Mon Sep 17 00:00:00 2001 From: hasufell Date: Sun, 1 Jun 2014 16:17:51 +0200 Subject: [PATCH] Make bezier calculation more modular --- src/bezier.c | 82 ++++++++++++++++++++++++++++++++++++++++++---------- src/bezier.h | 1 + 2 files changed, 67 insertions(+), 16 deletions(-) diff --git a/src/bezier.c b/src/bezier.c index edc08b3..7e979a6 100644 --- a/src/bezier.c +++ b/src/bezier.c @@ -30,39 +30,89 @@ #include +/* + * static function declarations + */ +static bool get_section_vec(vector *a, vector *b, vector *c, float section); + + +static bool get_section_vec(vector *a, vector *b, vector *c, float section) +{ + vector a_tmp, + b_tmp; + + if (!a || !b || !c) + return false; + + copy_vector(a, &a_tmp); + copy_vector(b, &b_tmp); + + set_null_vector(c); + + SUB_VECTORS(&a_tmp, &b_tmp, c); + VECTOR_LEN_SCAL_MUL(c, section, c); + ADD_VECTORS(c, b, c); + + return true; +} + +/** + * Get the reduced bezier curve which is of one degree less + * and strained between the defined sections of the old curve. + * + * @param bez the bezier curve the calcluate the next from + * @param new_bez the new bezier curve, with a newly + * allocated vector member [out] + * @param section the section which will be applied to all + * lines between the bezier vertices + * @return true/false for success/failure + */ +bool get_reduced_bez_curv(bez_curv *bez, bez_curv *new_bez, float section) +{ + vector *vec_arr = malloc(sizeof(*vec_arr) * bez->deg); + + for (uint32_t i = 0; i < bez->deg; i++) { + vector new_vec; + + get_section_vec(&(bez->vec[i + 1]), + &(bez->vec[i]), + &new_vec, + section); + + vec_arr[i] = new_vec; + } + + new_bez->vec = vec_arr; + new_bez->deg = bez->deg - 1; + + return new_bez; +} + /** * Calculate a point on the bezier curve according to the * bezier vertices. If section is set to 0.5 then it will * return the vector to the point in the middle of the curve. * - * @param obj the object holding the bezier vertices information + * @param bez the bezier curve the calcluate the point from * @param section the section which will be applied to all * lines between the bezier vertices - * @return the vector to the calculated point + * @return the vector to the calculated point, newly allocated */ vector *calculate_bezier_point(bez_curv *bez, float section) { - vector vec_arr[bez->deg]; - bez_curv new_bez; + bez_curv new_bez = { NULL, 0 }; - for (uint32_t i = 0; i < bez->deg; i++) { - vector new_vec; + free(new_bez.vec); - SUB_VECTORS(&(bez->vec[i + 1]), &(bez->vec[i]), &new_vec); - VECTOR_LEN_SCAL_MUL(&new_vec, section, &new_vec); - ADD_VECTORS(&new_vec, &(bez->vec[i]), &new_vec); - - vec_arr[i] = new_vec; - } - - new_bez.vec = vec_arr; - new_bez.deg = bez->deg - 1; + if (!get_reduced_bez_curv(bez, &new_bez, section)) + return NULL; if (new_bez.deg > 0) { return calculate_bezier_point(&new_bez, section); } else { vector *result_vector = malloc(sizeof(*result_vector)); - *result_vector = vec_arr[0]; + *result_vector = new_bez.vec[0]; + return result_vector; } } diff --git a/src/bezier.h b/src/bezier.h index ccbde1e..04dbafb 100644 --- a/src/bezier.h +++ b/src/bezier.h @@ -49,6 +49,7 @@ struct bez_curv { }; +bool get_reduced_bez_curv(bez_curv *bez, bez_curv *new_bez, float section); vector *calculate_bezier_point(bez_curv *bez, float section);