import numpy as np
+from numpy import cos, sin
+
+from bezier import BezierSegment
tau = np.pi * 2
-origin = (0,0,0)
-unit_x = (1,0,0)
-unit_y = (0,1,0)
-unit_z = (0,0,1)
+origin = np.array((0,0,0))
+unit_x = np.array((1,0,0))
+unit_y = np.array((0,1,0))
+unit_z = np.array((0,0,1))
-def ParametricCircle:
+class ParametricCircle:
def __init__(pc, c, r0, r1):
''' circle centred on c
with theta=0 point at c+r0
def point(pc, theta):
return pc._c + pc.radius(theta)
-def Twirler(ParametricCircle):
+class Twirler(ParametricCircle):
def __init__(tw, c, r0, r1, cycles, begin_zeta):
''' circle centred on c, etc.
but with an orientation at each point, orthogonal to
tw._axis = np.cross(r0, r1)
def dirn(tw, theta):
zeta = tw._begin_zeta + theta * tw._cycles
- r = radius(tw, theta)
- return cos(zeta) * r + sin(zeta) * pc._axis
+ r = tw.radius(theta)
+ return cos(zeta) * r + sin(zeta) * tw._axis
class Moebius:
- def __init__(m, n_u):
- m._edge = Twirler(origin, unit_z, unit_x, 2, 0)
- m._midline = Twirler(-unit_z, unit_z, unit_y, 1, 0)
- m._beziers = [ self._bezier(u) for u in np.linspace(0, 1, n_u) ]
- def _bezier(u):
+ def __init__(m, n_u): # ix_u will be in [0, n_u>
+ m.edge = Twirler(origin, unit_z, unit_x, 2, 0)
+ m.midline = Twirler(-unit_z, unit_z, unit_y, 1, 0)
+ m._beziers = [ m._bezier(u) for u in np.linspace(0, 1, n_u) ]
+ def _bezier(m,u):
theta = u * tau
cp = [None] * 4
- cp[0] = m._edge .point(theta)
- cp[1] = cp[0] + 0.5 * m._edge .dirn (theta)
- cp[3] = m._midline.point(theta*2)
- cp[2] = cp[3] + 0.5 * m._midline.dirn (theta*2)
- return BezierSegmentcp)
-
+ cp[0] = m.edge .point(theta)
+ cp[1] = cp[0] + 0.5 * m.edge .dirn (theta)
+ cp[3] = m.midline.point(theta*2)
+ cp[2] = cp[3] + 0.5 * m.midline.dirn (theta*2)
+ return BezierSegment(cp)
+ def point(m, ix_u, t):
+ return m._beziers[ix_u].point_at_t(t)