| | 443 | class LineConstraint(Constraint): |
|---|
| | 444 | """ |
|---|
| | 445 | Ensure a point is kept on a line. |
|---|
| | 446 | |
|---|
| | 447 | Attributes: |
|---|
| | 448 | - _line: line defined by tuple ((x1, y1), (x2, y2)) |
|---|
| | 449 | - _point: point defined by tuple (x, y) |
|---|
| | 450 | """ |
|---|
| | 451 | |
|---|
| | 452 | def __init__(self, line, point): |
|---|
| | 453 | super(LineConstraint, self).__init__(*(line[0] + line[1] + point)) |
|---|
| | 454 | |
|---|
| | 455 | self._line = line |
|---|
| | 456 | self._point = point |
|---|
| | 457 | |
|---|
| | 458 | self.update_ratio() |
|---|
| | 459 | |
|---|
| | 460 | |
|---|
| | 461 | def update_ratio(self): |
|---|
| | 462 | """ |
|---|
| | 463 | >>> from gaphas.solver import Variable |
|---|
| | 464 | >>> line = (Variable(0), Variable(0)), (Variable(30), Variable(20)) |
|---|
| | 465 | >>> point = (Variable(15), Variable(4)) |
|---|
| | 466 | >>> lc = LineConstraint(line=line, point=point) |
|---|
| | 467 | >>> lc.ratio_x, lc.ratio_y |
|---|
| | 468 | (0.5, 0.20000000000000001) |
|---|
| | 469 | >>> line[1][0].value = 40 |
|---|
| | 470 | >>> line[1][1].value = 30 |
|---|
| | 471 | >>> lc.solve_for(point[0]) |
|---|
| | 472 | >>> lc.ratio_x, lc.ratio_y |
|---|
| | 473 | (0.5, 0.20000000000000001) |
|---|
| | 474 | >>> point |
|---|
| | 475 | (Variable(20, 20), Variable(6, 20)) |
|---|
| | 476 | """ |
|---|
| | 477 | sx, sy = self._line[0] |
|---|
| | 478 | ex, ey = self._line[1] |
|---|
| | 479 | px, py = self._point |
|---|
| | 480 | |
|---|
| | 481 | try: |
|---|
| | 482 | self.ratio_x = float(px - sx) / float(ex - sx) |
|---|
| | 483 | except ZeroDivisionError: |
|---|
| | 484 | self.ratio_x = 0.0 |
|---|
| | 485 | try: |
|---|
| | 486 | self.ratio_y = float(py - sy) / float(ey - sy) |
|---|
| | 487 | except ZeroDivisionError: |
|---|
| | 488 | self.ratio_y = 0.0 |
|---|
| | 489 | |
|---|
| | 490 | |
|---|
| | 491 | def solve_for(self, var=None): |
|---|
| | 492 | self._solve() |
|---|
| | 493 | |
|---|
| | 494 | def _solve(self): |
|---|
| | 495 | """ |
|---|
| | 496 | Solve the equation for the connected_handle. |
|---|
| | 497 | >>> from gaphas.solver import Variable |
|---|
| | 498 | >>> line = (Variable(0), Variable(0)), (Variable(30), Variable(20)) |
|---|
| | 499 | >>> point = (Variable(15), Variable(4)) |
|---|
| | 500 | >>> lc = LineConstraint(line=line, point=point) |
|---|
| | 501 | >>> lc.solve_for(point[0]) |
|---|
| | 502 | >>> point |
|---|
| | 503 | (Variable(15, 20), Variable(4, 20)) |
|---|
| | 504 | >>> line[1][0].value = 40 |
|---|
| | 505 | >>> line[1][1].value = 30 |
|---|
| | 506 | >>> lc.solve_for(point[0]) |
|---|
| | 507 | >>> point |
|---|
| | 508 | (Variable(20, 20), Variable(6, 20)) |
|---|
| | 509 | """ |
|---|
| | 510 | sx, sy = self._line[0] |
|---|
| | 511 | ex, ey = self._line[1] |
|---|
| | 512 | px, py = self._point |
|---|
| | 513 | |
|---|
| | 514 | x = sx + (ex - sx) * self.ratio_x |
|---|
| | 515 | y = sy + (ey - sy) * self.ratio_y |
|---|
| | 516 | |
|---|
| | 517 | px.value, py.value = x, y |
|---|
| | 518 | |
|---|
| | 519 | |
|---|