def test_params_from_vertices_random(): center = Vector.random(5) major_axis = Vector.random(5) extrusion = Vector.random() ratio = 0.75 e = ConstructionEllipse(center, major_axis, extrusion, ratio) params = [random.uniform(0.0001, math.tau - 0.0001) for _ in range(20)] vertices = e.vertices(params) new_params = e.params_from_vertices(vertices) for expected, param in zip(params, new_params): assert math.isclose(expected, param) # This creates the same vertex as v1 and v2 v1, v2 = e.vertices([0, math.tau]) assert v1.isclose(v2) # This should create the same param for v1 and v2, but # floating point inaccuracy produces unpredictable results: p1, p2 = e.params_from_vertices((v1, v2)) assert math.isclose(p1, 0, abs_tol=1e-9) or math.isclose( p1, math.tau, abs_tol=1e-9) assert math.isclose(p2, 0, abs_tol=1e-9) or math.isclose( p2, math.tau, abs_tol=1e-9)
def test_intersection_ray_ray_3d_random(): for _ in range(5): intersection_point = Vector.random(5) ray1 = (intersection_point, intersection_point + Vector.random()) ray2 = (intersection_point, intersection_point - Vector.random()) result = intersection_ray_ray_3d(ray1, ray2) assert len(result) == 1 assert result[0].isclose(intersection_point)
def test_circle_fast_translation(): circle = Circle.new( dxfattribs={'center': (2, 3, 4), 'extrusion': Vector.random()}) ocs = circle.ocs() offset = Vector(1, 2, 3) center = ocs.to_wcs(circle.dxf.center) + offset circle.translate(*offset) assert ocs.to_wcs(circle.dxf.center).isclose(center, abs_tol=1e-9)
def build(): circle = Circle() vertices = list( circle.vertices(linspace(0, 360, vertex_count, endpoint=False))) m = Matrix44.chain( Matrix44.axis_rotate(axis=Vector.random(), angle=random.uniform(0, math.tau)), Matrix44.translate(dx=random.uniform(-2, 2), dy=random.uniform(-2, 2), dz=random.uniform(-2, 2)), ) return synced_transformation(circle, vertices, m)
def main_insert(layout): entity, vertices = insert() entity, vertices = synced_translation(entity, vertices, dx=1, dy=0, dz=0) axis = Vector.random() angle = random_angle() for sx, sy, sz in NON_UNIFORM_SCALING: # 1. scale entity0, vertices0 = synced_scaling(entity, vertices, sx=sx, sy=sy, sz=sz) # 2. rotate entity0, vertices0 = synced_rotation(entity0, vertices0, axis=axis, angle=angle) # 3. translate entity0, vertices0 = synced_translation(entity0, vertices0, dx=random.uniform(-2, 2), dy=random.uniform(-2, 2), dz=random.uniform(-2, 2)) layout.entitydb.add(entity0) layout.add_entity(entity0) origin, x, y, z = list(vertices0) layout.add_line(origin, x, dxfattribs={ 'color': 2, 'layer': 'new axis' }) layout.add_line(origin, y, dxfattribs={ 'color': 4, 'layer': 'new axis' }) layout.add_line(origin, z, dxfattribs={ 'color': 6, 'layer': 'new axis' }) for line in entity0.virtual_entities(): line.dxf.layer = 'exploded axis' line.dxf.color = 7 layout.entitydb.add(line) layout.add_entity(line)
def build(): ellipse = Ellipse.new(dxfattribs={ 'start_param': start, 'end_param': end, }) vertices = list(ellipse.vertices(ellipse.params(vertex_count))) m = Matrix44.chain( Matrix44.axis_rotate(axis=Vector.random(), angle=random.uniform(0, math.tau)), Matrix44.translate(dx=random.uniform(-2, 2), dy=random.uniform(-2, 2), dz=random.uniform(-2, 2)), ) return synced_transformation(ellipse, vertices, m)
def main_ellipse(layout): entity, vertices, axis_vertices = ellipse(start=math.pi / 2, end=-math.pi / 2) axis = Vector.random() angle = random_angle() entity, vertices, axis_vertices = synced_rotation(entity, vertices, axis_vertices, axis=axis, angle=angle) entity, vertices, axis_vertices = synced_translation( entity, vertices, axis_vertices, dx=random.uniform(-2, 2), dy=random.uniform(-2, 2), dz=random.uniform(-2, 2)) for sx, sy, sz in UNIFORM_SCALING + NON_UNIFORM_SCALING: entity0, vertices0, axis0 = synced_scaling(entity, vertices, axis_vertices, sx, sy, sz) add(layout, entity0, vertices0, layer=f'new ellipse') layout.add_line(axis0[0], axis0[2], dxfattribs={ 'color': 6, 'linetype': 'DASHED', 'layer': 'old axis' }) layout.add_line(axis0[1], axis0[3], dxfattribs={ 'color': 6, 'linetype': 'DASHED', 'layer': 'old axis' }) p = list(entity0.vertices([0, math.pi / 2, math.pi, math.pi * 1.5])) layout.add_line(p[0], p[2], dxfattribs={ 'color': 1, 'layer': 'new axis' }) layout.add_line(p[1], p[3], dxfattribs={ 'color': 3, 'layer': 'new axis' })
def build(): arc = Arc.new( dxfattribs={ 'start_angle': random.uniform(0, 360), 'end_angle': random.uniform(0, 360), }) vertices = list(arc.vertices(arc.angles(vertex_count))) m = Matrix44.chain( Matrix44.axis_rotate(axis=Vector.random(), angle=random.uniform(0, math.tau)), Matrix44.translate(dx=random.uniform(-2, 2), dy=random.uniform(-2, 2), dz=random.uniform(-2, 2)), ) return synced_transformation(arc, vertices, m)
def test_transformation(): axis = Vector.random() angle = 1.5 ucs = UCS(origin=(3, 4, 5)) m = Matrix44.axis_rotate(axis, angle) expected_origin = m.transform(ucs.origin) expected_ux = m.transform(ucs.ux) expected_uy = m.transform(ucs.uy) expected_uz = m.transform(ucs.uz) new = ucs.transform(m) assert new.origin.isclose(expected_origin) assert new.ux.isclose(expected_ux) assert new.uy.isclose(expected_uy) assert new.uz.isclose(expected_uz)
def test_random_block_reference_transformation(sx, sy, sz, doc1: 'Drawing'): def insert(): return Insert.new(dxfattribs={ 'name': 'AXIS', 'insert': (0, 0, 0), 'xscale': 1, 'yscale': 1, 'zscale': 1, 'rotation': 0, 'layer': 'insert', }, doc=doc1), [Vector(0, 0, 0), X_AXIS, Y_AXIS, Z_AXIS] def check(lines, chk): origin, x, y, z = chk l1, l2, l3 = lines assert origin.isclose(l1.dxf.start) assert x.isclose(l1.dxf.end) assert origin.isclose(l2.dxf.start) assert y.isclose(l2.dxf.end) assert origin.isclose(l3.dxf.start) assert z.isclose(l3.dxf.end) entity0, vertices0 = insert() entity0, vertices0 = synced_scaling(entity0, vertices0, 1, 2, 3) m = Matrix44.chain( # Transformation order is important: scale - rotate - translate # Because scaling after rotation leads to a non orthogonal # coordinate system, which can not represented by the # INSERT entity. Matrix44.scale(sx, sy, sz), Matrix44.axis_rotate(axis=Vector.random(), angle=random.uniform(0, math.tau)), Matrix44.translate(dx=random.uniform(-2, 2), dy=random.uniform(-2, 2), dz=random.uniform(-2, 2)), ) entity, vertices = synced_transformation(entity0, vertices0, m) lines = list(entity.virtual_entities()) check(lines, vertices)