def __init__(self, constraint_0, constraint_1, mode: str): """Creates line ARGS: constraint_0: Point object or ndarray representing a vector to (first) base point constraint_1: Point object or ndarray representing a vector to second base point or ndarray representing vector parallel to line mode (str): 'point' for defining line with two points or 'vector' for point and vector form """ mode = utility.modecheck_type(mode) utility.argcheck_type(self._argtypes_point, constraint_0) utility.argcheck_dim(self._dimension, constraint_0, constraint_1) self.__point_a = utility.vec(constraint_0) if mode == 'point': utility.argcheck_type(self._argtypes_point, constraint_1) self.__point_b = utility.vec(constraint_1) self.__vector = self.__point_b - self.__point_a elif mode == 'vector': utility.argcheck_type(self._argtypes_vector, constraint_1) self.__vector = utility.vec(constraint_1) self.__point_b = self.__point_a + self.__vector else: e_str = f"Line parameter \'mode\' takes either \'point\' or \'vector\' as argument. Unknown argument {mode}" raise ValueError(e_str)
def map_xyz_to_uv(origin, u_axis: np.ndarray, normal: np.ndarray, point, norm: bool = True) -> np.ndarray: """Map coordinates of a point in 3D space to local UV coordinates. ARGS: origin: Origin of local coordinate system. Either Point object or vector. u_axis (np.ndarray): vector defining local U axis normal (np.ndarray): normal pointing out of UV plane i.e. the plane in 3D space on which the UV coordinate system resides point: Point to be translated to UV projection. Either Point object or vector. norm (bool): normalize UV coordinate system (default: True) or use U vector to scale UV system. RETURNS: uv_coords (UVPoint): UVPoint object on UV plane. """ origin = utility.vec(origin) point = utility.vec(point) utility.argcheck_dim(3, origin, u_axis, normal, point) point = point - origin v_axis = np.cross(u_axis, -normal) if norm: #normalize coordinate system u_axis = u_axis / np.linalg.norm(u_axis) v_axis = v_axis / np.linalg.norm(v_axis) uv_system = np.stack((u_axis, v_axis)) uv_coords = np.dot(uv_system, point) return uv_coords
def __init__(self, point_0: UVPoint, point_1: UVPoint, point_2: UVPoint): utility.argcheck_dim(self._dimension, point_0, point_1, point_2) utility.argcheck_type(self._argtypes_point, point_0) utility.argcheck_type(self._argtypes_point, point_1) utility.argcheck_type(self._argtypes_point, point_2) self.__point_a = utility.vec(point_0) self.__point_b = utility.vec(point_1) self.__point_c = utility.vec(point_2) self.__edge_a = UVLine(self.__point_a, self.__point_b) self.__edge_b = UVLine(self.__point_b, self.__point_c) self.__edge_c = UVLine(self.__point_c, self.__point_a)
def __init__(self, vert_0, vert_1): """Creates Edge ARGS: vert_0: Vertex object or ndarray representing vector to vertex vert_1: Vertex object or ndarray representing vector to vertex """ utility.argcheck_type(self._argtypes_vert, vert_0) utility.argcheck_type(self._argtypes_vert, vert_1) utility.argcheck_dim(self._dimension, vert_0, vert_1) self.__vertex_a = utility.vec(vert_0) self.__vertex_b = utility.vec(vert_1) self.__vector = self.__vertex_b - self.__vertex_a
def __init__(self, constraint_0, constraint_1, constraint_2, mode: str): """Creates a plane. 3 forms of representation are possible: - three points - point and two vectors defining plane - point, vector parallel to plane and vector normal to plane ARGS: constraint_0: Point object or ndarray representing vector to base point constraint_1: Point object or ndarray representing vector to second base point or ndarray representing vector parallel to plane constraint_2: Point object or ndarray representing vector to third base point or ndarray representing second vector parallel to plane (non-parallel to constraint_1) or ndarray representing vector normal to plane mode (str): "point", "vector", "normal" for plane representation """ utility.argcheck_dim(self._dimension, constraint_0, constraint_1, constraint_2) utility.argcheck_type(self._argtypes_point, constraint_0) mode = utility.modecheck_type(mode) self.__point_a = utility.vec(constraint_0) if mode == 'point': utility.argcheck_type(self._argtypes_point, constraint_1) utility.argcheck_type(self._argtypes_point, constraint_2) self.__point_b = utility.vec(constraint_1) self.__point_c = utility.vec(constraint_2) self.__vector_u = self.__point_b - self.__point_a self.__vector_v = self.__point_c - self.__point_a else: utility.argcheck_type(self._argtypes_vector, constraint_1) utility.argcheck_type(self._argtypes_vector, constraint_2) self.__vector_u = utility.vec(constraint_1) self.__point_b = self.__point_a + self.__vector_u if mode == 'vector': self.__vector_v = utility.vec(constraint_2) elif mode == 'normal': # generate second plane defining vector to calculate points on plane self.__vector_v = cross(self.__point_c, self.__vector_u) else: e_str = f"Plane parameter \'mode\' takes either \'point\', \'vector\' or \'normal\' as argument. " \ f"Unknown argument {mode}" raise ValueError(e_str) self.__point_c = self.__point_a + self.__vector_v self.__normal = cross(self.__vector_u, self.__vector_v)
def __init__(self, element_0, element_1, element_2 = None): sigma = 1e-8 c_in_tol = lambda coord, tolerance: abs(coord) <= tolerance tol_comp = lambda c0, c1: c0 and c1 # Accounting for all initialization modes if element_2 is not None: # Vertex initialization mode utility.argcheck_type(self._argtypes_vert, element_0) utility.argcheck_type(self._argtypes_vert, element_1) utility.argcheck_type(self._argtypes_vert, element_2) self.__vertex_a = utility.vec(element_0) self.__vertex_b = utility.vec(element_1) self.__vertex_c = utility.vec(element_2) else: if type(element_0) == self._argtypes_edge[0] and type(element_1) == self._argtypes_edge[0]: # Two Edge initialization mode v0a = utility.vec(element_0.vertex_a) v0b = utility.vec(element_0.vertex_b) v1a = utility.vec(element_1.vertex_a) v1b = utility.vec(element_1.vertex_b) if reduce(tol_comp, c_in_tol(v0a - v1a, sigma)) or reduce(tol_comp, c_in_tol(v0a - v1b, sigma)): self.__vertex_a = v0b elif reduce(tol_comp, c_in_tol(v0b - v1a, sigma)) or reduce(tol_comp, c_in_tol(v0b - v1b, sigma)): self.__vertex_a = v0a else: raise ValueError("Passed Edge objects do not share at least 1 Vertex.") self.__vertex_b = v1a self.__vertex_c = v1b else: # Vertex and Edge initialization mode args = [element_0, element_1] self.__vertex_a = utility.vec(next(filter(lambda a: type(a) != Edge, args))) utility.argcheck_type(self._argtypes_vert, self.__vertex_a) arg_edge = next(filter(lambda a: type(a) == Edge, args)) self.__vertex_b = utility.vec(arg_edge.vertex_a) self.__vertex_c = utility.vec(arg_edge.vertex_b) utility.argcheck_dim(self._dimension, self.__vertex_a, self.__vertex_b, self.__vertex_c) self.__edge_a = Edge(self.__vertex_a, self.__vertex_b) self.__edge_b = Edge(self.__vertex_b, self.__vertex_c) self.__edge_c = Edge(self.__vertex_c, self.__vertex_a) self.__vector_u = self.__vertex_b - self.__vertex_a self.__vector_v = self.__vertex_c - self.__vertex_a self.__normal = cross(self.__vector_u, self.__vector_v)
def vertex_b(self, new_vert): utility.argcheck_type(self._argtypes_vert, new_vert) utility.argcheck_dim(self._dimension, new_vert) self.__vertex_b = utility.vec(new_vert) self.__vector = self.__vertex_b - self.__vertex_a
def vertex_c(self, new_vert): utility.argcheck_type(self._argtypes_vert, new_vert) utility.argcheck_dim(self._dimension, new_vert) self.__vertex_c = utility.vec(new_vert) self.__recalc_edges() self.__recalc_normal()
def point_c(self, new_const): utility.argcheck_type(self._argtypes_point, new_const) utility.argcheck_dim(self._dimension, new_const) self.__point_c = utility.vec(new_const) self.__recalc_normal()
def point_b(self, new_const): utility.argcheck_type( self._argtypes_point, new_const) utility.argcheck_dim(self._dimension, new_const) self.__point_b = utility.vec(new_const) self.__vector = self.__point_b - self.__point_a