From cf7e4ccad0ecc07ad916e516f84f9955e0a42449 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Fri, 24 Aug 2018 16:15:36 +0200 Subject: [PATCH] trigonometric operations added --- trigonometric/bounding-box.c | 60 ++++++++++++++++++++++++++++++- trigonometric/bounding-box.h | 2 +- trigonometric/vector-operations.c | 35 ++++++++++++++++-- trigonometric/vector-operations.h | 10 ++++-- 4 files changed, 100 insertions(+), 7 deletions(-) diff --git a/trigonometric/bounding-box.c b/trigonometric/bounding-box.c index 93c595e..df8b873 100644 --- a/trigonometric/bounding-box.c +++ b/trigonometric/bounding-box.c @@ -25,9 +25,11 @@ #include #include "bounding-box.h" +#include #define MIN(a,b) (((a) < (b)) ? (a) : (b)) /**< @brief Return smaller number */ #define MAX(a,b) (((a) > (b)) ? (a) : (b)) /**< @brief Return bigger number */ +#define ABS_DBL(a) ((a) < 0 ? -(a) : (a)) void bounding_box_calculate_polygon(GList *vertices, conv_generic_to_vector_2d_t conv_func, union bounding_box *box) { @@ -41,7 +43,10 @@ void bounding_box_calculate_polygon(GList *vertices, conv_generic_to_vector_2d_t for (list_item = vertices; list_item != NULL; list_item = g_list_next(list_item)) { /* Convert generic vertex to vector_2d */ - conv_func((void *)list_item->data, &temp_vec); + if (conv_func) + conv_func((void *)list_item->data, &temp_vec); + else + vector_2d_copy(&temp_vec, (struct vector_2d *)list_item->data); /* Update bounding coordinates with vertex */ xmin = MIN(xmin, temp_vec.x); @@ -79,3 +84,56 @@ void bounding_box_prepare_empty(union bounding_box *box) box->vectors.upper_right.x = DBL_MIN; box->vectors.upper_right.y = DBL_MIN; } + +static void calculate_path_miter_points(struct vector_2d *a, struct vector_2d *b, struct vector_2d *c, + struct vector_2d *m1, struct vector_2d *m2, double width) +{ + double angle, angle_sin, u; + struct vector_2d ba, bc, u_vec, v_vec, ba_norm; + + if (!a || !b || !c || !m1 || !m2) + return; + + vector_2d_subtract(&ba, a, b); + vector_2d_subtract(&bc, c, b); + + angle = vector_2d_calculate_angle_between(&ba, &bc); + + if (ABS_DBL(angle) < 0.05 || ABS_DBL(angle - M_PI) < 0.1) { + /* Specail cases Don*/ + vector_2d_copy(&ba_norm, &ba); + vector_2d_rotate(&ba_norm, DEG2RAD(90)); + vector_2d_normalize(&ba_norm); + vector_2d_scale(&ba_norm, width/2.0); + vector_2d_add(m1, b, &ba_norm); + vector_2d_subtract(m2, b, &ba_norm); + return; + } + angle_sin = sin(angle); + u = width/(2*angle_sin); + + vector_2d_copy(&u_vec, &ba); + vector_2d_copy(&v_vec, &bc); + vector_2d_normalize(&u_vec); + vector_2d_normalize(&v_vec); + vector_2d_scale(&u_vec, u); + vector_2d_scale(&v_vec, u); + + vector_2d_copy(m1, b); + vector_2d_add(m1, m1, &u_vec); + vector_2d_add(m1, m1, &v_vec); + + vector_2d_copy(m2, b); + vector_2d_subtract(m2, m2, &u_vec); + vector_2d_subtract(m2, m2, &v_vec); +} + +void bounding_box_calculate_path_box(GList *vertices, conv_generic_to_vector_2d_t conv_func, union bounding_box *box) +{ + +} + +void bounding_box_update_point(union bounding_box *destination, conv_generic_to_vector_2d_t conv_func, void *pt) +{ + +} diff --git a/trigonometric/bounding-box.h b/trigonometric/bounding-box.h index 33e7d39..d524c47 100644 --- a/trigonometric/bounding-box.h +++ b/trigonometric/bounding-box.h @@ -41,5 +41,5 @@ typedef void (*conv_generic_to_vector_2d_t)(void *, struct vector_2d *); void bounding_box_calculate_polygon(GList *vertices, conv_generic_to_vector_2d_t conv_func, union bounding_box *box); void bounding_box_update_box(union bounding_box *destination, union bounding_box *update); void bounding_box_prepare_empty(union bounding_box *box); - +void bounding_box_update_point(union bounding_box *destination, conv_generic_to_vector_2d_t conv_func, void *pt); #endif /* _BOUNDING_BOX_H_ */ diff --git a/trigonometric/vector-operations.c b/trigonometric/vector-operations.c index f9e110d..6796687 100644 --- a/trigonometric/vector-operations.c +++ b/trigonometric/vector-operations.c @@ -27,6 +27,8 @@ #include #include +#define ABS_DBL(a) ((a) < 0 ? -(a) : (a)) + double vector_2d_scalar_multipy(struct vector_2d *a, struct vector_2d *b) { if (a && b) @@ -35,7 +37,7 @@ double vector_2d_scalar_multipy(struct vector_2d *a, struct vector_2d *b) return 0.0; } -void vector_2d_normaize(struct vector_2d *vec) +void vector_2d_normalize(struct vector_2d *vec) { double len; if (!vec) @@ -53,14 +55,14 @@ void vector_2d_rotate(struct vector_2d *vec, double angle) sin_val = sin(angle); cos_val = cos(angle); - vecor_2d_copy(&temp, vec); + vector_2d_copy(&temp, vec); /* Apply rotation matrix */ vec->x = (cos_val * temp.x) - (sin_val * temp.y); vec->y = (sin_val * temp.x) + (cos_val * temp.y); } -struct vector_2d *vecor_2d_copy(struct vector_2d *opt_res, struct vector_2d *vec) +struct vector_2d *vector_2d_copy(struct vector_2d *opt_res, struct vector_2d *vec) { struct vector_2d *res; @@ -109,3 +111,30 @@ double vector_2d_abs(struct vector_2d *vec) } return len; } + +double vector_2d_calculate_angle_between(struct vector_2d *a, struct vector_2d *b) +{ + double cos_angle; + + if (!a || !b) + return 0.0; + + cos_angle = ABS_DBL(vector_2d_scalar_multipy(a, b)) / (vector_2d_abs(a) * vector_2d_abs(b)); + return acos(cos_angle); +} + +void vector_2d_subtract(struct vector_2d *res, struct vector_2d *a, struct vector_2d *b) +{ + if (res && a && b) { + res->x = a->x - b->x; + res->y = a->y - b->y; + } +} + +void vector_2d_add(struct vector_2d *res, struct vector_2d *a, struct vector_2d *b) +{ + if (res && a && b) { + res->x = a->x +b->x; + res->y = a->y + b->y; + } +} diff --git a/trigonometric/vector-operations.h b/trigonometric/vector-operations.h index 59bfae5..3b98573 100644 --- a/trigonometric/vector-operations.h +++ b/trigonometric/vector-operations.h @@ -26,19 +26,25 @@ #ifndef _VECTOR_OPERATIONS_H_ #define _VECTOR_OPERATIONS_H_ +#include + struct vector_2d { double x; double y; }; +#define DEG2RAD(a) ((a)*M_PI/180.0) double vector_2d_scalar_multipy(struct vector_2d *a, struct vector_2d *b); void vector_2d_normalize(struct vector_2d *vec); -void vecor_2d_rotate(struct vector_2d *vec, double angle); -struct vector_2d *vecor_2d_copy(struct vector_2d *opt_res, struct vector_2d *vec); +void vector_2d_rotate(struct vector_2d *vec, double angle); +struct vector_2d *vector_2d_copy(struct vector_2d *opt_res, struct vector_2d *vec); struct vector_2d *vector_2d_alloc(void); void vector_2d_free(struct vector_2d *vec); void vector_2d_scale(struct vector_2d *vec, double scale); double vector_2d_abs(struct vector_2d *vec); +double vector_2d_calculate_angle_between(struct vector_2d *a, struct vector_2d *b); +void vector_2d_subtract(struct vector_2d *res, struct vector_2d *a, struct vector_2d *b); +void vector_2d_add(struct vector_2d *res, struct vector_2d *a, struct vector_2d *b); #endif /* _VECTOR_OPERATIONS_H_ */