chiark / gitweb /
ab27e4458cc98e5fa41b4314229c58e0e07b99a2
[moebius3.git] / curveopt.py
1
2 from __future__ import print_function
3
4 import numpy as np
5 from numpy import cos, sin
6
7 import six
8 import sys
9 import subprocess
10 import math
11
12 from moedebug import *
13 from moenp import *
14 from moebez import *
15
16 from math import atan2, atan, sqrt
17
18 import symbolic
19
20 class OptimisedCurve():
21   counter = 0
22
23   def _dbg(oc, s):
24     dbg('OC#%04d %s' % (oc._counter, s))
25
26   def __init__(oc, cp, nt):
27     oc._counter = OptimisedCurve.counter
28     OptimisedCurve.counter += 1
29     oc._dbg('cp= ' + ' '.join(map(vec2dbg, cp)))
30
31     db = DiscreteBezier(cp, nt, bezier_constructor=BezierSegment)
32
33     fc_input = map(db.point_at_it, range(0, nt+1))
34     oc._dbg(repr(fc_input))
35
36     for end in (False,True):
37       ei = nt if end else 0
38       fi = nt-1 if end else 1
39       cp0i = 3 if end else 0
40       cp1i = 2 if end else 1
41       e = np.array(cp[cp0i])
42       ef_dirn = unit_v(cp[cp1i] - cp[cp0i])
43       ef_len = np.linalg.norm(np.array(fc_input[fi]) - np.array(fc_input[ei]))
44       f = e + ef_dirn * ef_len
45       oc._dbg(repr((end, e,f, ef_dirn, ef_len)))
46       fc_input[ei] = e
47       fc_input[fi] = f
48
49     oc._dbg(repr(fc_input))
50
51     findcurve_epsilon = 0.0001
52
53     cl = ['./findcurve', '%d' % (nt+1), '%.18g' % findcurve_epsilon]
54     oc._dbg('STARTING FINDCURVE %s' % cl)
55     subproc = subprocess.Popen(
56       cl,
57       bufsize=1,
58       stdin=subprocess.PIPE,
59       stdout=subprocess.PIPE,
60       stderr=None,
61       close_fds=False,
62       # restore_signals=True, // want python2 compat, nnng
63       universal_newlines=True,
64     )
65
66     oc._dbg('RUNNING FINDCURVE')
67
68     fc_input = np.hstack(fc_input)
69     s = ' '.join(map(str, fc_input))
70
71     oc._dbg(('>> %s' % s))
72
73     print(s, file=subproc.stdin)
74     subproc.stdin.flush()
75
76     oc.subproc = subproc
77     oc.nt = nt
78
79     #oc._await_subproc()
80
81   def _await_subproc(oc):
82     subproc = oc.subproc
83     if subproc is None: return
84
85     oc._dbg('(awaiting)')
86     commentary = ''
87
88     while True:
89       l = subproc.stdout.readline()
90       if not l:
91         oc._dbg('findcurve EOF')
92         vdbg().crashing('findcurve EOF')
93       l = l.rstrip()
94       oc._dbg('<< ' + l)
95       if not l.startswith('['):
96         commentary += ' '
97         commentary += l
98         continue
99
100       l = eval(l)
101       if not l: break
102
103       oc._dbg('[%s] %s' % (l, commentary))
104       commentary = ''
105
106       findcurve_result = l
107
108     subproc.stdin.close()
109     subproc.wait()
110     assert(subproc.returncode == 0)
111     oc.subproc = None
112
113     oc._result = np.reshape(findcurve_result, (-1,3), 'C')
114     oc._dbg(repr(oc._result))
115
116     #vdbg().curve( oc.point_at_t )
117
118   def point_at_it(oc, it):
119     oc._await_subproc()
120     oc._dbg(repr((it,)))
121     return oc._result[it]
122
123   def point_at_t(oc, t):
124     itd = t * oc.nt
125     it0 = int(math.floor(itd))
126     it1 = int(math.ceil(itd))
127     p0 = oc.point_at_it(it0)
128     p1 = oc.point_at_it(it1)
129     return p0 + (p1-p0) * (itd-it0)
130