summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile16
-rw-r--r--examples/stacked.c115
-rw-r--r--src/construction.c4
-rw-r--r--src/solve.c2
4 files changed, 132 insertions, 5 deletions
diff --git a/Makefile b/Makefile
index 86f38e4..98e6346 100644
--- a/Makefile
+++ b/Makefile
@@ -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,
});