Source code for monalisa.geometry._volume_element_voronoi_full_radial2

"""Port of src/geom2/bmVolumeElement_voronoi_full_radial2.m."""

import numpy as np

from monalisa._mat import fix, msize, squeeze
from monalisa.geometry._volume_element1 import volume_element1
from monalisa.geometry._voronoi import voronoi
from monalisa.trajectory._traj_line_direction import traj_line_direction
from monalisa.trajectory._traj_line_reshape import traj_line_reshape
from monalisa.trajectory._traj_norm import traj_norm


[docs] def volume_element_voronoi_full_radial2(t): """Volume elements of a 2D full-radial trajectory (radial x angular Voronoi).""" if msize(t, 1) != 2: raise ValueError("The trajectory must be 2Dim") t = traj_line_reshape(t) N, nLine = msize(t, 2), msize(t, 3) t3 = np.reshape(t, (2, N, nLine), order="F") e = np.reshape(traj_line_direction(t), (2, nLine), order="F") if (N / 2 - fix(N / 2)) > 0: raise ValueError( "The number of points per line must be even, because the 0 must be at index position N/2+1" ) dr = np.zeros((N, nLine)) for i in range(nLine): dr[:, i] = t3[:, :, i].T @ e[:, i] dr = volume_element1(dr) ee = np.concatenate([e, -e], axis=1) myAngle = np.arctan2(ee[1, :], ee[0, :]) myPerm = np.argsort(myAngle, kind="stable") myAngle = myAngle[myPerm] myInvPerm = np.argsort(myPerm, kind="stable") myCutSpace = (np.pi - myAngle[-1]) + (myAngle[0] - (-np.pi)) myVoronoi_1 = (myAngle[1] - myAngle[0]) / 2 + myCutSpace / 2 myVoronoi_end = (myAngle[-1] - myAngle[-2]) / 2 + myCutSpace / 2 myAngleVoronoi = np.ravel(voronoi(myAngle[None, :]), order="F").copy() myAngleVoronoi[0] = myVoronoi_1 myAngleVoronoi[-1] = myVoronoi_end myAngleVoronoi = myAngleVoronoi[myInvPerm][:nLine] myAngleVoronoi = np.tile(myAngleVoronoi, (N, 1)) ds = squeeze(traj_norm(t)) * myAngleVoronoi v = (np.ravel(dr, order="F") * np.ravel(ds, order="F"))[None, :] dr_0 = np.mean(dr[N // 2, :]) / 2 v0 = np.pi * (dr_0**2) / (2 * nLine) v[0, N // 2 :: N] = v0 return v