def french_fries(scale): def rod(): c = vector3.UnitCube1() m2 = np.eye(4) * scale m2[0, 0] = 0.1 * scale m2[1, 1] = 0.1 * scale m2[0:3, 3] = [+0.1 / 2.0 * 2 * scale, +0.1 / 2.0 * 2 * scale, + 1.0 / 2.0 * 2 * scale] m2[3, 3] = 1 iobj = vector3.Transformed(c, m2) # .move(-0.1/2.0, -0.1/2.0, -1.0/2.0) iobj \ .move(-0.2 * scale, -0.2 * scale, 0) \ .resize(2) \ .rotate(10, along=make_vector3(1, 1, 0), units="deg") \ .move(0.5 * scale, 0, 0) return iobj u = None for i in range(18): c = rod().rotate(-30 * i, along=make_vector3(0, 0, 1), units="deg") if u is None: u = c else: u = vector3.CrispUnion(u, c) return u
def cube_with_cylinders(scale): # SCALE = 2. # mm SCALE = 2. sz1 = 2.5 radius = 0.5 * SCALE c_len = 2 * SCALE A = make_vector4(-c_len/2.0, 0, 0) # A = make_vector4(0, 0, c_len / 2.0) # bug: aa is wrong w = make_vector4(1, 0, 0) w = w / np.linalg.norm(w[0:3]) w[3] = 1 u = make_vector4(0, 1, 0) cyl = vector3.SimpleCylinder(A, w, u, radius, radius, c_len) A2 = make_vector4(0, -c_len/2.0, 0) w2 = make_vector4(1, 0, 0) w2 = w / np.linalg.norm(w[0:3]) w[3] = 1 u2 = make_vector4(0, 1, 0) cyl_2 = vector3.SimpleCylinder(A2, u2, w2, radius, radius, c_len) cube = vector3.UnitCube1(size=sz1) union = vector3.CrispSubtract(cube, cyl_2) final_object = vector3.CrispUnion(union, cyl) # (RANGE_MIN, RANGE_MAX, STEPSIZE) = (-3, +5, 0.2) return final_object
def cage_rods(rod_r, rod_len, cage_r, N): import math un = None for i in range(N): th = i / float(N) * np.pi * 2 x, y = cage_r * math.sin(th), cage_r * math.cos(th) A = make_vector4(x, y, -rod_len / 2.) w = make_vector4(0, 0, 1) u = make_vector4(1, 0, 0) c = vector3.SimpleCylinder(A, w, u, rod_r, rod_r, rod_len) if un is None: un = c else: un = vector3.CrispUnion(un, c) return un
def first_csg(scale): m1 = np.eye(4) * 2 * scale m1[1, 1] = 0.4 * scale m1[0:3, 3] = [0, 0, 0] m1[3, 3] = 1 m2 = np.eye(4) * 1. * scale rcenter = np.array([0.5, 0, 0]) * scale m2[0:3, 3] = rcenter[0:3] m2[3, 3] = 1 m3 = np.eye(4) * 1.2 * scale m3[0:3, 3] = [1.5 * scale, 0, 0] m3[3, 3] = 1 iobj = vector3.CrispSubtract(vector3.CrispUnion(vector3.Ellipsoid(m1), vector3.Ellipsoid(m2)), vector3.Ellipsoid(m3)) return iobj
def cyl4(scale): """ Makes a nice cage with spiral bars. Don't change. """ cage = cage_rods(rod_r=1, rod_len=20, cage_r=10, N=20) from twist_z import TwistZ t = TwistZ(cage, 0.02) # cycles per mm # 0.06 is too much 0.02 is reasonable base_cyl = vector3.SimpleCylinder( make_vector4(0, 0, -10), # A make_vector4(0, 0, -1), # w make_vector4(1, 0, 0), 11., 11., 1.) ifunc = vector3.CrispUnion(base_cyl, t) # (RANGE_MIN, RANGE_MAX, STEPSIZE) = (-32, +32, 1.92 / 4.0) #15 sec! 2.5 millions voxels # (RANGE_MIN, RANGE_MAX, STEPSIZE) = (-32 / 2, +32 / 2, 1.92 / 4.0) # 2.5 sec! return ifunc
def union_of_two_cubes(scale): c2 = vector3.UnitCube1(1.) def rotate_scale_(iobj, scale, center, angle=0.): ns = vector3 import numpy m = numpy.eye(4) m[0, 0] = 0.1 iobj = ns.Transformed(iobj, m=m) iobj \ .resize(scale) \ .move(center[0], center[1], center[2]) if angle != 0.: iobj.rotate(angle, along=make_vector4(1, 1, 1), units="deg") return iobj c2 = rotate_scale_(c2, 2., [1, 1, 1]) iobj = vector3.CrispUnion(rcube_vec(1.), c2) return iobj
def rods(scale): # the scale needs to be equal to 2 in order to have a nice object def rod(): c = vector3.UnitCube1() m2 = np.eye(4) m2[0, 0] = 0.1 * scale m2[1, 1] = 0.1 * scale m2[2, 2] = scale iobj = vector3.Transformed(c, m2) iobj \ .move(-0, -0.3*scale, -1.0*scale) \ .resize(2) \ .rotate(40, along=make_vector3(1, 1, 0), units="deg") \ .move(0.5*scale, 0, 0) return iobj u = None for i in range(17): c = rod().rotate(-30 * i, along=make_vector3(0, 0, 1), units="deg") if u is None: u = c else: u = vector3.CrispUnion(u, c) return u
def cyl2(scale=1.): SCALE = scale*1. # mm un = None M = 5 + 1 for i in range(M): radius = 0.5 * SCALE c_len = 2 * SCALE * 1. / (i + 1) a_x = (i - (M - 1.) / 2.) * 1 * SCALE + -0.5 * c_len A = make_vector4(a_x, 0, 0) w = make_vector4(0, 1, 0) # m = np.eye(4) center = A # + make_vector4(0, 0, c_len/2.0) center[3] = 1 R = rotation_matrix(i * 90. / (M - 1.), make_vector4(1, 0, 0), units="deg", around=center) w = np.dot(R, np.transpose(w)) u = make_vector4(1, 0, 0) def make_uv(w, u): w = w / np.linalg.norm(w[0:3]) w[3] = 1 u = u / np.linalg.norm(u[0:3]) u[3] = 1 # print w, "u=",u assert np.linalg.norm(np.cross(w[:3], u[:3])) > 0.000000001 # cannot be parallel v3 = np.cross(w[:3], u[:3]) v3 = v3 / np.linalg.norm(v3[:3]) v = make_vector4(v3[0], v3[1], v3[2]) u3 = np.cross(v[:3], w[:3]) u3 = u3 / np.linalg.norm(u3[:3]) u = make_vector4(u3[0], u3[1], u3[2]) # return w, u return u u = make_uv(w, u) print np.linalg.norm(np.cross(w[:3], u[:3])) print np.linalg.norm(np.cross(w[:3], u[:3])) > 0.000000001 def set4th1(v): assert v.shape == (4,) v[3] = 1 return v # c = SimpleCylinder(A, w, u, radius, radius, c_len) newlen = c_len * 5 # Long and thin cyliner c1 = vector3.SimpleCylinder(set4th1(A - 1. * newlen / 2. * w), w, u, radius / 5., radius / 5., newlen) delta, twist_rate = radius * 0.2, 1./2. from vector3 import Screw c2 = Screw(A[:3], w[:3], u[:3], c_len, radius, delta, twist_rate) c_u = vector3.CrispUnion(c1, c2) # Fat cylinder CYL_ONLY = False if CYL_ONLY: c = c1 else: c = c_u if un is None: un = c else: un = vector3.CrispUnion(un, c) # (RANGE_MIN, RANGE_MAX, STEPSIZE) = (-32, +32, 1.92 / 4.0 * 1.5 / 1.5) # return un, (RANGE_MIN, RANGE_MAX, STEPSIZE) return un