chiark / gitweb /
curveopt: fix handling of empty lines from findcurve
[moebius3.git] / genscad
1 #!/usr/bin/python3
2
3 from __future__ import print_function
4
5 import signal
6 signal.signal(signal.SIGINT, signal.SIG_DFL)
7
8 from moebius import *
9 from scad import *
10
11 nomsize = 30;
12 thick = 2.000;
13
14 sliceat = 1.675;
15
16 nv = 80
17 nw = 80
18
19 m = Moebius(nv, nw)
20
21 relthick = thick/(nomsize*2)
22
23 def make_moebius(objname):
24   so = ScadObject()
25   for v in range(0, nv):
26     for w in range(0, nw):
27       so.quad([ m.point_offset(v+a, w+b,  relthick)
28                 for a in (0, 1)
29                 for b in (0, 1) ])
30       so.rquad([ m.point_offset(v+a, w+b, -relthick)
31                  for a in (1, 0)
32                  for b in (1, 0) ])
33     for q, w in ((so.quad, 0), (so.rquad, nw)):
34       q([ m.point_offset(v+a, w,  b*relthick)
35           for a in (0, 1)
36           for b in (-1, +1) ])
37   so.writeout(objname, nomsize)
38
39 def make_pinlocations():
40   bests = [ None, None ] # bests[ y>=0 ] = (locn, normal)
41
42   def goodness(info):
43     # we find the one with biggest Z (actually, the least -ve)
44     return (
45       0 * np.linalg.norm(info[0][0:2])
46       -abs(info[1][2])
47     )
48     return abs(info[1][1])
49
50   for v in range(0, nv):
51     for w in range(0, nw):
52       core_quad = [ m.point(v+a, w+b)
53                     for a in (1, 0)
54                     for b in (1, 0) ]
55       for p,q in [ (core_quad[i], core_quad[(i+1) % 4])
56                    for i in range(0,4) ]:
57         normal = (m.point_offset(v,  w,   0.5) - core_quad[0] +
58                   m.point_offset(v+1,w+1, 0.5) - core_quad[3]);
59         if normal[2] > 0: # inwards, make outwards
60           normal = -normal
61
62         #print(repr((p,q)), file=sys.stderr)
63         if (p[2] > -sliceat) == (q[2] > -sliceat): continue
64
65         lincomb = (-sliceat - p[2]) / (q[2] - p[2])
66         here = p * (1-lincomb) + q * lincomb;
67         best_key = here[1] >= 0
68         prospective = (here,normal)
69         if (bests[best_key] is None or
70             goodness(prospective) > goodness(bests[best_key])):
71           bests[best_key] = prospective
72   def print_best_list(name, l):
73     print('moebius_pin_%s=[' % name)
74     for i in l: print(repr(list(i)),',')
75     print('];')
76   def print_bests(name, info_index):
77     print_best_list(name, [b[info_index] for b in bests])
78   print_bests('locns', 0)
79   print_bests('normals', 1)
80   upwardses = []
81   alongs = []
82   matrices = []
83   for b in bests:
84     along = unit_v(np.cross(b[1], unit_z))
85     upwards = np.cross(b[1], along)
86     matrix = [ along,
87                -upwards,
88                -b[1] ]
89     #print('initial', matrix, file=sys.stderr)
90     matrix = np.concatenate((matrix, [[0,0,0]]))
91     #print('concatd', matrix, file=sys.stderr)
92     matrix = np.array(matrix).T
93     #print('transposed', matrix, file=sys.stderr)
94     matrix = np.concatenate((matrix, [[0,0,0,1]]))
95     #print('concat2', matrix, file=sys.stderr)
96     matrix = [ list(row) for row in matrix ]
97     #print('listed', matrix, file=sys.stderr)
98     alongs   .append(along)
99     upwardses.append(upwards)
100     matrices. append(matrix)
101   print_best_list('upwardses',upwardses)
102   print_best_list('alongs',   alongs)
103   print_best_list('matrix',   matrices)
104
105 make_moebius('MoebiusCore')
106 make_pinlocations()
107 print('moebiuscore_nomsize=%s;' % repr(nomsize))
108 print('moebiuscore_sliceat=%s;' % repr(sliceat))