diff options
Diffstat (limited to 'test')
| -rw-r--r-- | test/solve.c | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/test/solve.c b/test/solve.c index ae54597..6213540 100644 --- a/test/solve.c +++ b/test/solve.c @@ -1,7 +1,31 @@ #include "cad/solve.h" +#include "cad/debug.h" #include <assert.h> +#include <math.h> #include <string.h> +static double point_line_distance_abs(struct point p, struct line l) { + return fabs((glm_vec2_dot(l.norm, p.pos) + l.C) / glm_vec2_norm(l.norm)); +} + +static double point_point_distance(struct point p1, struct point p2) { + vec2 between; + glm_vec2_sub(p1.pos, p2.pos, between); + return glm_vec2_norm(between); +} + +static double line_line_angle_abs(struct line l1, struct line l2) { + double dot = glm_vec2_dot(l1.norm, l2.norm); + double mag = glm_vec2_norm(l1.norm) * glm_vec2_norm(l2.norm); + double c = fabs(dot / mag); + c = fmin(1.0, fmax(-1.0, c)); + return acos(c); +} + +static void assert_near(double actual, double expected) { + assert(fabs(actual - expected) < 1e-6); +} + int main(int argc, char *argv[]) { struct subassembly assemblies[16] = {}; size_t assemblies_num; @@ -69,6 +93,105 @@ int main(int argc, char *argv[]) { memset(assemblies, 0, sizeof(assemblies)); { + printf("Corner by point-on-line root\n"); + struct constraints constraints = {}; + + struct component base = {.type = COM_LINE}; + struct component side = {.type = COM_LINE}; + struct component corner = {.type = COM_POINT}; + struct component tip = {.type = COM_POINT}; + + add_constraint(&constraints, (struct constraint[]){ + POINT_ON_LINE(&corner, &base), + POINT_ON_LINE(&corner, &side), + LL_ANGLE(&base, &side, DEG(90)), + PL_DISTANCE(&tip, &base, 10), + PL_DISTANCE(&tip, &side, -20), + CEND(), + }); + + struct drawing drawing = {}; + bool solved = solve_constraints(&constraints, &drawing, assemblies, &assemblies_num); + + assert(solved); + assert(assemblies_num == 1); + assert(drawing.root != NULL); + + double *params = malloc(sizeof(double) * constraints.length); + for(size_t i = 0; i < constraints.length; i++) { + params[i] = constraints.elements[i].v; + } + place_points(&drawing, params); + free(params); + + assert(corner.e != NULL); + assert(tip.e != NULL); + assert(base.e != NULL); + assert(side.e != NULL); + + print_subassemblies(&constraints, assemblies, assemblies_num); + + assert_near(point_line_distance_abs(corner.e->point, base.e->line), 0.0); + assert_near(point_line_distance_abs(corner.e->point, side.e->line), 0.0); + assert_near(line_line_angle_abs(base.e->line, side.e->line), DEG(90)); + assert_near(point_line_distance_abs(tip.e->point, base.e->line), 10.0); + assert_near(point_line_distance_abs(tip.e->point, side.e->line), 20.0); + + free_drawing(&drawing); + free_constraints(&constraints); + } + + memset(assemblies, 0, sizeof(assemblies)); + { + printf("Corner by offset point-line root\n"); + struct constraints constraints = {}; + + struct component base = {.type = COM_LINE}; + struct component side = {.type = COM_LINE}; + struct component corner = {.type = COM_POINT}; + struct component tip = {.type = COM_POINT}; + + add_constraint(&constraints, (struct constraint[]){ + PL_DISTANCE(&corner, &base, 5), + POINT_ON_LINE(&corner, &side), + LL_ANGLE(&base, &side, DEG(90)), + PL_DISTANCE(&tip, &base, 10), + PL_DISTANCE(&tip, &side, -20), + CEND(), + }); + + struct drawing drawing = {}; + bool solved = solve_constraints(&constraints, &drawing, assemblies, &assemblies_num); + + assert(solved); + assert(assemblies_num == 1); + assert(drawing.root != NULL); + + double *params = malloc(sizeof(double) * constraints.length); + for(size_t i = 0; i < constraints.length; i++) { + params[i] = constraints.elements[i].v; + } + place_points(&drawing, params); + free(params); + + assert(corner.e != NULL); + assert(tip.e != NULL); + assert(base.e != NULL); + assert(side.e != NULL); + + assert_near(point_line_distance_abs(corner.e->point, base.e->line), 5.0); + assert_near(point_line_distance_abs(corner.e->point, side.e->line), 0.0); + assert_near(line_line_angle_abs(base.e->line, side.e->line), DEG(90)); + assert_near(point_line_distance_abs(tip.e->point, base.e->line), 10.0); + assert_near(point_line_distance_abs(tip.e->point, side.e->line), 20.0); + assert_near(point_point_distance(corner.e->point, tip.e->point), sqrt(425.0)); + + free_drawing(&drawing); + free_constraints(&constraints); + } + + memset(assemblies, 0, sizeof(assemblies)); + { printf("Two triangles sharing a point one defined by angles\n"); struct constraints constraints = {}; |
