def test_matrix44_rotation(): # normalization is not necessary ux = Vector(1, 2, 0) # only cartesian coord systems work uy = ux.rotate_deg(90) ucs = UCS(ux=ux, uy=uy) m = Matrix44.ucs(ux=ux.normalize(), uy=uy.normalize()) assert m.ux == ux.normalize() assert m.uy == uy.normalize() assert m.uz == (0, 0, 1) assert m.is_cartesian v = m.transform((1, 2, 3)) assert v == ucs.to_wcs((1, 2, 3)) assert m.ucs_vertex_from_wcs(v) == (1, 2, 3)
def vertices(self, params: Iterable[float]) -> Iterable[Vector]: """ Yields vertices on ellipse for iterable `params` in WCS. Args: params: param values in the range from ``0`` to ``2*pi`` in radians, param goes counter clockwise around the extrusion vector, major_axis = local x-axis = 0 rad. .. versionadded:: 0.11 """ # get main axis major_axis = Vector(self.dxf.major_axis) # local x-axis, 0 rad extrusion = Vector(self.dxf.extrusion) # local z-axis, normal vector of the ellipse plane minor_axis = extrusion.cross(major_axis) # local y-axis, pi/2 rad, need only normalized direction # normal vectors for local x- and y-axis x_axis = major_axis.normalize() y_axis = minor_axis.normalize() # point on ellipse calculation radius_x = major_axis.magnitude radius_y = radius_x * self.dxf.ratio center = Vector(self.dxf.center) for param in params: # Ellipse params in radians by definition (DXF Reference) x = math.cos(param) * radius_x y = math.sin(param) * radius_y # construct WCS coordinates, do not convert from OCS to WCS, extrusion defines only the normal vector of # the ellipse plane. yield center + (x_axis * x) + (y_axis * y)
def test_rotation(): # normalization is not necessary ux = Vector(1, 2, 0) # only cartesian coord systems work uy = ux.rotate_deg(90) ucs = UCS(ux=ux, uy=uy) assert ucs.ux == ux.normalize() assert ucs.uy == uy.normalize() assert ucs.uz == (0, 0, 1) assert ucs.is_cartesian is True
def transform(self, m: Matrix44) -> 'MText': """ Transform MTEXT entity by transformation matrix `m` inplace. .. versionadded:: 0.13 """ dxf = self.dxf old_extrusion = Vector(dxf.extrusion) new_extrusion, _ = transform_extrusion(old_extrusion, m) if dxf.hasattr('rotation') and not dxf.hasattr('text_direction'): # MTEXT is not an OCS entity, but I don't know how else to convert # a rotation angle for an entity just defined by an extrusion vector. # It's correct for the most common case: extrusion=(0, 0, 1) ocs = OCS(old_extrusion) dxf.text_direction = ocs.to_wcs(Vector.from_deg_angle( dxf.rotation)) dxf.discard('rotation') old_text_direction = Vector(dxf.text_direction) new_text_direction = m.transform_direction(old_text_direction) old_char_height_vec = old_extrusion.cross( old_text_direction).normalize(dxf.char_height) new_char_height_vec = m.transform_direction(old_char_height_vec) oblique = new_text_direction.angle_between(new_char_height_vec) dxf.char_height = new_char_height_vec.magnitude * math.sin(oblique) if dxf.hasattr('width'): width_vec = old_text_direction.normalize(dxf.width) dxf.width = m.transform_direction(width_vec).magnitude dxf.insert = m.transform(dxf.insert) dxf.text_direction = new_text_direction dxf.extrusion = new_extrusion return self