summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/quad.c2
-rw-r--r--inc/cad/construction.h6
-rw-r--r--src/construction.c93
-rw-r--r--src/solve.c287
4 files changed, 292 insertions, 96 deletions
diff --git a/examples/quad.c b/examples/quad.c
index 878fba3..a22e872 100644
--- a/examples/quad.c
+++ b/examples/quad.c
@@ -17,6 +17,7 @@ void draw_from_constraints(struct constraints *c, struct topology *t, struct can
}
place_points(&drawing, params);
+ dump_program(&drawing, params);
free(params);
reconstruct_drawing(c, assemblies, &assemblies_num);
@@ -45,7 +46,6 @@ int main(int argc, char *argv[]) {
struct component l4 = {.type = COM_LINE};
add_constraint(&constraints, (struct constraint[]){
- // Make a triangle
PP_DISTANCE(&p1, &p2, 10),
PP_DISTANCE(&p4, &p1, 20),
diff --git a/inc/cad/construction.h b/inc/cad/construction.h
index 71add62..ea784cf 100644
--- a/inc/cad/construction.h
+++ b/inc/cad/construction.h
@@ -21,6 +21,11 @@ enum operation {
// Handle assemblies
CMD_IMPORT_POINT_LINE,
+ CMD_IMPORT_LINE_LINE,
+
+ // Measure elements
+ CMD_MEASURE_POINT_LINE_DISTANCE,
+ CMD_MEASURE_LINE_LINE_ANGLE,
};
struct point {
@@ -87,6 +92,7 @@ struct drawing {
struct element* insert_cmd(struct drawing *drawing, struct command cmd);
void place_points(struct drawing *drawing, double inputs[]);
+void dump_program(struct drawing *drawing, double inputs[]);
void free_drawing(struct drawing *drawing);
bool circle_line_intersect(struct circle circle, struct line line, uint8_t root, struct point *point);
diff --git a/src/construction.c b/src/construction.c
index 33f37ad..f175f79 100644
--- a/src/construction.c
+++ b/src/construction.c
@@ -87,6 +87,8 @@ static void transform_part(struct command *cmd, const struct command *last_cmd,
switch(cmd->op) {
case CMD_VALUE_INPUT:
case CMD_OFFSET_INPUT:
+ case CMD_MEASURE_POINT_LINE_DISTANCE:
+ case CMD_MEASURE_LINE_LINE_ANGLE:
break;
case CMD_LINE_X:
case CMD_LINE_POINT_POINT:
@@ -127,6 +129,7 @@ static void transform_part(struct command *cmd, const struct command *last_cmd,
break;
case CMD_IMPORT_POINT_LINE:
+ case CMD_IMPORT_LINE_LINE:
transform_part(cmd->d->first_command, cmd->d->last_command, transform);
break;
}
@@ -137,6 +140,64 @@ static void transform_part(struct command *cmd, const struct command *last_cmd,
}
}
+void dump_program(struct drawing *drawing, double inputs[]) {
+ for(struct command *current = drawing->root; current != NULL; current = current->next) {
+ switch(current->op) {
+ case CMD_VALUE_INPUT: {
+ fprintf(stderr, "%p -> LIT(%d, %f) = %f\n", &current->result, current->dir, inputs[current->index], current->result.value);
+ }break;
+ case CMD_OFFSET_INPUT: {
+ fprintf(stderr, "%p -> OFF(%f, %d, %f) = %f\n", &current->result, current->arg1->value, current->dir, inputs[current->index], current->result.value);
+ }break;
+ case CMD_ORIGIN: {
+ fprintf(stderr, "%p -> ZER() = <%f, %f>\n", &current->result, current->result.point.pos[0], current->result.point.pos[1]);
+ }break;
+ case CMD_LINE_X: {
+ fprintf(stderr, "%p -> LNX() = (%fx + %fy + %f = 0)\n", &current->result, current->result.line.norm[0], current->result.line.norm[1], current->result.line.C);
+ }break;
+ case CMD_CIRCLE_CENTER_RADIUS: {
+ fprintf(stderr, "%p -> CCR(%p, %p) = ((x-%f)^2 + (y-%f)^2 = %f^2)\n", &current->result, current->arg1, current->arg2, current->result.circle.center[0], current->result.circle.center[1], current->result.circle.radius);
+ }break;
+ case CMD_LINE_POINT_POINT: {
+ fprintf(stderr, "%p -> LPP(%p, %p) = (%fx + %fy + %f = 0)\n", &current->result, current->arg1, current->arg2, current->result.line.norm[0], current->result.line.norm[1], current->result.line.C);
+ }break;
+ case CMD_LINE_POINT_LINE_ANGLE: {
+ fprintf(stderr, "%p -> PLA(%p, %p, %p) = (%fx + %fy + %f = 0)\n", &current->result, current->arg1, current->arg2, current->arg3, current->result.line.norm[0], current->result.line.norm[1], current->result.line.C);
+ }break;
+ case CMD_LINE_LINE_DISTANCE_PARALLEL: {
+ fprintf(stderr, "%p -> LDP(%p, %p) = (%fx + %fy + %f = 0)\n", &current->result, current->arg1, current->arg2, current->result.line.norm[0], current->result.line.norm[1], current->result.line.C);
+ }break;
+ case CMD_LINE_CIRCLE_CIRCLE_TANGENT: {
+ fprintf(stderr, "%p -> CCT(%p, %p) = (%fx + %fy + %f = 0)\n", &current->result, current->arg1, current->arg2, current->result.line.norm[0], current->result.line.norm[1], current->result.line.C);
+ }break;
+ case CMD_POINT_CIRCLE_LINE: {
+ fprintf(stderr, "%p -> PCL(%p, %p) = <%f, %f>\n", &current->result, current->arg1, current->arg2, current->result.point.pos[0], current->result.point.pos[1]);
+ }break;
+ case CMD_POINT_CIRCLE_CIRCLE: {
+ fprintf(stderr, "%p -> PCC(%p, %p) = <%f, %f>\n", &current->result, current->arg1, current->arg2, current->result.point.pos[0], current->result.point.pos[1]);
+ }break;
+ case CMD_POINT_LINE_LINE: {
+ fprintf(stderr, "%p -> PLL(%p, %p) = <%f, %f>\n", &current->result, current->arg1, current->arg2, current->result.point.pos[0], current->result.point.pos[1]);
+ }break;
+ case CMD_CIRCLE_CENTER_POINT: {
+ fprintf(stderr, "%p -> CCR(%p, %p) = ((x-%f)^2 + (y-%f)^2 = %f^2)\n", &current->result, current->arg1, current->arg2, current->result.circle.center[0], current->result.circle.center[1], current->result.circle.radius);
+ }break;
+ case CMD_IMPORT_POINT_LINE: {
+ fprintf(stderr, "%p -> IMP(%p, %p, %p, %p) = <N/A>\n", &current->result, current->arg1, current->arg2, current->attachp, current->attachl);
+ }break;
+ case CMD_IMPORT_LINE_LINE: {
+ // Deprecated
+ }break;
+ case CMD_MEASURE_POINT_LINE_DISTANCE: {
+ fprintf(stderr, "%p -> MPL(%p, %p) = %f\n", &current->result, current->arg1, current->arg2, current->result.value);
+ }break;
+ case CMD_MEASURE_LINE_LINE_ANGLE: {
+ fprintf(stderr, "%p -> MLL(%p, %p) = %f\n", &current->result, current->arg1, current->arg2, current->result.value);
+ }break;
+ }
+ }
+}
+
void place_points(struct drawing *drawing, double inputs[]) {
struct command *outer_object = drawing->root;
@@ -272,28 +333,50 @@ void place_points(struct drawing *drawing, double inputs[]) {
assert(current->d != NULL);
assert(current->attachp != NULL);
assert(current->attachl != NULL);
+ assert(current->attachp->type == ETYPE_POINT);
+ assert(current->attachl->type == ETYPE_LINE);
double theta;
// Align the two lines
theta = atan2(current->arg2->line.norm[1], current->arg2->line.norm[0]) - atan2(current->attachl->line.norm[1], current->attachl->line.norm[0]);
- fprintf(stderr, "%f\n", theta / M_PI * 180.0);
mat3 transform;
glm_mat3_identity(transform);
- glm_translate2d(transform, current->attachp->point.pos);
+ glm_translate2d(transform, current->arg1->point.pos);
glm_rotate2d(transform, theta);
{
vec2 negative_translate;
- glm_vec2_negate_to(current->arg1->point.pos, negative_translate);
+ glm_vec2_negate_to(current->attachp->point.pos, negative_translate);
glm_translate2d(transform, negative_translate);
}
- fprintf(stderr, "Assembly %p %p %p %f\n", current->d, current->d->first_command, current->d->last_command, theta);
+ fprintf(stderr, "Assembly %p %p %p %f %f %f\n", current->d, current->d->first_command, current->d->last_command, transform[2][0], transform[2][1], theta);
transform_part(current->d->first_command, current->d->last_command, transform);
}break;
+ case CMD_IMPORT_LINE_LINE: {
+ abort();
+ }break;
+ case CMD_MEASURE_POINT_LINE_DISTANCE: {
+ assert(current->arg1->type == ETYPE_POINT);
+ assert(current->arg2->type == ETYPE_LINE);
+ assert(current->result.type == ETYPE_VALUE);
+
+ double dot = glm_vec2_dot(current->arg2->line.norm, current->arg1->point.pos);
+ current->result.value = (dot + current->arg2->line.C) / glm_vec2_norm(current->arg2->line.norm);
+ fprintf(stderr, "Measured Distance %f\n", current->result.value);
+ }break;
+ case CMD_MEASURE_LINE_LINE_ANGLE: {
+ assert(current->arg1->type == ETYPE_LINE);
+ assert(current->arg2->type == ETYPE_LINE);
+ assert(current->result.type == ETYPE_VALUE);
+
+ double theta = atan2(current->arg1->line.norm[1], current->arg1->line.norm[0]) - atan2(current->arg2->line.norm[1], current->arg2->line.norm[0]);
+ current->result.value = theta;
+ fprintf(stderr, "Measured Angle %f\n", current->result.value);
+ }break;
}
// printf("%fx + %fy + %f = 0\n", cmd[2].line.norm[0], cmd[2].line.norm[1], cmd[2].line.C);
}
@@ -323,7 +406,7 @@ void place_points(struct drawing *drawing, double inputs[]) {
glm_translate2d(transform, negative_translate);
}
- fprintf(stderr, "W %f %f\n", origin->result.point.pos[0], origin->result.point.pos[1]);
+ fprintf(stderr, "W %f %f %f\n", origin->result.point.pos[0], origin->result.point.pos[1], theta);
transform_part(outer_object, NULL, transform);
}
}
diff --git a/src/solve.c b/src/solve.c
index 353f052..0eab611 100644
--- a/src/solve.c
+++ b/src/solve.c
@@ -63,15 +63,15 @@ static void add_frontier(struct component *component) {
component->fixed = true;
}
-static void build_angle_point_line(struct drawing *drawing, struct constraint *constraints, size_t index_i, size_t index_j, struct component *local_i, struct component *local_j, struct component *oppo_i) {
- assert(local_i->e != NULL);
- assert(local_j->e != NULL);
- assert(local_i->type == COM_LINE);
- assert(local_j->type == COM_POINT);
+static void build_angle_point_line2(struct drawing *drawing, struct constraint *constraints, size_t index_i, size_t index_j, struct element *local_i, struct element *local_j, bool inverse, struct element **oppo_i) {
+ assert(local_i != NULL);
+ assert(local_j != NULL);
+ assert(local_i->type == ETYPE_LINE);
+ assert(local_j->type == ETYPE_POINT);
struct element *theta = insert_cmd(drawing, (struct command){
.op = CMD_VALUE_INPUT,
.index = index_i,
- .dir = constraints[index_i].forward,
+ .dir = constraints[index_i].forward ^ inverse,
.result.type = ETYPE_VALUE,
});
@@ -80,7 +80,7 @@ static void build_angle_point_line(struct drawing *drawing, struct constraint *c
.op = CMD_OFFSET_INPUT,
.arg1 = theta,
.index = p->i,
- .dir = p->direction,
+ .dir = p->direction ^ inverse,
.result.type = ETYPE_VALUE,
});
}
@@ -88,29 +88,33 @@ static void build_angle_point_line(struct drawing *drawing, struct constraint *c
struct element *d = insert_cmd(drawing, (struct command){
.op = CMD_VALUE_INPUT,
.index = index_j,
- .dir = constraints[index_i].forward,
+ .dir = constraints[index_i].forward ^ inverse,
.result.type = ETYPE_VALUE,
});
struct element* l = insert_cmd(drawing, (struct command){
.op = CMD_LINE_POINT_LINE_ANGLE,
- .hidden = !oppo_i->show_when_placed,
+ .hidden = false,
.result.type = ETYPE_LINE,
- .arg1 = local_j->e,
- .arg2 = local_i->e,
+ .arg1 = local_j,
+ .arg2 = local_i,
.arg3 = theta,
});
assert(l != NULL);
- oppo_i->e = insert_cmd(drawing, (struct command){
+ *oppo_i = insert_cmd(drawing, (struct command){
.op = CMD_LINE_LINE_DISTANCE_PARALLEL,
- .hidden = !oppo_i->show_when_placed,
+ .hidden = false,
.result.type = ETYPE_LINE,
.arg1 = l,
.arg2 = d,
});
}
+static void build_angle_point_line(struct drawing *drawing, struct constraint *constraints, size_t index_i, size_t index_j, struct component *local_i, struct component *local_j, struct component *oppo_i) {
+ return build_angle_point_line2(drawing, constraints, index_i, index_j, local_i->e, local_j->e, false, &oppo_i->e);
+}
+
struct solve_step {
size_t i;
size_t j;
@@ -549,7 +553,7 @@ static size_t build_triangles(struct constraints *constraints_in, struct compone
if(possibly_angle_c == NULL) continue;
- printf("Assembly %p and %p, %d %d %s %s\n", ein_a, ein_b, f1_c, f2_c, constraint_type_name[not_angle_c->type], constraint_type_name[possibly_angle_c->type]);
+ fprintf(stderr, "Assembly %p and %p, %d %d %s %s\n", ein_a, ein_b, f1_c, f2_c, constraint_type_name[not_angle_c->type], constraint_type_name[possibly_angle_c->type]);
// We've fixed the subcomponents, so we have to fix
// the whole thing
@@ -751,6 +755,65 @@ static void draw_for_subassembly(struct constraint *constraints, size_t fix, str
});
}
+void point_from_line_and_distance(struct drawing *drawing, struct constraint *constraints, size_t c1, size_t c2, struct element *line, struct element *point, int root, struct element **result) {
+ assert(line->type == ETYPE_LINE);
+ assert(point->type == ETYPE_POINT);
+
+ struct element *d1 = insert_cmd(drawing, (struct command){
+ .op = CMD_VALUE_INPUT,
+ .index = c1,
+ .dir = constraints[c1].forward,
+ .result.type = ETYPE_VALUE,
+ });
+ struct element *d2 = insert_cmd(drawing, (struct command){
+ .op = CMD_VALUE_INPUT,
+ .index = c2,
+ .dir = constraints[c2].forward,
+ .result.type = ETYPE_VALUE,
+ });
+
+ struct element *l = insert_cmd(drawing, (struct command){
+ .op = CMD_LINE_LINE_DISTANCE_PARALLEL,
+ .hidden = false,
+ .result.type = ETYPE_LINE,
+ .arg1 = line,
+ .arg2 = d1,
+ });
+
+ struct element *c = insert_cmd(drawing, (struct command){
+ .op = CMD_CIRCLE_CENTER_RADIUS,
+ .hidden = false,
+ .result.type = ETYPE_CIRCLE,
+ .arg1 = point,
+ .arg2 = d2,
+ });
+
+ *result = insert_cmd(drawing, (struct command){
+ .op = CMD_POINT_CIRCLE_LINE,
+ .hidden = false,
+ .root = root,
+ .result.type = ETYPE_POINT,
+ .arg1 = c,
+ .arg2 = l,
+ });
+}
+
+#define expand_constraint(NAME, IDX) \
+ struct constraint *NAME = &constraints[IDX]; \
+ struct component *NAME##_local; \
+ struct component *NAME##_oppo; \
+ do { \
+ if(IDX##_forward) { \
+ NAME##_local = constraints[IDX].c1; \
+ NAME##_oppo = constraints[IDX].c2; \
+ } else { \
+ NAME##_local = constraints[IDX].c2; \
+ NAME##_oppo = constraints[IDX].c1; \
+ } \
+ } while(0)
+
+
+
static void draw_for_double_subassembly(struct constraint *constraints, size_t fix, struct solve_step *step, struct drawing *drawing, struct subassembly *assembly) {
assert(step->assembly != NULL);
assert(step->assembly2 != NULL);
@@ -759,7 +822,123 @@ static void draw_for_double_subassembly(struct constraint *constraints, size_t f
// two constraints each, but are also mutually constrained by two
// constraints.
- abort();
+ expand_constraint(a1, step->i);
+ expand_constraint(a2, step->j);
+
+ expand_constraint(b1, step->k);
+ expand_constraint(b2, step->x);
+
+ expand_constraint(c1, step->y);
+ expand_constraint(c2, step->z);
+
+ // Lets solve for a pretty static case first
+ assert(a1->type == CT_POINT_POINT_DISTANCE);
+ assert(a2->type == CT_POINT_LINE_DISTANCE);
+
+ assert(b1->type == CT_POINT_LINE_DISTANCE);
+ assert(b2->type == CT_LINE_LINE_ANGLE);
+
+ assert(c1->type == CT_POINT_LINE_DISTANCE);
+ assert(c2->type == CT_LINE_LINE_ANGLE);
+
+ // All the constraints form triangles, not necessarily required, but
+ // simpler
+ assert(a1_oppo == a2_oppo);
+ assert(a1_local != a2_local);
+ assert(b1_oppo == b2_oppo);
+ assert(b1_local != b2_local);
+ assert(c1_oppo == c2_oppo);
+ assert(c1_local != c2_local);
+
+ // The basic idea here is to create some new points for ax_oppo and bx_oppo
+ // which we can then use to place a circle or line
+ struct element *ax_oppo_locally = {};
+ point_from_line_and_distance(drawing, constraints, step->j, step->i, a2_local->e, a1_local->e, constraints[step->j].c2 == a2_local, &ax_oppo_locally);
+
+ struct element *bx_oppo_locally = {};
+ build_angle_point_line2(drawing, constraints, step->x, step->k, b2_local->e, b1_local->e, true, &bx_oppo_locally);
+
+ //cx's naming is strange, the two local points are in bx and the opposing
+ //point is in ax. We know that since ax was built before bx and had the two
+ //local elements been in ax, we would have included the point as well.
+ //
+ struct element *assembly1_distance = insert_cmd(drawing, (struct command){
+ .op = CMD_MEASURE_POINT_LINE_DISTANCE,
+ .hidden = true,
+ .result.type = ETYPE_VALUE,
+ .arg1 = a1_oppo->e,
+ .arg2 = c1_oppo->e,
+ });
+
+ // This line isn't really in our scope at this point. This is technically
+ // dubious, but it works due to the current implementation
+ struct element *cx_oppo_bx = {};
+ build_angle_point_line2(drawing, constraints, step->z, step->y, c2_local->e, c1_local->e, true, &cx_oppo_bx);
+
+ struct element *assembly2_angle = insert_cmd(drawing, (struct command){
+ .op = CMD_MEASURE_LINE_LINE_ANGLE,
+ .hidden = true,
+ .result.type = ETYPE_VALUE,
+ .arg1 = b1_oppo->e,
+ .arg2 = cx_oppo_bx,
+ });
+
+ struct element* cx_oppo_direction_locally;
+ {
+ struct element* l = insert_cmd(drawing, (struct command){
+ .op = CMD_LINE_POINT_LINE_ANGLE,
+ .hidden = false,
+ .result.type = ETYPE_LINE,
+ .arg1 = ax_oppo_locally,
+ .arg2 = bx_oppo_locally,
+ .arg3 = assembly2_angle,
+ });
+
+ cx_oppo_direction_locally = insert_cmd(drawing, (struct command){
+ .op = CMD_LINE_LINE_DISTANCE_PARALLEL,
+ .hidden = false,
+ .result.type = ETYPE_LINE,
+ .root = 1,
+ .arg1 = l,
+ .arg2 = assembly1_distance,
+ });
+ }
+
+ insert_cmd(drawing, (struct command){
+ .op = CMD_IMPORT_POINT_LINE,
+ .arg1 = ax_oppo_locally,
+ .arg2 = cx_oppo_direction_locally,
+ .d = step->assembly,
+ .attachp = a1_oppo->e,
+ .attachl = c1_oppo->e,
+ });
+
+ {
+ struct element *local_intersection = insert_cmd(drawing, (struct command){
+ .op = CMD_POINT_LINE_LINE,
+ .hidden = true,
+ .result.type = ETYPE_POINT,
+ .arg1 = bx_oppo_locally,
+ .arg2 = cx_oppo_direction_locally,
+ });
+
+ struct element *subassembly2_intersection = insert_cmd(drawing, (struct command){
+ .op = CMD_POINT_LINE_LINE,
+ .hidden = true,
+ .result.type = ETYPE_POINT,
+ .arg1 = b1_oppo->e,
+ .arg2 = cx_oppo_bx,
+ });
+
+ insert_cmd(drawing, (struct command){
+ .op = CMD_IMPORT_POINT_LINE,
+ .arg1 = local_intersection,
+ .arg2 = bx_oppo_locally,
+ .d = step->assembly2,
+ .attachp = subassembly2_intersection,
+ .attachl = b1_oppo->e,
+ });
+ }
}
static void draw_solution(struct constraint *constraints, size_t fix, struct solve_step* steps, size_t steps_num, struct drawing *drawing, struct subassembly *assembly) {
@@ -988,43 +1167,7 @@ static void draw_solution(struct constraint *constraints, size_t fix, struct sol
&& local_j->type == COM_POINT) {
assert(oppo_i->type == COM_POINT);
- struct element *d1 = insert_cmd(drawing, (struct command){
- .op = CMD_VALUE_INPUT,
- .index = step->i,
- .dir = constraints[step->i].forward,
- .result.type = ETYPE_VALUE,
- });
- struct element *d2 = insert_cmd(drawing, (struct command){
- .op = CMD_VALUE_INPUT,
- .index = step->j,
- .dir = constraints[step->j].forward,
- .result.type = ETYPE_VALUE,
- });
-
- struct element *l = insert_cmd(drawing, (struct command){
- .op = CMD_LINE_LINE_DISTANCE_PARALLEL,
- .hidden = !shown,
- .result.type = ETYPE_LINE,
- .arg1 = local_i->e,
- .arg2 = d1,
- });
-
- struct element *c = insert_cmd(drawing, (struct command){
- .op = CMD_CIRCLE_CENTER_RADIUS,
- .hidden = !shown,
- .result.type = ETYPE_CIRCLE,
- .arg1 = local_j->e,
- .arg2 = d2,
- });
-
- oppo_i->e = insert_cmd(drawing, (struct command){
- .op = CMD_POINT_CIRCLE_LINE,
- .hidden = !shown,
- .root = constraints[step->j].c2 == local_j,
- .result.type = ETYPE_POINT,
- .arg1 = c,
- .arg2 = l,
- });
+ point_from_line_and_distance(drawing, constraints, step->i, step->j, local_i->e, local_j->e, constraints[step->j].c2 == local_j, &oppo_i->e);
} else if(constraints[step->i].type == CT_POINT_POINT_DISTANCE
&& local_i->type == COM_POINT
&& constraints[step->j].type == CT_POINT_LINE_DISTANCE
@@ -1032,43 +1175,7 @@ static void draw_solution(struct constraint *constraints, size_t fix, struct sol
// @COPYPASTA: Taken from above but with params swapped
assert(oppo_i->type == COM_POINT);
- struct element *d1 = insert_cmd(drawing, (struct command){
- .op = CMD_VALUE_INPUT,
- .index = step->i,
- .dir = constraints[step->i].forward,
- .result.type = ETYPE_VALUE,
- });
- struct element *d2 = insert_cmd(drawing, (struct command){
- .op = CMD_VALUE_INPUT,
- .index = step->j,
- .dir = constraints[step->j].forward,
- .result.type = ETYPE_VALUE,
- });
-
- struct element *l = insert_cmd(drawing, (struct command){
- .op = CMD_LINE_LINE_DISTANCE_PARALLEL,
- .hidden = !shown,
- .result.type = ETYPE_LINE,
- .arg1 = local_j->e,
- .arg2 = d2,
- });
-
- struct element *c = insert_cmd(drawing, (struct command){
- .op = CMD_CIRCLE_CENTER_RADIUS,
- .hidden = !shown,
- .result.type = ETYPE_CIRCLE,
- .arg1 = local_i->e,
- .arg2 = d1,
- });
-
- oppo_i->e = insert_cmd(drawing, (struct command){
- .op = CMD_POINT_CIRCLE_LINE,
- .hidden = !shown,
- .root = constraints[step->j].c2 == local_i,
- .result.type = ETYPE_POINT,
- .arg1 = c,
- .arg2 = l,
- });
+ point_from_line_and_distance(drawing, constraints, step->j, step->i, local_j->e, local_i->e, constraints[step->j].c2 == local_i, &oppo_i->e);
} else {
CRASH("Unknown constraint combination %s and %s\n", constraint_type_name[constraints[step->i].type], constraint_type_name[constraints[step->j].type]);
}
@@ -1119,7 +1226,7 @@ bool solve_constraints(struct constraints *constraints, struct drawing *drawing,
size_t fix;
while(fix_first(constraints->elements, constraints->length, &fix)) {
// Build triangles on that root
- assemblies[*assemblies_num].steps = malloc(sizeof(struct solve_step) * constraints->length);
+ assemblies[*assemblies_num].steps = calloc(1, sizeof(struct solve_step) * constraints->length);
assemblies[*assemblies_num].articulation = malloc(sizeof(struct component*) * constraints->length);
assemblies[*assemblies_num].articulation_position = malloc(sizeof(struct element*) * constraints->length);
assemblies[*assemblies_num].steps_num = build_triangles(constraints, components, dest_num, fix, *assemblies_num+1, &assemblies[*assemblies_num]);