.config(1);
Bar : 'bar.gif' P = [10,10] Q = [50,10];
// We place the bar somewhere
@0.0 Bar.P = [10,10]; Bar.Q = Bar.P + [_,0];
barPx = 10; barPy = 10; barQx = barPx + d; barQy = barPy;
barQy can readily be computed, but not barQx! Some constraint is obviously missing. This also follows from the fact that we have four equations, but five variables: The four bar.. variables and the "slack variable" d.
Let's now rotate the bar by 45°:
@1.0 Bar.Q = [e,e];
According to the "key convention", the constraint Bar.P = [10,10] remains in force, but the Bar.Q constraint from @0.0 is replaced. Therefore, we end up with the following four equations:
barPx = 10; barPy = 10; barQx = e; barQy = e;
Again, we cannot compute some values - in this case, both for barQx and barQy. Again, we have five variables - the bar..s, and e -, but only four equations.
Let's now add a "length constraint":
// implicit length constraint
(Bar.P.x - Bar.Q.x)² + (Bar.P.y - Bar.Q.y)² = 40²
Using this constraint, we get a fifth equation. For the initial placement in step @0.0, we can now solve the equations:
barPx = 10; barPy = 10; barQx = barPx + d; barQy = barPy;
(barPx - barQx)² + (barPy - barQy)² = 40²
We substitute barPx and barPy (as they are equal to constants) and barQy and get:
barQx = 10 + d; (10 - barQx)² + (10 - 10)² = 40²
Dropping (10-10)² = 0 and substituting barQx gives us
(10 - 10 - d)² = 40²
and we arrive at the two solutions d = +40 and d = -40. Backsubstitution will give us the variables for the initial placement of the bar.
But ... there are two possible solutions! What do we do about this? Possibilities:
- We require an additional explicit constraint, e.g. Bar.Q.x > Bar.P.x.
- We assume additional implicit constraints - my suggestion: If for two anchors A and B of a thing T, we have A.x > B.x, then we also require T.A.x > T.B.x for the solution.
- hold too short (i.e., they are also necessary for some movements); or
- too long (i.e., they will prevent a single solution at some time); or
- are not sufficient (e.g., when two solution have equal x, or when multiple quadratic equations yield four or more solutions).
But also for explicit inequality constraints, the lifetime seems to be tricky - the three problems above might also occur with them. So we need a lifetime regime for inequality constraints!
Here is my suggestion: Inequality constraints are marked with the variable on the left side and the inequality operator (maybe <= is unified with <, and >= with >). Using the following "vacuous" constraint, an inequality constraint can be "killed:"
x > _
(Another possibility would be to have infinite lifetime for inequality constraints, but invoke them only if there are two or more solutions ... but I am afraid that then, it gets even harder to get unique solutions).
Let's also try the solution for the @1.0 step: We have the five equations
barPx = 10; barPy = 10; barQx = e; barQy = e;
(barPx - barQx)² + (barPy - barQy)² = 40²
We substitute all four bar.. variables and get:
(10 - e)² + (10 - e)² = 40²
This can be solved and yields 10 - e ≈ ±28.28, or e ≈ +38.28 or e ≈ -18.28. From this, we can find the values of the bar.. variables. Again, > constraints are needed to select a unique solution.
The rigid body (length) constraints must of course remain in force for the full script. Therefore, I give them a key that can never be given to another constraint - some internal Guid or the like.
No comments:
Post a Comment