diff options
| -rw-r--r-- | examples/triangle_tip.c | 12 | ||||
| -rw-r--r-- | src/solve.c | 34 |
2 files changed, 33 insertions, 13 deletions
diff --git a/examples/triangle_tip.c b/examples/triangle_tip.c index 9d2d5ce..b6fcf99 100644 --- a/examples/triangle_tip.c +++ b/examples/triangle_tip.c @@ -39,8 +39,8 @@ int main(int argc, char *argv[]) { struct component p5 = {.type = COM_POINT}; struct component t1base = {.type = COM_LINE}; + struct component t1bas2 = {.type = COM_LINE}; struct component t2base = {.type = COM_LINE}; - struct component t2side = {.type = COM_LINE}; add_constraint(&constraints, (struct constraint[]){ // Make a triangle @@ -51,21 +51,19 @@ int main(int argc, char *argv[]) { POINT_ON_LINE(&p1, &t1base), POINT_ON_LINE(&p2, &t1base), + POINT_ON_LINE(&p1, &t1bas2), + LL_ANGLE(&t1base, &t1bas2, DEG(-10)), + // With another triangle sharing a point PP_DISTANCE(&p4, &p5, 30), PP_DISTANCE(&p3, &p4, 30), PP_DISTANCE(&p5, &p3, 30), - // LL_ANGLE(&t2side, &t2base, DEG(120)), - - POINT_ON_LINE(&p3, &t2side), - POINT_ON_LINE(&p4, &t2side), - POINT_ON_LINE(&p4, &t2base), POINT_ON_LINE(&p5, &t2base), // The edge they don't share is constrained - LL_ANGLE(&t1base, &t2base, DEG(70)), + LL_ANGLE(&t1bas2, &t2base, DEG(70)), CEND(), }); diff --git a/src/solve.c b/src/solve.c index 1401f44..5b3cdce 100644 --- a/src/solve.c +++ b/src/solve.c @@ -814,7 +814,7 @@ constraint_matches_j: // assembly from that information float theta = atan2(constraint->c1->e->line.norm[1], constraint->c1->e->line.norm[0]) - atan2(constraint->c2->e->line.norm[1], constraint->c2->e->line.norm[0]); - theta = forward ? theta : -theta; + theta = forward ? -theta : theta; constraint->used = true; theta += constraint->forward ? constraint->v : -constraint->v; @@ -835,7 +835,8 @@ constraint_matches_j: glm_translate2d(transform, negative_translate); } - // Transform the baseline points + // We have to transform the fixed point separately, since it + // doesn't have a build step { struct component *c = constraints->elements[assemblies[i].fix].c1; assert(c->type == COM_POINT); @@ -860,11 +861,32 @@ constraint_matches_j: if(c->type == COM_POINT) { affine_transform_vec2(transform, c->e->point.pos, c->e->point.pos); + } else if(c->type == COM_LINE) { + // Find a point on the line, what point doesn't matter + // since the whole line is moving + struct line line = c->e->line; + double a = line.norm[0]; + double b = line.norm[1]; + + double rec = pow(a, 2) + pow(b, 2); + double x0 = -a*line.C / rec; + double y0 = -b*line.C / rec; + vec2 p = {x0, y0}; + + // Rotate the line to the new orientation + glm_vec2_rotate(line.norm, theta, line.norm); + + // Transform the fixed point + affine_transform_vec2(transform, p, p); + glm_vec2_negate(p); + + // Calculate a C to follow the new point + line.C = glm_vec2_dot(line.norm, p); + + c->e->line = line; + } else { + abort(); } - // @HACK We're not transforming lines, this relies on the - // user not requiring/caring about the lines AFTER solving. - // This is wrong, but useful enough for getting something - // on screen. } } } |
