Paths
Contents
Paths#
Magpylib objects all have position
and orientation
attributes in the global reference frame. These attributes can be single instances describing a single position and a single orientation of an object, but they can also be vectors of positions and orientations. In this case the attributes represent multiple object locations and orientaions and are referred to as a path. When the field of an object is computed, it is automatically computed for the whole path. The reason is that computation is much more efficient when all instances are computed in a single operation. The introduction to position
and orientation
attributes and path can be found in Position and orientation. Here we show how to work with paths properly.
Assigning absolute paths#
Absolute object paths are assigned at initialization or through the object properties.
import numpy as np
from scipy.spatial.transform import Rotation as R
import magpylib as magpy
ts = np.linspace(0, 10, 51)
pos = np.array([(t, 0, np.sin(t)) for t in ts])
ori = R.from_rotvec(np.array([(0, -np.cos(t)*0.785, 0) for t in ts]))
# set path at initialization
sensor = magpy.Sensor(position=pos, orientation=ori)
# set path through properties
cube = magpy.magnet.Cuboid(magnetization=(0,0,1), dimension=(.5,.5,.5))
cube.position = pos + np.array((0,0,3))
cube.orientation = ori
magpy.show(sensor, cube, style_path_frames=10)

Move and rotate#
The attributes position and orientation can be either of “scalar” nature, i.e. a single position or a single rotation, or “vectors” when they are arrays of such scalars. The two attributes together define an object “path”.
The move and rotate methods obey the following rules:
Scalar input is applied to the whole object path, starting with path index
start
. With the defaultstart='auto'
the index is set tostart=0
and the functionality is moving objects around.Vector input of length \(n\) applies the individual \(n\) operations to \(n\) object path entries, starting with path index
start
. Padding applies when the input exceeds the existing path. With the defaultstart='auto'
the index is set tostart=len(object path)
and the functionality is appending paths.
import magpylib as magpy
sensor = magpy.Sensor()
sensor.move((1,1,1)) # scalar input is by default applied
print(sensor.position) # to the whole path
# out: [1. 1. 1.]
sensor.move([(1,1,1), (2,2,2)]) # vector input is by default appended
print(sensor.position) # to the existing path
# out: [[1. 1. 1.] [2. 2. 2.] [3. 3. 3.]]
sensor.move((1,1,1), start=1) # scalar input and start=1 is applied
print(sensor.position) # to whole path starting at index 1
# out: [[1. 1. 1.] [3. 3. 3.] [4. 4. 4.]]
sensor.move([(0,0,10), (0,0,20)], start=1) # vector input and start=1 merges
print(sensor.position) # the input with the existing path
# out: [[ 1. 1. 1.] [ 3. 3. 13.] [ 4. 4. 24.]] # starting at index 1.
Relative paths#
move
and rotate
input is interpreted relative to the existing path. Vector input is by default appended:
import numpy as np
from magpylib.magnet import Sphere
x_path = np.linspace((0,0,0), (10,0,0), 10)[1:]
z_path = np.linspace((0,0,0), (0,0,10), 10)[1:]
sphere = Sphere(magnetization=(0,0,1), diameter=3)
for _ in range(3):
sphere.move(x_path).move(z_path)
sphere.show()

Merging paths#
Complex paths can be created by merging multiple path operations. This is done with vector input for the move
and rotate
methods, and choosing values for start
that will make the paths overlap. In the following example we combine a linear path with a rotation about self (anchor=None
) until path index 30. Thereon, a second rotation about the origin is applied, creating a spiral motion.
import numpy as np
from magpylib.magnet import Cuboid
cube = Cuboid(magnetization=(0,0,100), dimension=(2,2,2))
cube.position = np.linspace((0,0,0), (10,0,0), 60)
cube.rotate_from_rotvec(np.linspace((0,0,0), (0,0,360), 30), start=0)
cube.rotate_from_rotvec(np.linspace((0,0,0), (0,0,360), 30), anchor=0, start=30)
cube.show(backend='plotly', animation=True)