diff options
| author | Jesper Jensen <jesper@jnsn.dev> | 2026-02-10 23:25:43 +0100 |
|---|---|---|
| committer | Jesper Jensen <jesper@jnsn.dev> | 2026-02-10 23:25:43 +0100 |
| commit | 73e446a99b3045a19bdd2be4238b4178502398ae (patch) | |
| tree | 13fc78a462f9cf3b7347451e11502efd7443fb4f | |
| parent | 2689a0c5cadc4e6b5f18f3cb276ad8d2e7451372 (diff) | |
Add place for examples
and fix some bugs that make the examples not work!
| -rw-r--r-- | Makefile | 16 | ||||
| -rw-r--r-- | examples/stacked.c | 115 | ||||
| -rw-r--r-- | src/construction.c | 4 | ||||
| -rw-r--r-- | src/solve.c | 2 |
4 files changed, 132 insertions, 5 deletions
@@ -4,6 +4,7 @@ SRCDIR ?= src INCDIR ?= inc OBJDIR ?= obj TSTDIR ?= test +EXMDIR ?= examples LIBS = -lm INCS = -Ithirdparty/cglm/include -Iinc/ @@ -24,7 +25,12 @@ TST_OBJS = $(TST_SOURCES:%.c=$(OBJDIR)/%.o) TST_DEPS = $(TST_OBJS:%.o=%.d) TST_APPS = $(TST_SOURCES:%.c=$(OBJDIR)/%) --include $(APP_DEPS) $(APP_MAIN_DEPS) $(TST_DEPS) +EXM_SOURCES = $(shell find $(EXMDIR) -name "*.c") +EXM_OBJS = $(EXM_SOURCES:%.c=$(OBJDIR)/%.o) +EXM_DEPS = $(EXM_OBJS:%.o=%.d) +EXM_APPS = $(EXM_SOURCES:%.c=$(OBJDIR)/%) + +-include $(APP_DEPS) $(APP_MAIN_DEPS) $(TST_DEPS) $(EXM_DEPS) # We don't really need to run the tests for bear to record them compile_commands.json: clean Makefile $(APP_SOURCES) @@ -42,6 +48,10 @@ $(OBJDIR)/test/%: $(OBJDIR)/test/%.o $(APP_OBJS) @mkdir -p $(dir $@) $(CC) $(LDFLAGS) $(CFLAGS) -o $@ $< $(APP_OBJS) $(LIBS) +$(OBJDIR)/examples/%: $(OBJDIR)/examples/%.o $(APP_OBJS) + @mkdir -p $(dir $@) + $(CC) $(LDFLAGS) $(CFLAGS) -o $@ $< $(APP_OBJS) $(LIBS) + clean: @rm -rf $(OBJDIR) @rm -f main @@ -50,5 +60,7 @@ test: $(TST_APPS) @echo "Running tests" @for t in $(TST_APPS); do echo "$$t"; $$t; done +examples: $(EXM_APPS) + .DEFAULT_GOAL := all -all: main test +all: main test examples diff --git a/examples/stacked.c b/examples/stacked.c new file mode 100644 index 0000000..256a682 --- /dev/null +++ b/examples/stacked.c @@ -0,0 +1,115 @@ +#include "cad.h" + +struct box { + struct component corner[4]; + struct component side[4]; +}; + +void a_box(struct box *box, struct topology *topo, struct constraints *constr) { + assert(box != NULL); + + *box = (struct box){ + .corner = { + {.type = COM_POINT}, + {.type = COM_POINT}, + {.type = COM_POINT}, + {.type = COM_POINT}, + }, + .side = { + {.type = COM_LINE}, + {.type = COM_LINE}, + {.type = COM_LINE}, + {.type = COM_LINE}, + }, + }; + + if(topo != NULL) { + add_fragment(topo, (struct topology_elem[]){ + TOPO_MOVETO(&box->corner[0]), + TOPO_LINETO(&box->corner[1]), + TOPO_LINETO(&box->corner[2]), + TOPO_LINETO(&box->corner[3]), + TOPO_LINETO(&box->corner[0]), + + TOPO_END(), + }); + } + + if(constr != NULL) { + add_constraint(constr, (struct constraint[]){ + POINT_ON_LINE(&box->corner[0], &box->side[0]), + POINT_ON_LINE(&box->corner[1], &box->side[0]), + + POINT_ON_LINE(&box->corner[1], &box->side[1]), + POINT_ON_LINE(&box->corner[2], &box->side[1]), + + POINT_ON_LINE(&box->corner[2], &box->side[2]), + POINT_ON_LINE(&box->corner[3], &box->side[2]), + + POINT_ON_LINE(&box->corner[0], &box->side[3]), + POINT_ON_LINE(&box->corner[3], &box->side[3]), + + LL_ANGLE(&box->side[3], &box->side[0], DEG(90)), + LL_ANGLE(&box->side[1], &box->side[2], DEG(90)), + LL_ANGLE(&box->side[2], &box->side[3], DEG(90)), + CEND(), + }); + } +} + +void draw_from_constraints(struct constraints *c, struct topology *t, struct canvas *cv) { + struct drawing drawing = {}; + bool rc = solve_constraints(c, &drawing); + assert(rc); + + // Copy over all the parameter values to a new array + // @PERF: Maybe we should just store them in a separate array to start with + double *params = malloc(sizeof(double) * (c->length)); + for(size_t i = 0; i < c->length; i++) { + params[i] = c->elements[i].v; + } + + place_points(&drawing, params); + free(params); + + begin_drawing(cv); + draw_topology(cv, t); + draw_constraints(cv, c); + end_drawing(cv); +} + +int main(int argc, char *argv[]) { + struct constraints constraints = {}; + struct topology topo = {}; + + struct box box1; + a_box(&box1, &topo, &constraints); + + struct box box2; + a_box(&box2, &topo, &constraints); + + struct box box3; + a_box(&box3, &topo, &constraints); + + add_constraint(&constraints, (struct constraint[]){ + PP_DISTANCE(&box1.corner[0], &box1.corner[1], 10), + PP_DISTANCE(&box1.corner[1], &box1.corner[2], 10), + + PP_SAME(&box2.corner[0], &box1.corner[3]), + PP_SAME(&box2.corner[1], &box1.corner[2]), + PP_DISTANCE(&box2.corner[1], &box2.corner[2], 10), + + PP_SAME(&box3.corner[0], &box2.corner[3]), + PP_DISTANCE(&box3.corner[1], &box3.corner[2], 10), + PP_DISTANCE(&box3.corner[0], &box3.corner[1], 7), + LL_ANGLE(&box3.side[0], &box1.side[0], DEG(-40)), + CEND(), + }); + + struct canvas canvas = { + .state = CANVAS_INIT, + .f = stdout, + }; + + draw_from_constraints(&constraints, &topo, &canvas); +} diff --git a/src/construction.c b/src/construction.c index 23f02a7..090a36f 100644 --- a/src/construction.c +++ b/src/construction.c @@ -36,9 +36,9 @@ bool circle_line_intersect(struct circle circle, struct line line, uint8_t root, } void line_through_points(struct point p1, struct point p2, struct line* l) { - l->norm[0] = p1.pos[1] - p1.pos[1]; + l->norm[0] = p1.pos[1] - p2.pos[1]; l->norm[1] = p2.pos[0] - p1.pos[0]; - l->C = p1.pos[1] * -l->norm[1] + p1.pos[0] * -l->norm[1]; + l->C = p1.pos[0] * -l->norm[0] + p1.pos[1] * -l->norm[1]; } void line_line_intersect(struct line l1, struct line l2, struct point* p) { diff --git a/src/solve.c b/src/solve.c index 5cdff63..3f8e081 100644 --- a/src/solve.c +++ b/src/solve.c @@ -342,7 +342,7 @@ static void draw_solution(struct constraint *constraints, size_t fix, struct sol struct element *distance = insert_cmd(drawing, (struct command){ .op = CMD_VALUE_INPUT, - .index = 0, + .index = fix, .dir = constraints[fix].forward, .result.type = ETYPE_VALUE, }); |
