Skip to content

Commit

Permalink
Merge pull request #1399 from compas-dev/box_scaled
Browse files Browse the repository at this point in the history
Fix `scaled` in `Box`
  • Loading branch information
gonzalocasas authored Oct 16, 2024
2 parents aabed04 + 2120660 commit d43a85c
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 6 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed

* Fixed `RuntimeError` when using `compas_rhino.unload_modules` in CPython`.
* Fixed bug in `Box.scaled` causing a `TypeError` due to incorrect parameter forwarding.
* Changed argument names of `Box.scale()` to `x`, `y`, `z`, instead of `factor` and made `y` and `z` optional to keep positional arguments backwards compatible.

### Removed

Expand Down
38 changes: 32 additions & 6 deletions src/compas/geometry/shapes/box.py
Original file line number Diff line number Diff line change
Expand Up @@ -558,22 +558,48 @@ def to_brep(self):
# self.ysize *= scaley
# self.zsize *= scalez

def scale(self, factor):
def scale(self, x, y=None, z=None):
"""Scale the box.
Parameters
----------
factor : float
The scaling factor.
x : float
The scaling factor in x-direction. If no other factor is specified,
this factor will be used for all directions.
y : float, optional
The scaling factor in the y-direction.
Defaults to ``x``.
z : float, optional
The scaling factor in the z-direction.
Defaults to ``x``.
Returns
-------
None
"""
self.xsize *= factor
self.ysize *= factor
self.zsize *= factor
self.xsize *= x
self.ysize *= y if y is not None else x
self.zsize *= z if z is not None else x

def scaled(self, x, y=None, z=None):
"""Returns a scaled copy of the box.
Parameters
----------
x : float
The scaling factor in the x-direction.
y : float, optional
The scaling factor in the y-direction.
Defaults to ``x``.
z : float, optional
The scaling factor in the z-direction.
Defaults to ``x``.
"""
box = self.copy()
box.scale(x, y, z)
return box

# ==========================================================================
# Methods
Expand Down
113 changes: 113 additions & 0 deletions tests/compas/geometry/test_box.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import pytest
from compas.geometry import Box
from compas.geometry import Point


@pytest.fixture
def default_box():
return Box(1.0, 2.0, 3.0)


@pytest.fixture
def unit_box():
return Box(1.0)


def test_box_constructor(default_box):
assert default_box.xsize == 1.0
assert default_box.ysize == 2.0
assert default_box.zsize == 3.0


def test_box_volume(default_box):
assert default_box.volume == 6.0


def test_box_area(default_box):
assert default_box.area == 22.0


def test_box_dimensions(default_box):
assert default_box.dimensions == [1.0, 2.0, 3.0]


def test_box_corners(default_box):
assert len(default_box.points) == 8


def test_box_corner(default_box):
assert default_box.corner(0) == Point(-0.5, -1.0, -1.5)
assert default_box.corner(1) == Point(-0.5, 1.0, -1.5)
assert default_box.corner(2) == Point(0.5, 1.0, -1.5)
assert default_box.corner(3) == Point(0.5, -1.0, -1.5)
assert default_box.corner(4) == Point(-0.5, -1.0, 1.5)
assert default_box.corner(5) == Point(-0.5, 1.0, 1.5)
assert default_box.corner(6) == Point(0.5, 1.0, 1.5)
assert default_box.corner(7) == Point(0.5, -1.0, 1.5)


def test_box_contains_point(default_box):
assert default_box.contains_point(Point(0.0, 0.0, 0.0))
assert not default_box.contains_point(Point(2.0, 2.0, 2.0))


def test_box_contains_points(default_box):
points = [Point(0.0, 0.0, 0.0), Point(2.0, 2.0, 2.0)]
results = default_box.contains_points(points)
assert results == [True, False]


def test_box_from_width_height_depth():
box = Box.from_width_height_depth(1.0, 2.0, 3.0)
assert box.xsize == 1.0
assert box.ysize == 3.0
assert box.zsize == 2.0


def test_box_from_bounding_box():
bbox = [
Point(0.0, 0.0, 0.0),
Point(1.0, 0.0, 0.0),
Point(1.0, 1.0, 0.0),
Point(0.0, 1.0, 0.0),
Point(0.0, 0.0, 1.0),
Point(1.0, 0.0, 1.0),
Point(1.0, 1.0, 1.0),
Point(0.0, 1.0, 1.0),
]
box = Box.from_bounding_box(bbox)
assert box.xsize == 1.0
assert box.ysize == 1.0
assert box.zsize == 1.0


def test_box_from_corner_corner_height():
box = Box.from_corner_corner_height([0.0, 0.0, 0.0], [1.0, 1.0, 0.0], 1.0)
assert box.xsize == 1.0
assert box.ysize == 1.0
assert box.zsize == 1.0


def test_box_from_diagonal():
diagonal = [Point(0.0, 0.0, 0.0), Point(1.0, 1.0, 1.0)]
box = Box.from_diagonal(diagonal)
assert box.xsize == 1.0
assert box.ysize == 1.0
assert box.zsize == 1.0


def test_box_scale(default_box):
default_box.scale(2.0)
assert default_box.xsize == 2.0
assert default_box.ysize == 4.0
assert default_box.zsize == 6.0


def test_box_scaled(default_box):
new_box = default_box.scaled(2.0, 4.0, 2.0)
assert default_box.xsize == 1.0
assert default_box.ysize == 2.0
assert default_box.zsize == 3.0
assert new_box.xsize == 2.0
assert new_box.ysize == 8.0
assert new_box.zsize == 6.0

0 comments on commit d43a85c

Please sign in to comment.