slmsuite.holography.toolbox.fit_3pt

fit_3pt(y0, y1, y2, N=None, x0=(0, 0), x1=(1, 0), x2=(0, 1), orientation_check=False)[source]

Fits three points to an affine transformation. This transformation is given by:

\[\vec{y} = M \cdot \vec{x} + \vec{b}\]

At base, this function finds and optionally uses affine transformations:

y0 = (1.,1.)    # Origin
y1 = (2.,2.)    # First point in x direction
y2 = (1.,2.)    # first point in y direction

# If N is None, return a dict with keys "M", and "b"
affine_dict =   fit_3pt(y0, y1, y2, N=None)

# If N is provided, evaluates the transformation on indices with the given shape
# In this case, the requested 5x5 indices results in an array with shape (2,25)
vector_array =  fit_3pt(y0, y1, y2, N=(5,5))

However, fit_3pt is more powerful that this, and can fit an affine transformation to semi-arbitrary sets of points with known indices in the coordinate system of the dependent variable \(\vec{x}\), as long as the passed indices x0, x1, x2 are not colinear.

# y11 is at x index (1,1), etc
fit_3pt(y11, y34, y78, N=(5,5), x0=(1,1), x1=(3,4), x2=(7,8))

# These indices don't have to be integers
fit_3pt(a, b, c, N=(5,5), x0=(np.pi,1.5), x1=(20.5,np.sqrt(2)), x2=(7.7,42.0))

Optionally, basis vectors can be passed directly instead of adding these vectors to the origin, by making use of passing None for x1 or x2:

origin =    (1.,1.)     # Origin
dv1 =       (1.,1.)     # Basis vector in x direction
dv2 =       (1.,0.)     # Basis vector in y direction

# The following are equivalent:
option1 = fit_3pt(origin, np.add(origin, dv1), np.add(origin, dv2), N=(5,5))
option2 = fit_3pt(origin, dv1, dv2, N=(5,5), x1=None, x2=None)

assert option1 == option2
Parameters
  • y0 (array_like) – See y2.

  • y1 (array_like) – See y2.

  • y2 (array_like) – 2-vectors defining the affine transformation. These vectors correspond to positions which we will fit our transformation to. These vectors have corresponding indices x0, x1, x2; see these variables for more information. With the default values for the indices, y0 is base/origin and y1 and y2 are the positions of the first point in the x and y directions of index-space, respectively. Cleaned with format_2vectors().

  • N (int OR (int, int) OR numpy.ndarray OR None) – Size of the grid of vectors to return (N1, N2). If a scalar is passed, then the grid is assumed square. If None or any non-positive integer is passed, then a dictionary with the affine transformation is instead returned. Defaults to None.

  • x0 (array_like OR None) – See x2.

  • x1 (array_like OR None) – See x2.

  • x2 (array_like OR None) – Should not be colinear. If x0 is None, defaults to the origin (0,0). If x1 or x2 are None, y1 or y2 are interpreted as differences between (0,0) and (1,0) or (0,0) and (0,1), respectively, instead of as positions. Cleaned with format_2vectors().

  • orientation_check (bool) – If True, removes the last two points in the affine grid. If False, does nothing.

Returns

2-vector or array of 2-vectors (2, N) in slm coordinates. If N is None or non-positive, then returns a dictionary with keys "M" and "b" (transformation matrix and shift, respectively).

Return type

numpy.ndarray OR dict