-#!/usr/bin/python
+#!/usr/bin/python3
from __future__ import print_function
signal.signal(signal.SIGINT, signal.SIG_DFL)
from moebius import *
+from scad import *
-nomsize = 20
-thick = 2.5
+nomsize = 30;
+thick = 2.000;
-nv = 40
-nw = 40
+sliceat = 1.675;
+
+nv = 80
+nw = 80
m = Moebius(nv, nw)
+relthick = thick/(nomsize*2)
-stl_points = []
-stl_point_indices = {}
-stl_triangles = []
-
-def stl_writeout():
- print('module MoebiusCore(){ scale(%s) polyhedron(points=[' % nomsize)
- for p in stl_points: print(p, ',')
- print('],faces=[')
- for t in stl_triangles: print(repr(t), ',')
- print('],convexity=10); }')
-
-def stl_point(p):
- l = list(p)
- s = repr(l)
- try:
- ix = stl_point_indices[s]
- except KeyError:
- ix = len(stl_points)
- stl_points.append(s)
- stl_point_indices[s] = ix
- return ix
-
-def stl_triangle(a,b,c):
- ''' a b c are clockwise from inside '''
- stl_triangles.append([ stl_point(p) for p in (a,b,c) ])
-
-def stl_quad(cnrs):
- ''' cnrs[0] [1] [3] [2] are clockwise from inside '''
- stl_triangle(cnrs[0], cnrs[1], cnrs[3])
- stl_triangle(cnrs[0], cnrs[3], cnrs[2])
+def make_moebius(objname):
+ so = ScadObject()
+ for v in range(0, nv):
+ for w in range(0, nw):
+ so.quad([ m.point_offset(v+a, w+b, relthick)
+ for a in (0, 1)
+ for b in (0, 1) ])
+ so.rquad([ m.point_offset(v+a, w+b, -relthick)
+ for a in (1, 0)
+ for b in (1, 0) ])
+ for q, w in ((so.quad, 0), (so.rquad, nw)):
+ q([ m.point_offset(v+a, w, b*relthick)
+ for a in (0, 1)
+ for b in (-1, +1) ])
+ so.writeout(objname, nomsize)
-relthick = thick/(nomsize*2)
+def make_pinlocations():
+ bests = [ None, None ] # bests[ y>=0 ] = (locn, normal)
+
+ def goodness(info):
+ # we find the one with biggest Z (actually, the least -ve)
+ return (
+ 0 * np.linalg.norm(info[0][0:2])
+ -abs(info[1][2])
+ )
+ return abs(info[1][1])
+
+ for v in range(0, nv):
+ for w in range(0, nw):
+ core_quad = [ m.point(v+a, w+b)
+ for a in (1, 0)
+ for b in (1, 0) ]
+ for p,q in [ (core_quad[i], core_quad[(i+1) % 4])
+ for i in range(0,4) ]:
+ normal = (m.point_offset(v, w, 0.5) - core_quad[0] +
+ m.point_offset(v+1,w+1, 0.5) - core_quad[3]);
+ if normal[2] > 0: # inwards, make outwards
+ normal = -normal
+
+ #print(repr((p,q)), file=sys.stderr)
+ if (p[2] > -sliceat) == (q[2] > -sliceat): continue
-for v in range(0, nv):
- for w in range(0, nw):
- stl_quad([ m.point_offset(v+a, w+b, relthick)
- for a in (0, 1)
- for b in (0, 1) ])
- stl_quad([ m.point_offset(v+a, w+b, -relthick)
- for a in (1, 0)
- for b in (1, 0) ])
+ lincomb = (-sliceat - p[2]) / (q[2] - p[2])
+ here = p * (1-lincomb) + q * lincomb;
+ best_key = here[1] >= 0
+ prospective = (here,normal)
+ if (bests[best_key] is None or
+ goodness(prospective) > goodness(bests[best_key])):
+ bests[best_key] = prospective
+ def print_best_list(name, l):
+ print('moebius_pin_%s=[' % name)
+ for i in l: print(repr(list(i)),',')
+ print('];')
+ def print_bests(name, info_index):
+ print_best_list(name, [b[info_index] for b in bests])
+ print_bests('locns', 0)
+ print_bests('normals', 1)
+ upwardses = []
+ alongs = []
+ matrices = []
+ for b in bests:
+ along = unit_v(np.cross(b[1], unit_z))
+ upwards = np.cross(b[1], along)
+ matrix = [ along,
+ -upwards,
+ -b[1] ]
+ #print('initial', matrix, file=sys.stderr)
+ matrix = np.concatenate((matrix, [[0,0,0]]))
+ #print('concatd', matrix, file=sys.stderr)
+ matrix = np.array(matrix).T
+ #print('transposed', matrix, file=sys.stderr)
+ matrix = np.concatenate((matrix, [[0,0,0,1]]))
+ #print('concat2', matrix, file=sys.stderr)
+ matrix = [ list(row) for row in matrix ]
+ #print('listed', matrix, file=sys.stderr)
+ alongs .append(along)
+ upwardses.append(upwards)
+ matrices. append(matrix)
+ print_best_list('upwardses',upwardses)
+ print_best_list('alongs', alongs)
+ print_best_list('matrix', matrices)
-stl_writeout()
+make_moebius('MoebiusCore')
+make_pinlocations()
+print('moebiuscore_nomsize=%s;' % repr(nomsize))
+print('moebiuscore_sliceat=%s;' % repr(sliceat))