| | 444 | class Projector(object): |
|---|
| | 445 | """ |
|---|
| | 446 | Base class for variable space projectors. |
|---|
| | 447 | |
|---|
| | 448 | Variable space projectors allow to convert variables' values to common |
|---|
| | 449 | space before constraint solving. |
|---|
| | 450 | |
|---|
| | 451 | Consider two geometrical objects defined by their position (x0, y0) |
|---|
| | 452 | and object's affine information (see gaphas.sexample module) |
|---|
| | 453 | >>> from solver import Variable |
|---|
| | 454 | >>> from gaphas.sexamples import Rectangle, Vector, AffineProjector |
|---|
| | 455 | >>> r = Rectangle(5, 5, 20, 20) |
|---|
| | 456 | >>> v = Vector(5, 50, 5, -25) |
|---|
| | 457 | |
|---|
| | 458 | To keep vector's terminal point on a rectangle's bottom side create |
|---|
| | 459 | affine projector and appropriate constraints |
|---|
| | 460 | >>> proj = AffineProjector() |
|---|
| | 461 | >>> zero = Variable(0) # used for balance constraint band |
|---|
| | 462 | >>> bc = BalanceConstraint(band=(zero, r.width), v=v.x, balance=0.25) |
|---|
| | 463 | >>> eq = EqualsConstraint(a=r.height, b=v.y) |
|---|
| | 464 | >>> proj(bc, {v.x: v.x0, r.width: r.x0, zero: r.x0}) |
|---|
| | 465 | >>> proj(eq, {v.y: v.y0, r.height: r.y0}) |
|---|
| | 466 | |
|---|
| | 467 | Let's change rectangle dimensions |
|---|
| | 468 | >>> r.width.value = 24 |
|---|
| | 469 | >>> r.height.value = 25 |
|---|
| | 470 | |
|---|
| | 471 | and use constraints to keep vector's terminal point on rectangle bottom |
|---|
| | 472 | side |
|---|
| | 473 | >>> bc.solve_for(v.x) |
|---|
| | 474 | >>> eq.solve_for(v.y) |
|---|
| | 475 | >>> v.x, v.y |
|---|
| | 476 | (Variable(6, 20), Variable(-20, 20)) |
|---|
| | 477 | """ |
|---|
| | 478 | def _cproj(self): |
|---|
| | 479 | """ |
|---|
| | 480 | Perform projection to common space. |
|---|
| | 481 | """ |
|---|
| | 482 | raise NotImplemented |
|---|
| | 483 | |
|---|
| | 484 | |
|---|
| | 485 | def _iproj(self): |
|---|
| | 486 | """ |
|---|
| | 487 | Perform projection to internal space. |
|---|
| | 488 | """ |
|---|
| | 489 | raise NotImplemented |
|---|
| | 490 | |
|---|
| | 491 | |
|---|
| | 492 | def __call__(self, c, data): |
|---|
| | 493 | """ |
|---|
| | 494 | Decorator for Constraint.solve_for method to perform |
|---|
| | 495 | projection to common space before variable solving and later |
|---|
| | 496 | project to internal variable space. |
|---|
| | 497 | """ |
|---|
| | 498 | f = c.solve_for |
|---|
| | 499 | def wrapper(var): |
|---|
| | 500 | self._cproj(c, data) |
|---|
| | 501 | f(var) |
|---|
| | 502 | self._iproj(c, data) |
|---|
| | 503 | c.solve_for = wrapper |
|---|
| | 504 | |
|---|
| | 505 | |
|---|
| | 506 | |
|---|