m.edge = Twirler(origin, unit_z, unit_x, -2, tau/2)
m.midline = Twirler(-unit_z, unit_z, unit_y, -0.5, 0)
m.nu = nu
- #m._cp2b = BezierSegment([(x,) for x in [0.2, 0.2, 1]])
- m._beziers = [ m._bezier(u) for u in np.linspace(0, 1, nu+1) ]
- def _bezier(m,u):
- theta = u * tau
+ m._thetas = [ u * tau for u in np.linspace(0, 1, nu+1) ]
+ m._beziers = [ m._bezier(theta) for theta in m._thetas ]
+ def _bezier(m, theta):
cp = [None] * 4
cp[0] = m.edge .point(theta)
cp[3] = m.midline.point(theta*2)
ncp3 = np.linalg.norm(cp[3])
cpt = ncp3 * ncp3 / 4
- #cp2scale = m._cp2b.point_at_t(ncp3)[0]
cp2scale = 1.50 * cpt + 0.33 * (1-cpt)
cp1scale = 0.75 * cpt + 0.33 * (1-cpt)
- print('u=%d ncp3=%f cp2scale=%f' % (u, ncp3, cp2scale),
- file=sys.stderr)
+ #print('u=%d ncp3=%f cp2scale=%f' % (u, ncp3, cp2scale),
+ # file=sys.stderr)
cp[1] = cp[0] + cp1scale * m.edge .dirn (theta)
cp[2] = cp[3] + cp2scale * m.midline.dirn (theta*2)
return BezierSegment(cp)
0 <= t <= 1 across the half-traverse
0 is the edge, 1 is the midline
'''
- return m._beziers[iu].point_at_t(t)
+ return np.array(m._beziers[iu].point_at_t(t))
+
+ def point_offset(m, iu, t, offset):
+ '''
+ offset by offset perpendicular to the surface
+ at the top (iu=t=0), in the y direction
+ '''
+ p = MoebiusHalf.point(m, iu, t)
+ if t == 0:
+ dirn = m.edge.dirn(m._thetas[iu], extra_zeta=-tau/4)
+ elif iu == m.nu:
+ return MoebiusHalf.point_offset(m, 0, 1-t, -offset)
+ else:
+ vec_t = MoebiusHalf.point(m, iu, t + 0.01) - p
+ vec_u = MoebiusHalf.point(m, iu+1, t) - p
+ dirn = np.cross(vec_u, vec_t)
+ return p + offset * dirn / np.linalg.norm(dirn)
class Moebius(MoebiusHalf):
def __init__(m, nv, nw):
def point(m, v, w):
return MoebiusHalf.point(m, **m._vw2tiu_kw(v,w))
+
+ def point_offset(m, v, w, offset):
+ return MoebiusHalf.point_offset(m,
+ offset=
+ offset if w <= m.nt else -offset,
+ **m._vw2tiu_kw(v,w))