Rotating and translating the model

This example shows how to rotate the model around a specified axis and point. To allow adding shapes in other planes than the default x-y plane. We also demonstrate how to translate the model.

from qtcad.builder import Builder
from qtcad.builder import Mask, Polygon, Circle, Direction

Rotation

First we create a mask with two shapes, a large base and a smaller shape on top of it.

footprint = Polygon.box(10, 10, name="base").centered()
small = Circle(name="small", center=(0, 0), radius=2)

example_mask = Mask("footprint")
example_mask.add_shape(footprint)
example_mask.add_shape(small)
Circle(name='small', id=1, radius=2, center=(0, 0))

We create a Builder with this mask, extrude the base shape and then extrude the smaller shape on top of it.

builder = (
    Builder()
    .add_mask(example_mask)
    .use_shape("base")
    .extrude(10)
    .use_shape("small")
    .extrude(2)
    .view(
        volume_labels=True,
        surfaces=True,
        angles=(-45, 0, 45),
        save="figs/unrotated_model.svg",
        font_size=20,
        zoom=0.7,
    )
)
rotation
[14:50:27] INFO     Selected shapes: [Polygon 0 'base']             _builder.py:880
           INFO     Extruding shape 0 from mask 'footprint' with   _builder.py:2895
                    name 'base' by 10 at z=0
           INFO     Creating new physical group of dimension 2     _builder.py:2679
                    with name 'base_bottom'
           INFO     Creating new physical group of dimension 2     _builder.py:2679
                    with name 'base_side'
           INFO     Creating new physical group of dimension 2     _builder.py:2679
                    with name 'base_top'
           INFO     Creating new physical group of dimension 3     _builder.py:2679
                    with name 'base'
           INFO     Setting z-coordinate to 10                      _builder.py:929
           INFO     Selected shapes: [Circle 1 'small']             _builder.py:880
           INFO     Extruding shape 1 from mask 'footprint' with   _builder.py:2895
                    name 'small' by 2 at z=10
           INFO     Creating new physical group of dimension 2     _builder.py:2679
                    with name 'small_bottom'
           INFO     Creating new physical group of dimension 2     _builder.py:2679
                    with name 'small_side'
           INFO     Creating new physical group of dimension 2     _builder.py:2679
                    with name 'small_top'
           INFO     Creating new physical group of dimension 3     _builder.py:2679
                    with name 'small'
           INFO     Identifying potential intersections...        fragmenter.py:290
           INFO     Fragmenting...                                fragmenter.py:320
           INFO     Setting z-coordinate to 12                      _builder.py:929
           INFO     Saving figure                                  _builder.py:1994

Now, we rotate the model 90 degrees around the x axis, using the base shape as the point to rotate around. We then extrude the small shape again on top of the rotated base shape.

builder.rotate_model(angle=90, axis=Direction.x, around="base").extrude(2).view(
    volume_labels=True,
    angles=(-45, 0, 45),
    save="figs/rotated_model.svg",
    font_size=20,
    zoom=0.8,
    surfaces=True,
)
rotation
           INFO     Rotating model around [1. 0. 0.] based at       _builder.py:670
                    [-4.19775326e-16 -1.88331090e-17
                    5.00000000e+00] by 90 degrees
           INFO     New z-coordinate after rotation is 10.0         _builder.py:679
           INFO     Extruding shape 1 from mask 'footprint' with   _builder.py:2895
                    name 'small' by 2 at z=10.0
           INFO     Identifying potential intersections...        fragmenter.py:290
           INFO     Fragmenting...                                fragmenter.py:320
           INFO     Setting z-coordinate to 12.0                    _builder.py:929
           INFO     Saving figure                                  _builder.py:1994

<qtcad.builder.builder.Builder object at 0x7ff52105fc50>

Finally, we rotate the model 20 degrees around a tilted axis defined by the vector (1, 1, 1), again using the base shape as the point to rotate around. We then extrude the small shape in the middle of the rotated base shape.

builder.rotate_model(angle=20, axis=[1, 1, 1], around="base").set_z(5).extrude(2).view(
    volume_labels=True,
    angles=(-60, 0, 45),
    save="figs/rotated_model_arbitrary_axis.svg",
    font_size=20,
    zoom=0.8,
    surfaces=True,
    axes=3,
)
rotation
[14:50:28] INFO     Rotating model around [1. 1. 1.] based at       _builder.py:670
                    [-8.34887715e-17 -6.82121026e-16
                    5.00000000e+00] by 20 degrees
           INFO     Could not find any points nearby to snap to.   _builder.py:2376
                    Falling back to bounding box value...
           INFO     New z-coordinate after rotation is              _builder.py:679
                    12.27996891767327
           INFO     Setting z-coordinate to 5                       _builder.py:929
           INFO     Extruding shape 1 from mask 'footprint' with   _builder.py:2895
                    name 'small' by 2 at z=5
           INFO     Identifying potential intersections...        fragmenter.py:290
           INFO     Fragmenting...                                fragmenter.py:320
           INFO     Setting z-coordinate to 7                       _builder.py:929
           INFO     Saving figure                                  _builder.py:1994

<qtcad.builder.builder.Builder object at 0x7ff52105fc50>

Translation

We can also translate the model. As an example, we first undo the previous rotation.

builder.rotate_model(angle=-20, axis=[1, 1, 1], around="base").view(
    volume_labels=True,
    angles=(-60, 0, 45),
    save="figs/befro_rotation.svg",
    font_size=20,
    zoom=0.8,
    surfaces=True,
    axes=3,
)
rotation
[14:50:29] INFO     Rotating model around [1. 1. 1.] based at [     _builder.py:670
                    5.19313470e-16 -9.63690918e-16  4.97421932e+00]
                    by -20 degrees
           INFO     New z-coordinate after rotation is              _builder.py:679
                    11.998963489820566
           INFO     Saving figure                                  _builder.py:1994

<qtcad.builder.builder.Builder object at 0x7ff52105fc50>

Then, we translate the model 5 units in the x direction and then extrude a scaled down version of the circle on top of the translated base shape.

builder.translate_model((6, 0, 0)).use_shape("small").copy_shape(
    scale=0.5, name="smaller"
).extrude(2).view(
    volume_labels=True,
    angles=(-60, 0, 45),
    save="figs/translated_model.svg",
    font_size=20,
    zoom=0.8,
    surfaces=True,
    axes=3,
)
rotation
[14:50:30] INFO     Translating model by [6. 0. 0.]                 _builder.py:591
           INFO     Selected shapes: [Circle 1 'small']             _builder.py:880
           INFO     Extruding shape 2 from mask 'footprint' with   _builder.py:2895
                    name 'smaller' by 2 at z=11.998963489820566
           INFO     Creating new physical group of dimension 2     _builder.py:2679
                    with name 'smaller_bottom'
           INFO     Creating new physical group of dimension 2     _builder.py:2679
                    with name 'smaller_side'
           INFO     Creating new physical group of dimension 2     _builder.py:2679
                    with name 'smaller_top'
           INFO     Creating new physical group of dimension 3     _builder.py:2679
                    with name 'smaller'
           INFO     Identifying potential intersections...        fragmenter.py:290
           INFO     Setting z-coordinate to 13.998963489820566      _builder.py:929
           INFO     Saving figure                                  _builder.py:1994

<qtcad.builder.builder.Builder object at 0x7ff52105fc50>

Total running time of the script: (0 minutes 4.128 seconds)

Gallery generated by Sphinx-Gallery