added advanced algebra topics
|
|
@ -6,6 +6,9 @@ Advanced Topics
|
||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
|
|
||||||
assemblies.rst
|
assemblies.rst
|
||||||
|
algebra_performance.rst
|
||||||
|
location_arithmetic.rst
|
||||||
|
algebra_definition.rst
|
||||||
center.rst
|
center.rst
|
||||||
custom.rst
|
custom.rst
|
||||||
debugging_logging.rst
|
debugging_logging.rst
|
||||||
|
|
|
||||||
110
docs/algebra_definition.rst
Normal file
|
|
@ -0,0 +1,110 @@
|
||||||
|
.. _algebra_definition:
|
||||||
|
|
||||||
|
Algebraic definition
|
||||||
|
========================
|
||||||
|
|
||||||
|
Objects and object arithmetic
|
||||||
|
----------------------------------
|
||||||
|
|
||||||
|
Set definitions:
|
||||||
|
|
||||||
|
:math:`P` is the set of all ``Part`` objects ``p`` with ``p._dim = 3``
|
||||||
|
|
||||||
|
:math:`S` is the set of all ``Sketch`` objects ``s`` with ``s._dim = 2``
|
||||||
|
|
||||||
|
:math:`C` is the set of all ``Curve`` objects ``c`` with ``c._dim = 3``
|
||||||
|
|
||||||
|
Neutral elements:
|
||||||
|
|
||||||
|
:math:`p_0` := ``p0`` is the empty ``Part`` object ``p0`` with ``p0._dim = 3`` and ``p0.wrapped = None``
|
||||||
|
|
||||||
|
:math:`s_0` := ``s0`` is the empty ``SKetch`` object ``s0`` with ``s0._dim = 2`` and ``s0.wrapped = None``
|
||||||
|
|
||||||
|
:math:`c_0` := ``c0`` is the empty ``Curve`` object ``c0`` with ``c0._dim = 1`` and ``c0.wrapped = None``
|
||||||
|
|
||||||
|
**Sets of predefined basic shapes:**
|
||||||
|
|
||||||
|
:math:`P_D := \lbrace` ``Part``, ``Box``, ``Cylinder``, ``Cone``, ``Sphere``, ``Torus``, ``Wedge``, ``Hole``, ``CounterBoreHole``, ``CounterSinkHole`` :math:`\rbrace`
|
||||||
|
|
||||||
|
:math:`S_D := \lbrace` ``Sketch``, ``Rectangle``, ``Circle``, ``Ellipse``, ``Rectangle``, ``Polygon``, ``RegularPolygon``, ``Text``, ``Trapezoid``, ``SlotArc``, ``SlotCenterPoint``, ``SlotCenterToCenter``, ``SlotOverall`` :math:`\rbrace`
|
||||||
|
|
||||||
|
:math:`C_D := \lbrace` ``Curve``, ``Bezier``, ``PolarLine``, ``Polyline``, ``Spline``, ``Helix``, ``CenterArc``, ``EllipticalCenterArc``, ``RadiusArc``, ``SagittaArc``, ``TangentArc``, ``ThreePointArc``, ``JernArc`` :math:`\rbrace`
|
||||||
|
|
||||||
|
with :math:`P_D \subset P, S_D \subset S` and :math:`C_D \subset C`
|
||||||
|
|
||||||
|
**Operations:**
|
||||||
|
|
||||||
|
|
||||||
|
:math:`+: P \times P \rightarrow P` with :math:`(a,b) \mapsto a + b`
|
||||||
|
|
||||||
|
:math:`+: S \times S \rightarrow S` with :math:`(a,b) \mapsto a + b`
|
||||||
|
|
||||||
|
:math:`+: C \times C \rightarrow C` with :math:`(a,b) \mapsto a + b`
|
||||||
|
|
||||||
|
and :math:`a + b :=` ``a.fuse(b)`` for each operation
|
||||||
|
|
||||||
|
|
||||||
|
:math:`-: P \rightarrow P` with :math:`a \mapsto -a`
|
||||||
|
|
||||||
|
:math:`-: S \rightarrow S` with :math:`a \mapsto -a`
|
||||||
|
|
||||||
|
:math:`-: C \rightarrow C` with :math:`a \mapsto -a`
|
||||||
|
|
||||||
|
and :math:`b + (-a) :=` ``b.cut(a)`` for each operation (implicit definition)
|
||||||
|
|
||||||
|
|
||||||
|
:math:`\&: P \times P \rightarrow P` with :math:`(a,b) \mapsto a \& b`
|
||||||
|
|
||||||
|
:math:`\&: S \times S \rightarrow S` with :math:`(a,b) \mapsto a \& b`
|
||||||
|
|
||||||
|
:math:`\&: C \times C \rightarrow C` with :math:`(a,b) \mapsto a \& b`
|
||||||
|
|
||||||
|
and :math:`a \; \& \; b :=` ``a.intersect(b)`` for each operation
|
||||||
|
|
||||||
|
Note: :math:`a \; \& \; b = (a + b) + -(a + (-b)) + -(b + (-a))`
|
||||||
|
|
||||||
|
**Abelian groups**
|
||||||
|
|
||||||
|
:math:`( P, p_0, +, -)`, :math:`( S, s_0, +, -)`, :math:`( C, c_0, +, -)` are abelian groups
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
* The implementation ``a - b = a.cut(b)`` needs to be read as :math:`a + (-b)` since the group does not have a binary ``-`` operation. As such, :math:`a - (b - c) = a + -(b + -c)) \ne a - b + c`
|
||||||
|
|
||||||
|
* This definition also includes that neither ``-`` nor ``&`` are commutative.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Locations, planes and location arithmentic
|
||||||
|
---------------------------------------------
|
||||||
|
|
||||||
|
:math:`L := \lbrace` ``Location((x, y, z), (a, b, c))`` :math:`: x,y,z \in R \land a,b,c \in R\rbrace` with :math:`a,b,c` being angles in degrees
|
||||||
|
|
||||||
|
:math:`Q := \lbrace` ``Plane(o, x, z)`` :math:`: o,x,z ∈ R^3 \land \|x\| = \|z\| = 1\rbrace` with ``o`` being the origin and ``x``, ``z`` the x- and z-direction of the plane.
|
||||||
|
|
||||||
|
:math:`*: L \times L \rightarrow L` (multiply two locations :math:`l_1, l_2 \in L`, i.e. ``l1 * l2``)
|
||||||
|
|
||||||
|
:math:`*: Q \times L \rightarrow Q` (move plane :math:`p \in Q` to location :math:`l \in L`, i.e. ``Plane(p.to_location() * l)``)
|
||||||
|
|
||||||
|
Neutral element: :math:`l_0 \in L`: ``Location()``
|
||||||
|
|
||||||
|
Inverse element: :math:`l^{-1} \in L`: ``l.inverse()``
|
||||||
|
|
||||||
|
|
||||||
|
**Placing objects onto planes**
|
||||||
|
|
||||||
|
:math:`*: Q \times P \rightarrow P` (locate an object :math:`p \in P` onto plane :math:`q \in Q`, i.e. ``p.moved(q.to_location())``)
|
||||||
|
|
||||||
|
:math:`*: Q \times S \rightarrow S` (locate an object :math:`s \in S` onto plane :math:`q \in Q`, i.e. ``s.moved(q.to_location())``)
|
||||||
|
|
||||||
|
:math:`*: Q \times C \rightarrow C` (locate an object :math:`c \in C` onto plane :math:`q \in Q`, i.e. ``c.moved(q.to_location())``)
|
||||||
|
|
||||||
|
|
||||||
|
**Placing objects at locations**
|
||||||
|
|
||||||
|
:math:`*: L \times P \rightarrow P` (locate an object :math:`p \in P` at location :math:`l \in L`, i.e. ``p.moved(l)``)
|
||||||
|
|
||||||
|
:math:`*: L \times S \rightarrow S` (locate an object :math:`s \in S` at location :math:`l \in L`, i.e. ``s.moved(l)``)
|
||||||
|
|
||||||
|
:math:`*: L \times C \rightarrow C` (locate an object :math:`c \in C` at location :math:`l \in L`, i.e. ``c.moved(l)``)
|
||||||
34
docs/algebra_performance.rst
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
.. _algebra_performance:
|
||||||
|
|
||||||
|
Performance considerations in algebra mode
|
||||||
|
===============================================
|
||||||
|
|
||||||
|
Creating lots of Shapes in a loop means for every step ``fuse`` and ``clean`` will be called.
|
||||||
|
In an example like the below, both functions get slower and slower the more objects are
|
||||||
|
already fused. Overall it takes on an M1 Mac 4.76 sec.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
diam = 80
|
||||||
|
holes = Sketch()
|
||||||
|
r = Rectangle(2, 2)
|
||||||
|
for loc in GridLocations(4, 4, 20, 20):
|
||||||
|
if loc.position.X**2 + loc.position.Y**2 < (diam / 2 - 1.8) ** 2:
|
||||||
|
holes += loc * r
|
||||||
|
|
||||||
|
c = Circle(diam / 2) - holes
|
||||||
|
|
||||||
|
|
||||||
|
One way to avoid it is to use lazy evaluation for the algebra operations. Just collect all objects and
|
||||||
|
then call ``fuse`` (``+``) once with all objects and ``clean`` once. Overall it takes 0.19 sec.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
r = Rectangle(2, 2)
|
||||||
|
holes = [
|
||||||
|
loc * r
|
||||||
|
for loc in GridLocations(4, 4, 20, 20).locations
|
||||||
|
if loc.position.X**2 + loc.position.Y**2 < (diam / 2 - 1.8) ** 2
|
||||||
|
]
|
||||||
|
|
||||||
|
c = Circle(diam / 2) - holes
|
||||||
BIN
docs/assets/location-example-01.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
docs/assets/location-example-02.png
Normal file
|
After Width: | Height: | Size: 37 KiB |
BIN
docs/assets/location-example-03.png
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
docs/assets/location-example-04.png
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
docs/assets/location-example-05.png
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
docs/assets/location-example-06.png
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
docs/assets/location-example-07.png
Normal file
|
After Width: | Height: | Size: 46 KiB |
|
|
@ -270,12 +270,18 @@ customized to match the look and feel of your company's documentation. They also
|
||||||
provide multiple output formats, support for multiple languages and can be
|
provide multiple output formats, support for multiple languages and can be
|
||||||
integrated with code management tools.
|
integrated with code management tools.
|
||||||
|
|
||||||
**********************
|
****************************************
|
||||||
Build123d Key Concepts
|
Key Concepts (context mode)
|
||||||
**********************
|
****************************************
|
||||||
|
|
||||||
.. include:: key_concepts.rst
|
.. include:: key_concepts.rst
|
||||||
|
|
||||||
|
****************************************
|
||||||
|
Key Concepts (algebra mode)
|
||||||
|
****************************************
|
||||||
|
|
||||||
|
.. include:: key_concepts_algebra.rst
|
||||||
|
|
||||||
************************
|
************************
|
||||||
Advantages Over CadQuery
|
Advantages Over CadQuery
|
||||||
************************
|
************************
|
||||||
|
|
|
||||||
135
docs/key_concepts_algebra.rst
Normal file
|
|
@ -0,0 +1,135 @@
|
||||||
|
|
||||||
|
Build123d's algebra mode works on objects of the classes ``Shape``, ``Part``, ``Sketch`` and ``Curve`` and is based on two concepts:
|
||||||
|
|
||||||
|
1. **Object arithmetic**
|
||||||
|
2. **Placement arithmetic**
|
||||||
|
|
||||||
|
Object arithmetic
|
||||||
|
=====================
|
||||||
|
|
||||||
|
- Creating a box and a cylinder centered at ``(0, 0, 0)``
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
b = Box(1, 2, 3)
|
||||||
|
c = Cylinder(0.2, 5)
|
||||||
|
|
||||||
|
- Fusing a box and a cylinder
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
r = Box(1, 2, 3) + Cylinder(0.2, 5)
|
||||||
|
|
||||||
|
- Cutting a cylinder from a box
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
r = Box(1, 2, 3) - Cylinder(0.2, 5)
|
||||||
|
|
||||||
|
- Intersecting a box and a cylinder
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
r = Box(1, 2, 3) & Cylinder(0.2, 5)
|
||||||
|
|
||||||
|
**Notes:**
|
||||||
|
|
||||||
|
* `b`, `c` and `r` are instances of class ``Compound`` and can be viewed with every viewer that can show ``build123d.Compound`` objects.
|
||||||
|
* A discussion around performance can be found in :ref:`algebra_performance`.
|
||||||
|
|
||||||
|
|
||||||
|
Placement arithmetic
|
||||||
|
=======================
|
||||||
|
|
||||||
|
A ``Part``, ``Sketch``or ``Curve`` does not have any location or rotation paramater.
|
||||||
|
The rationale is that an object defines its topology (shape, sizes and its center), but does not know
|
||||||
|
where in space it will be located. Instead, it will be relocated with the ``*`` operator onto a plane
|
||||||
|
and to location relative to the plane (similar ``moved``).
|
||||||
|
|
||||||
|
The generic forms of object placement are:
|
||||||
|
|
||||||
|
1. Placement on ``plane`` or at ``location`` relative to XY plane:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
plane * alg_compound
|
||||||
|
location * alg_compound
|
||||||
|
|
||||||
|
2. Placement on the ``plane`` and then moved relative to the ``plane`` by ``location``
|
||||||
|
(the location is relative to the local corrdinate system of the plane).
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
plane * location * alg_compound
|
||||||
|
|
||||||
|
|
||||||
|
**???** Details can be found in [Locations](./docs/locations.md).
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
- Box on the ``XY`` plane, centered at `(0, 0, 0)` (both forms are equivalent):
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
Plane.XY * Box(1, 2, 3)
|
||||||
|
|
||||||
|
Box(1, 2, 3)
|
||||||
|
|
||||||
|
Note: On the ``XY`` plane no placement is needed (mathematically ``Plane.XY *`` will not change the
|
||||||
|
location of an object).
|
||||||
|
|
||||||
|
- Box on the ``XY`` plane centered at `(0, 1, 0)` (all three are equivalent):
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
Plane.XY * Pos(0, 1, 0) * Box(1, 2, 3)
|
||||||
|
|
||||||
|
Pos(0, 1, 0) * Box(1, 2, 3)
|
||||||
|
|
||||||
|
Pos(y=1) * Box(1, 2, 3)
|
||||||
|
|
||||||
|
Note: Again, ``Plane.XY`` can be omitted.
|
||||||
|
|
||||||
|
- Box on plane ``Plane.XZ``:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
Plane.XZ * Box(1, 2, 3)
|
||||||
|
|
||||||
|
- Box on plane ``Plane.XZ`` with a location ``(x=1, y=2, z=3)`` relative to the ``XZ`` plane, i.e.,
|
||||||
|
using the x-, y- and z-axis of the ``XZ`` plane:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
Plane.XZ * Pos(1, 2, 3) * Box(1, 2, 3)
|
||||||
|
|
||||||
|
- Box on plane ``Plane.XZ`` moved to ``(x=1, y=2, z=3)`` relative to this plane and rotated there
|
||||||
|
by the angles `(x=0, y=100, z=45)` around ``Plane.XZ`` axes:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
Plane.XZ * Pos(1, 2, 3) * Rot(0, 100, 45) * Box(1, 2, 3)
|
||||||
|
|
||||||
|
Location((1, 2, 3), (0, 100, 45)) * Box(1, 2, 3)
|
||||||
|
|
||||||
|
Note: ``Pos * Rot`` is the same as using ``Location`` directly
|
||||||
|
|
||||||
|
- Box on plane ``Plane.XZ`` rotated on this plane by the angles ``(x=0, y=100, z=45)`` (using the
|
||||||
|
x-, y- and z-axis of the ``XZ`` plane) and then moved to ``(x=1, y=2, z=3)`` relative to the ``XZ`` plane:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
Plane.XZ * Rot(0, 100, 45) * Pos(0,1,2) * Box(1, 2, 3)
|
||||||
|
|
||||||
|
|
||||||
|
Combing both concepts
|
||||||
|
==========================
|
||||||
|
|
||||||
|
**Object arithmetic** and **Placement at locations** can be combined:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
b = Plane.XZ * Rot(x=30) * Box(1, 2, 3) + Plane.YZ * Pos(x=-1) * Cylinder(0.2, 5)
|
||||||
|
|
||||||
|
**Note:** In Python ``*`` binds stronger then ``+``, ``-``, ``&``, hence brackets are not needed.
|
||||||
|
|
||||||
155
docs/location_arithmetic.rst
Normal file
|
|
@ -0,0 +1,155 @@
|
||||||
|
.. _location_arithmetics:
|
||||||
|
|
||||||
|
Location arithmetic for algebra mode
|
||||||
|
======================================
|
||||||
|
|
||||||
|
|
||||||
|
Position a shape relative to the XY plane
|
||||||
|
---------------------------------------------
|
||||||
|
|
||||||
|
For the following use the helper function:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
def location_symbol(self, l=1) -> Compound:
|
||||||
|
axes = SVG.axes(axes_scale=l).locate(self)
|
||||||
|
return Compound.make_compound(axes)
|
||||||
|
|
||||||
|
|
||||||
|
1. **Positioning at a location**
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
loc = Location((0.1, 0.2, 0.3), (10, 20, 30))
|
||||||
|
|
||||||
|
face = loc * Rectangle(1,2)
|
||||||
|
|
||||||
|
show_object(face, name="face")
|
||||||
|
show_object(location_symbol(loc), name="location")
|
||||||
|
|
||||||
|
|
||||||
|
.. image:: assets/location-example-01.png
|
||||||
|
|
||||||
|
2) **Positioning on a plane**
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
plane = Plane.XZ
|
||||||
|
|
||||||
|
face = plane * Rectangle(1, 2)
|
||||||
|
|
||||||
|
show_object(face, name="face")
|
||||||
|
show_object(plane_symbol(plane), name="plane")
|
||||||
|
|
||||||
|
|
||||||
|
.. image:: assets/location-example-07.png
|
||||||
|
|
||||||
|
Note that the ``x``-axis and the ``y``-axis of the plane are on the ``x``-axis and the ``z``-axis of the world coordinate system (red and blue axis)
|
||||||
|
|
||||||
|
|
||||||
|
Relative positioning to a plane
|
||||||
|
------------------------------------
|
||||||
|
|
||||||
|
1. **Position an object on a plane relative to the plane**
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
loc = Location((0.1, 0.2, 0.3), (10, 20, 30))
|
||||||
|
|
||||||
|
face = loc * Rectangle(1,2)
|
||||||
|
|
||||||
|
box = Plane(loc) * Pos(0.2, 0.4, 0.1) * Box(0.2, 0.2, 0.2)
|
||||||
|
# box = Plane(face.location) * Pos(0.2, 0.4, 0.1) * Box(0.2, 0.2, 0.2)
|
||||||
|
# box = loc * Pos(0.2, 0.4, 0.1) * Box(0.2, 0.2, 0.2)
|
||||||
|
|
||||||
|
show_object(face, name="face")
|
||||||
|
show_object(location_symbol(loc), name="location")
|
||||||
|
show_object(box, name="box")
|
||||||
|
|
||||||
|
|
||||||
|
.. image:: assets/location-example-02.png
|
||||||
|
|
||||||
|
The ``x``, ``y``, ``z`` components of ``Pos(0.2, 0.4, 0.1)`` are relative to the ``x``-axis, ``y``-axis or
|
||||||
|
``z``-axis of the underlying location ``loc``.
|
||||||
|
|
||||||
|
Note: ``Plane(loc) *``, ``Plane(face.location) *`` and ``loc *`` are equivalent in this example.
|
||||||
|
|
||||||
|
2. **Rotate an object on a plane relative to the plane**
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
loc = Location((0.1, 0.2, 0.3), (10, 20, 30))
|
||||||
|
|
||||||
|
face = loc * Rectangle(1,2)
|
||||||
|
|
||||||
|
box = Plane(loc) * Rot(z=80) * Box(0.2, 0.2, 0.2)
|
||||||
|
|
||||||
|
show_object(face, name="face")
|
||||||
|
show_object(location_symbol(loc), name="location")
|
||||||
|
show_object(box, name="box")
|
||||||
|
|
||||||
|
|
||||||
|
.. image:: assets/location-example-03.png
|
||||||
|
|
||||||
|
The box is rotated via ``Rot(z=80)`` around the ``z``-axis of the underlying location
|
||||||
|
(and not of the z-axis of the world).
|
||||||
|
|
||||||
|
More general:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
loc = Location((0.1, 0.2, 0.3), (10, 20, 30))
|
||||||
|
|
||||||
|
face = loc * Rectangle(1,2)
|
||||||
|
|
||||||
|
box = loc * Rot(20, 40, 80) * Box(0.2, 0.2, 0.2)
|
||||||
|
|
||||||
|
show_object(face, name="face")
|
||||||
|
show_object(location_symbol(loc), name="location")
|
||||||
|
show_object(box, name="box")
|
||||||
|
|
||||||
|
|
||||||
|
.. image:: assets/location-example-04.png
|
||||||
|
|
||||||
|
The box is rotated via ``Rot(20, 40, 80)`` around all three axes relative to the plane.
|
||||||
|
|
||||||
|
3. **Rotate and position an object relative to a location**
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
loc = Location((0.1, 0.2, 0.3), (10, 20, 30))
|
||||||
|
|
||||||
|
face = loc * Rectangle(1,2)
|
||||||
|
|
||||||
|
box = loc * Rot(20, 40, 80) * Pos(0.2, 0.4, 0.1) * Box(0.2, 0.2, 0.2)
|
||||||
|
|
||||||
|
show_object(face, name="face")
|
||||||
|
show_object(location_symbol(loc), name="location")
|
||||||
|
show_object(box, name="box")
|
||||||
|
show_object(location_symbol(loc * Rot(20, 40, 80), 0.5), options={"color":(0, 255, 255)}, name="local_location")
|
||||||
|
|
||||||
|
|
||||||
|
.. image:: assets/location-example-05.png
|
||||||
|
|
||||||
|
The box is positioned via ``Pos(0.2, 0.4, 0.1)`` relativce to the location ``loc * Rot(20, 40, 80)``
|
||||||
|
|
||||||
|
4. **Position and rotate an object relative to a location**
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
loc = Location((0.1, 0.2, 0.3), (10, 20, 30))
|
||||||
|
|
||||||
|
face = loc * Rectangle(1,2)
|
||||||
|
|
||||||
|
box = loc * Pos(0.2, 0.4, 0.1) * Rot(20, 40, 80) * Box(0.2, 0.2, 0.2)
|
||||||
|
|
||||||
|
show_object(face, name="face")
|
||||||
|
show_object(location_symbol(loc), name="location")
|
||||||
|
show_object(box, name="box")
|
||||||
|
show_object(location_symbol(loc * Pos(0.2, 0.4, 0.1), 0.5), options={"color":(0, 255, 255)}, name="local_location")
|
||||||
|
|
||||||
|
|
||||||
|
.. image:: assets/location-example-06.png
|
||||||
|
|
||||||
|
Note: This is the same as `box = loc * Location((0.2, 0.4, 0.1), (20, 40, 80)) * Box(0.2, 0.2, 0.2)`
|
||||||
|
|
||||||