chiark / gitweb /
use DoubleCubicBezier
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 5 Nov 2017 15:33:13 +0000 (15:33 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 5 Nov 2017 15:33:13 +0000 (15:33 +0000)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
moebius.py

index d9888d2cea0a896b511dd417ab9d898e73120db0..dea2e125dd3ef0552a10bf6d006f5088c3f32a7d 100644 (file)
@@ -15,6 +15,29 @@ unit_x = np.array((1,0,0))
 unit_y = np.array((0,1,0))
 unit_z = np.array((0,0,1))
 
+class DoubleCubicBezier():
+  def __init__(db, cp):
+    single = BezierSegment(cp)
+    midpoint = np.array(single.point_at_t(0.5))
+    mid_dirn = single.point_at_t(0.5 + 0.001) - midpoint
+    mid_dirn /= np.linalg.norm(mid_dirn)
+    ocp_factor = 0.5
+    mid_scale = ocp_factor * 0.5 * (np.linalg.norm(cp[1] - cp[0]) +
+                                    np.linalg.norm(cp[3] - cp[2]))
+    db.b0 = BezierSegment([ cp[0],
+                            cp[1] * ocp_factor + cp[0] * (1-ocp_factor),
+                            midpoint - mid_dirn * mid_scale,
+                            midpoint ])
+    db.b1 = BezierSegment([ midpoint,
+                            midpoint + mid_dirn * mid_scale,
+                            cp[2] * ocp_factor + cp[3] * (1-ocp_factor),
+                            cp[3] ])
+  def point_at_t(db, t):
+    if t < 0.5:
+      return db.b0.point_at_t(t*2)
+    else:
+      return db.b1.point_at_t(t*2 - 1)
+
 class ParametricCircle:
   def __init__(pc, c, r0, r1):
     ''' circle centred on c
@@ -76,7 +99,7 @@ class MoebiusHalf:
     #      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)
+    return DoubleCubicBezier(cp)
   def point(m, iu, t):
     '''
     0 <= iu <= nu     meaning 0 <= u <= 1