def proj3to2(n: Vector) -> Matrix: es = List([ Vector([1.0, 0.0, 0.0]), Vector([0.0, 1.0, 0.0]), Vector([0.0, 0.0, 1.0]) ]) vs = es.fmap(lambda v: proj(v, n)) return transpose(Matrix([vs[0].unbox(), vs[1].unbox(), vs[2].unbox()]))
def test_rotate(self): b = Box([10, 10, 10], [1.0, 2.0, 0.0], [0, 1, 0]) axis = Axis(normal=Vector([-1.0, 0.0, 0.0]), origin=Vector([0.0, 1.0, 0.0])) theta = math.pi / 2 b_rotate = b.rotate(axis, theta) self.assertEqual(b_rotate, Box([10, 10, 10], [1.0, 1.0, -1.0], [0.0, 0.0, -1.0]))
def axis_to_axis(source, target): """ Rotation matrix which rotate source axis to target axis. Implemented by firstly roteta source axis to `AXES3_STD.z`, and then rotate `AXES3_STD.z` to target axis. """ source, target = Vector(source), Vector(target) # source, target = source.unbox(), target.unbox() return z_to_axis(target)@axis_to_z(source)
def from_axis_like(cls, axis_like, possible_origin=None): if possible_origin is None: possible_origin = Vector([0.0, 0.0, 0.0]) if isinstance(axis_like, Axis): normal, origin = axis_like.normal, axis_like.origin else: normal, origin = axis_like, possible_origin normal, origin = Vector(normal), Vector(origin) return Axis(normal, origin)
def test_Vector_ndarray(): v = Vector([[1, 2, 3], [4, 5, 6]]) n = np.array([[1, 4], [2, 5], [3, 6]]) assert matmul(v, n) == Vector([[14, 32], [32, 27]]) v = Vector([1, 4]) n = np.array([1, 4]) assert matmul(v, n) == np.array([17])
def axis_x_of(n: Vector) -> Vector: """ Returns: x axis if z is n. """ # FIXME add support for AXIS, lazy vector n = unit(Vector(n)) main_index_of_n = argmax(abs_(n)) result = [0.0, 0.0, 0.0] main_index_of_result = (main_index_of_n + 1) % 3 result[main_index_of_result] = n[main_index_of_n] result[main_index_of_n] = -n[main_index_of_result] return unit(Vector(result))
def get_rot_yz(axis): axis = Vector(axis) # rot_y = math.acos(axis.z) # rot_z = math.atan2(axis.y, axis.x) rot_y = math.acos(axis[2]) rot_z = math.atan2(axis[1], axis[0]) return rot_y, rot_z
class Box(Entity): shape: Vector = attr.ib(converter=Vector) origin: Vector = attr.ib(converter=Vector, default=Vector([0.0, 0.0, 0.0])) normal: Vector = attr.ib(converter=Vector, default=Vector([0.0, 0.0, 1.0])) # __slots__ = ['shape', 'origin', 'normal'] # def __init__(self, # shape: Vector, # origin: Vector = None, # normal: Vector = None): # self.shape = Vector(shape) # if origin is None: # origin = Vector([0.0, 0.0, 0.0]) # self.origin = Vector(origin) # if normal is None: # normal = Vector([0.0, 0.0, 1.0]) # self.normal = Vector(normal) # def rotate_on_direction(self, direction, theta): # from .point import Point # p_origin = Point(self.origin) # p_normal = Point(self.normal) # return self.replace(origin=p_origin._rotate_on_direction(direction, theta).origin, # normal=p_normal._rotate_on_direction(direction, theta).origin) def is_collision(self, p: 'Entity') -> bool: from dxl.shape.data.axis import Axis from dxl.shape.function.rotation.matrix import axis_to_z p_tran_rot = p.translate(-self.origin).origin @ transpose( axis_to_z(self.normal)) if ((-self.shape.x / 2 <= p_tran_rot.x < self.shape.x / 2) and (-self.shape.y / 2 <= p_tran_rot.y < self.shape.y / 2) and (-self.shape.z / 2 <= p_tran_rot.z < self.shape.z / 2)): return True else: return False def fmap(self, f): return Box(self.shape, f(self.origin), f(self.normal)) def __eq__(self, b): if not isinstance(b, Box): return False return all_close(self.shape, b.shape) and all_close(self.origin, b.origin) and all_close(self.normal, b.normal)
def test_init(self): a1 = Axis(normal=Vector([0.0, 1.0, 0.0]), origin=Vector([1.0, 2.0, 0.0])) a2 = Axis(normal=Vector([0.0, 1.0, 0.0])) assert all_close(a1.normal, Vector([0.0, 1.0, 0.0])) assert all_close(a1.origin, Vector([1.0, 2.0, 0.0])) assert all_close(a2.normal, Vector([0.0, 1.0, 0.0])) assert all_close(a2.origin, Vector([0.0, 0.0, 0.0])) self.assertTrue(isinstance(a1, Axis)) self.assertTrue(isinstance(a2, Axis))
class Axis(Entity): normal: Vector = attr.ib(converter=Vector) origin: Vector = attr.ib(converter=Vector, default=Vector([0.0, 0.0, 0.0])) def rotate_on_direction(self, direction: Vector, theta: float): from dxl.shape.function import rotate return self.replace(normal=rotate(self.normal, direction, theta), origin=rotate(self.origin, direction, theta)) def fmap(self, f): return Axis(f(self.normal), f(self.origin)) @classmethod def from_axis_like(cls, axis_like, possible_origin=None): if possible_origin is None: possible_origin = Vector([0.0, 0.0, 0.0]) if isinstance(axis_like, Axis): normal, origin = axis_like.normal, axis_like.origin else: normal, origin = axis_like, possible_origin normal, origin = Vector(normal), Vector(origin) return Axis(normal, origin)
def test_slice(): v = Vector([1.0, 2.0]) assert v[0] == 1.0
def test_rotate_on_direction(self): a = Axis(normal=Vector([0.0, 1.0, 0.0]), origin=Vector([1.0, 2.0, 0.0])) direction_x = Vector([1.0, 0.0, 0.0]) direction_y = Vector([0.0, 1.0, 0.0]) direction_z = Vector([0.0, 0.0, 1.0]) theta = math.pi / 2 a_rot_x = a.rotate_on_direction(direction_x, theta) a_rot_y = a.rotate_on_direction(direction_y, theta) a_rot_z = a.rotate_on_direction(direction_z, theta) assert all_close(a_rot_x.origin, Vector([1.0, 0.0, 2.0])) assert all_close(a_rot_x.normal, Vector([0.0, 0.0, 1.0])) assert all_close(a_rot_y.origin, Vector([0.0, 2.0, -1.0])) assert all_close(a_rot_y.normal, Vector([0.0, 1.0, 0.0])) assert all_close(a_rot_z.origin, Vector([-2.0, 1.0, 0.0])) assert all_close(a_rot_z.normal, Vector([-1.0, 0.0, 0.0]))
def test_construction(self): ax = Axis(Vector([1.0, 0.0, 0.0])) self.assertEqual(ax.normal.x, 1.0) self.assertEqual(ax.normal.z, 0.0)
def theta(position): result = np.math.acos(Vector(position).x / norm(p_xy(position))) if Vector(position).y < 0: result = 2 * np.pi - result return result
def ring_id(scanner, position): return int((Vector(position).z / scanner.axial_length + 0.5) * scanner.nb_rings * scanner.blocks[0].grid[2])
def outer_product(a: Vector, b: Vector): return Vector( [a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x])
def test_Vector_Vector_ndarray(): v = Vector([[1, 1], [1, 1]]) n = np.array([[1, 1], [1, 1]]) assert all_close(project(v, n), np.array([[0.5, 0.5], [0.5, 0.5]]))
def rotate_on_direction(self, direction: Vector, theta: float): from dxl.shape.function import rotate return self.replace(normal=rotate(self.normal, direction, theta), origin=rotate(self.origin, direction, theta)) def fmap(self, f): return Axis(f(self.normal), f(self.origin)) @classmethod def from_axis_like(cls, axis_like, possible_origin=None): if possible_origin is None: possible_origin = Vector([0.0, 0.0, 0.0]) if isinstance(axis_like, Axis): normal, origin = axis_like.normal, axis_like.origin else: normal, origin = axis_like, possible_origin normal, origin = Vector(normal), Vector(origin) return Axis(normal, origin) AXIS3_X = Axis(Vector([1.0, 0.0, 0.0])) AXIS3_Y = Axis(Vector([0.0, 1.0, 0.0])) AXIS3_Z = Axis(Vector([0.0, 0.0, 1.0])) class AXES3: x = AXIS3_X y = AXIS3_Y z = AXIS3_Z
def test_project_withvalue(): v1 = Vector([1.0, 0.0]) v2 = Vector([1.0, 1.0]) assert all_close(project(v1, v2), Vector([0.5, -0.5]))
def proj(v: Vector, n: Vector): v, n = Vector(v), Vector(n) p = project(v, n) return Vector([p[(np.argmax(n) + i + 1) % len(p)] for i in range(v.size - 1)])
def test_matmul(): v = Vector([1.0, 1.0]) assert v@v == 2.0 assert isinstance(v@v, float)
def test_random_vectors(self, v): rot = z_to_axis(Vector(v)) assert all_close(rot @ (AXIS3_Z.normal), v)
def test_matmul_with_nparray(): d = np.array([1.0, 1.0]) v = Vector(d) assert v@d == 2.0 # assert d@v == 2.0
def embed2to3(n: Vector) -> Matrix: es = List([Vector([1.0, 0.0]), Vector([0.0, 1.0])]) vs = es.fmap(lambda v: embed(v, n)).fmap(lambda v: v.unbox()) return transpose(Matrix(vs))
def test_Vector_Matrix(): v = Vector([[1, 4], [2, 5], [3, 6]]) m = Matrix([[1, 2, 3], [4, 5, 6]]) assert matmul(v, m) == Vector([[17, 22, 27], [22, 29, 36], [27, 36, 45]])
def test_Vector_Vector(): v1 = Vector([[1, 2, 3], [4, 5, 6]]) v2 = Vector([[1, 4], [2, 5], [3, 6]]) assert matmul(v1, v2) == Vector([[14, 32], [32, 27]])
def sub_box_shape(b: Box, grid: List[int]) -> Vector: return Vector([s / g for s, g in zip(b.shape, grid)])
def axis_y_of(n: Vector) -> Vector: n = unit(Vector(n)) return unit(outer_product(n, axis_x_of(n)))
def embed(v: Vector, n: Vector): v, n = Vector(v), Vector(n) from ..axes import axis_x_of, axis_y_of return axis_x_of(n) * v.x + axis_y_of(n) * v.y
def test_Matrix_Vector(): m = Matrix([[1, 2, 3], [4, 5, 6]]) v = Vector([[1, 4], [2, 5], [3, 6]]) assert matmul(m, v) == Vector([[14, 32], [32, 27]])