Source code for QPolargraph.patterns.PolarScan
from QPolargraph.patterns.QScanPattern import QScanPattern
import numpy as np
[docs]
class PolarScan(QScanPattern):
'''Arc-by-arc polar scan pattern centered on the left motor pulley.
Overrides :meth:`QScanPattern.vertices` to sweep arcs of increasing
radius across the scan rectangle. Each arc is centered on the left
motor pulley position at ``(-ell/2, 0)``.
'''
def _radii(self) -> np.ndarray:
'''Return the arc radii [m] for the polar sweeps.
Returns
-------
numpy.ndarray
Radii at spacing ``step`` [mm] from the near to far corner
of the scan rectangle.
'''
L = self.polargraph.ell / 2
x1, y1, x2, y2 = self.rect
rmin = np.hypot(x1 + L, y1)
rmax = np.hypot(x2 + L, y2)
return np.arange(rmin, rmax, self.step * 1e-3)
def _intercepts(self, r: float) -> list:
'''Return the two points where arc of radius *r* crosses the scan rectangle.
Parameters
----------
r : float
Arc radius measured from the left pulley [m].
Returns
-------
list of [float, float]
``[start, end]`` intersection points ``[x, y]`` [m].
'''
p = -self.polargraph.ell / 2
x1, y1, x2, y2 = self.rect
x1 -= p
x2 -= p
if r < np.hypot(x2, y1):
r1 = [p + np.sqrt(r ** 2 - y1 ** 2), y1]
else:
r1 = [p + x2, np.sqrt(r ** 2 - x2 ** 2)]
if r < np.hypot(x1, y2):
r2 = [p + x1, np.sqrt(r ** 2 - x1 ** 2)]
else:
r2 = [p + np.sqrt(r ** 2 - y2 ** 2), y2]
return [r1, r2]
[docs]
def vertices(self) -> np.ndarray:
'''Return arc-endpoint waypoints for all polar sweeps.
Returns
-------
numpy.ndarray
``(nvertices, 2)`` array of ``(x, y)`` waypoints [m].
'''
xy = np.array([])
for n, r in enumerate(self._radii()):
p1, p2 = self._intercepts(r)
if (n % 2) == 0:
p1, p2 = p2, p1
xy = np.append(xy, [p1, p2])
return xy.reshape(-1, 2)
[docs]
def trajectory(self) -> np.ndarray:
'''Return dense arc paths for all polar sweeps for display.
Returns
-------
numpy.ndarray
``(2, npts)`` array of ``(x, y)`` coordinates [m].
'''
L = self.polargraph.ell
x = np.array([])
y = np.array([])
points = self.vertices().reshape(-1, 4)
for n, r in enumerate(self._radii()):
x1, y1, x2, y2 = points[n]
s1 = np.sqrt(r ** 2 - 2. * L * x1)
s2 = np.sqrt(r ** 2 - 2. * L * x2)
s = np.linspace(s1, s2)
thisx = (r ** 2 - s ** 2) / (2. * L)
x = np.append(x, thisx)
y = np.append(y, np.sqrt(r ** 2 - (L / 2. + thisx) ** 2))
return np.vstack([x, y])