|
15 | 15 | from compas_rhino.conversions import line_to_rhino |
16 | 16 | from compas_rhino.conversions import xform_to_rhino |
17 | 17 | from compas_rhino.conversions import plane_to_compas_frame |
| 18 | +from compas_rhino.conversions import box_to_compas |
18 | 19 |
|
19 | 20 | import Rhino.Geometry |
20 | 21 |
|
@@ -458,43 +459,93 @@ def frame_at(self, t): |
458 | 459 | plane = self.rhino_curve.FrameAt(t) |
459 | 460 | return plane_to_compas_frame(plane) |
460 | 461 |
|
461 | | - def closest_point(self, point, parameter=False): |
| 462 | + def closest_point(self, point, return_parameter=False): |
462 | 463 | """Compute the closest point on the curve to a given point. |
463 | 464 |
|
464 | 465 | Parameters |
465 | 466 | ---------- |
466 | 467 | point : Point |
467 | 468 | The point to project orthogonally to the curve. |
468 | | - parameter : bool, optional |
469 | | - Return the projected point as well as the curve parameter. |
| 469 | + return_parameter : bool, optional |
| 470 | + Return the curve parameter in addition to the projected point. |
470 | 471 |
|
471 | 472 | Returns |
472 | 473 | ------- |
473 | | - Point or tuple |
| 474 | + :class:`compas.geometry.Point` or tuple of :class:`compas.geometry.Point` and float |
474 | 475 | The nearest point on the curve, if ``parameter`` is false. |
475 | 476 | The nearest as (point, parameter) tuple, if ``parameter`` is true. |
476 | 477 | """ |
477 | | - raise NotImplementedError |
| 478 | + point, t = self.rhino_curve.ClosestPoint(point) |
| 479 | + point = point_to_compas(point) |
| 480 | + if return_parameter: |
| 481 | + return point, t |
| 482 | + return point |
478 | 483 |
|
479 | | - def divide_by_count(self, count): |
480 | | - """Divide the curve into a specific number of equal length segments.""" |
481 | | - raise NotImplementedError |
| 484 | + def divide_by_count(self, count, return_points=False): |
| 485 | + """Divide the curve into a specific number of equal length segments. |
482 | 486 |
|
483 | | - def divide_by_length(self, length): |
484 | | - """Divide the curve into segments of specified length.""" |
485 | | - raise NotImplementedError |
| 487 | + Parameters |
| 488 | + ---------- |
| 489 | + count : int |
| 490 | + The number of segments. |
| 491 | + return_points : bool, optional |
| 492 | + If ``True``, return the list of division parameters, |
| 493 | + and the points corresponding to those parameters. |
| 494 | + If ``False``, return only the list of parameters. |
486 | 495 |
|
487 | | - def aabb(self, precision=0.0): |
488 | | - """Compute the axis aligned bounding box of the curve.""" |
489 | | - raise NotImplementedError |
| 496 | + Returns |
| 497 | + ------- |
| 498 | + list of float or tuple of list of float and list of :class:`compas.geometry.Point` |
| 499 | + The parameters defining the discretisation, |
| 500 | + and potentially the points corresponding to those parameters. |
| 501 | + """ |
| 502 | + params = self.rhino_curve.DivideByCount(count, True) |
| 503 | + if return_points: |
| 504 | + points = [self.point_at(t) for t in params] |
| 505 | + return params, points |
| 506 | + return params |
| 507 | + |
| 508 | + def divide_by_length(self, length, return_points=False): |
| 509 | + """Divide the curve into segments of specified length. |
| 510 | +
|
| 511 | + Parameters |
| 512 | + ---------- |
| 513 | + length : float |
| 514 | + The length of the segments. |
| 515 | + return_points : bool, optional |
| 516 | + If ``True``, return the list of division parameters, |
| 517 | + and the points corresponding to those parameters. |
| 518 | + If ``False``, return only the list of parameters. |
| 519 | +
|
| 520 | + Returns |
| 521 | + ------- |
| 522 | + list of float or tuple of list of float and list of :class:`compas.geometry.Point` |
| 523 | + The parameters defining the discretisation, |
| 524 | + and potentially the points corresponding to those parameters. |
| 525 | + """ |
| 526 | + params = self.rhino_curve.DivideByLength(length, True) |
| 527 | + if return_points: |
| 528 | + points = [self.point_at(t) for t in params] |
| 529 | + return params, points |
| 530 | + return params |
| 531 | + |
| 532 | + def aabb(self): |
| 533 | + """Compute the axis aligned bounding box of the curve. |
| 534 | +
|
| 535 | + Returns |
| 536 | + ------- |
| 537 | + :class:`compas.geometry.Box` |
| 538 | + """ |
| 539 | + box = self.rhino_curve.getBoundingBox(True) |
| 540 | + return box_to_compas(box) |
490 | 541 |
|
491 | 542 | def obb(self, precision=0.0): |
492 | 543 | """Compute the oriented bounding box of the curve.""" |
493 | 544 | raise NotImplementedError |
494 | 545 |
|
495 | | - def length(self, precision=1e-3): |
| 546 | + def length(self, precision=1e-8): |
496 | 547 | """Compute the length of the curve.""" |
497 | | - raise NotImplementedError |
| 548 | + return self.rhino_curve.GetLength(precision) |
498 | 549 |
|
499 | 550 | def segment(self, u, v, precision=1e-3): |
500 | 551 | """Modifies this curve by segmenting it between the parameters u and v. |
|
0 commit comments