summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/triangle_tip.c12
-rw-r--r--src/solve.c34
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.
}
}
}