def setup_xy_fresnel(self): k0, k1 = self.k0, self.k1 if k1 == 0: k1 = 1e-6 # hack if k1 != 0: sqrk1 = sqrt(2 * abs(k1)) t0 = (k0 - .5 * k1) / sqrk1 t1 = (k0 + .5 * k1) / sqrk1 (y0, x0) = cornu.eval_cornu(t0) (y1, x1) = cornu.eval_cornu(t1) chord_th = atan2(y1 - y0, x1 - x0) chord = hypot(y1 - y0, x1 - x0) scale = self.chord / chord if k1 >= 0: th = self.chth - chord_th self.mxx = scale * cos(th) self.myx = scale * sin(th) self.mxy = -self.myx self.myy = self.mxx else: th = self.chth + chord_th self.mxx = scale * cos(th) self.myx = scale * sin(th) self.mxy = self.myx self.myy = -self.mxx # rotate -chord_th, flip top/bottom, rotate self.chth self.x0 = self.z0[0] - (self.mxx * x0 + self.mxy * y0) self.y0 = self.z0[1] - (self.myx * x0 + self.myy * y0)
def cornu_to_cubic(t0, t1): def th_fn(s): return (s + t0)**2 y0, x0 = cornu.eval_cornu(t0) y1, x1 = cornu.eval_cornu(t1) bz, score = fit_cubic((x0, y0), (x1, y1), t1 - t0, th_fn, 0) return bz, score
def cornu_to_cubic(t0, t1): def th_fn(s): return (s + t0) ** 2 y0, x0 = cornu.eval_cornu(t0) y1, x1 = cornu.eval_cornu(t1) bz, score = fit_cubic((x0, y0), (x1, y1), t1 - t0, th_fn, 0) return bz, score
def compute_dth(k0, k1): if k1 < 0: return -compute_dth(k0, -k1) elif k1 == 0: return 0 sqrk1 = sqrt(2 * k1) t0 = (k0 - .5 * k1) / sqrk1 t1 = (k0 + .5 * k1) / sqrk1 (y0, x0) = cornu.eval_cornu(t0) (y1, x1) = cornu.eval_cornu(t1) chord_th = atan2(y1 - y0, x1 - x0) return mod_2pi(t1 * t1 - chord_th) - mod_2pi(chord_th - t0 * t0)
def compute_chord(k0, k1): if k1 == 0: if k0 == 0: return 1 else: return sin(k0 * .5) / (k0 * .5) sqrk1 = sqrt(2 * abs(k1)) t0 = (k0 - .5 * k1) / sqrk1 t1 = (k0 + .5 * k1) / sqrk1 (y0, x0) = cornu.eval_cornu(t0) (y1, x1) = cornu.eval_cornu(t1) return hypot(y1 - y0, x1 - x0) / abs(t1 - t0)
def plot_errors_2d(t0, t1, as_ppm): xs = 1024 ys = 1024 if as_ppm: print 'P6' print xs, ys print 255 def th_fn(s): return (s + t0)**2 y0, x0 = cornu.eval_cornu(t0) y1, x1 = cornu.eval_cornu(t1) z0 = (x0, y0) z1 = (x1, y1) chord = hypot(y1 - y0, x1 - x0) arclen = t1 - t0 th0 = th_fn(0) th1 = th_fn(arclen) cth0, sth0 = cos(th0), sin(th0) cth1, sth1 = -cos(th1), -sin(th1) for y in range(ys): b = .8 * chord * (ys - y - 1) / ys for x in range(xs): a = .8 * chord * x / xs bz = [ z0, (z0[0] + cth0 * a, z0[1] + sth0 * a), (z1[0] + cth1 * b, z1[1] + sth1 * b), z1 ] s_bz = bz_arclength(bz, 10) def th_fn_scaled(s): return (s * arclen / s_bz + t0)**2 score = measure_bz_rk4(bz, arclen, th_fn_scaled, 10) if as_ppm: ls = -log(score) color_th = ls darkstep = 0 if s_bz > arclen: g0 = 128 - darkstep else: g0 = 128 + darkstep sc = 127 - darkstep rr = g0 + sc * cos(color_th) gg = g0 + sc * cos(color_th + 2 * pi / 3) bb = g0 + sc * cos(color_th - 2 * pi / 3) sys.stdout.write(struct.pack('3B', rr, gg, bb)) else: print a, b, score if not as_ppm: print
def plot_errors_2d(t0, t1, as_ppm): xs = 1024 ys = 1024 if as_ppm: print "P6" print xs, ys print 255 def th_fn(s): return (s + t0) ** 2 y0, x0 = cornu.eval_cornu(t0) y1, x1 = cornu.eval_cornu(t1) z0 = (x0, y0) z1 = (x1, y1) chord = hypot(y1 - y0, x1 - x0) arclen = t1 - t0 th0 = th_fn(0) th1 = th_fn(arclen) cth0, sth0 = cos(th0), sin(th0) cth1, sth1 = -cos(th1), -sin(th1) for y in range(ys): b = 0.8 * chord * (ys - y - 1) / ys for x in range(xs): a = 0.8 * chord * x / xs bz = [z0, (z0[0] + cth0 * a, z0[1] + sth0 * a), (z1[0] + cth1 * b, z1[1] + sth1 * b), z1] s_bz = bz_arclength(bz, 10) def th_fn_scaled(s): return (s * arclen / s_bz + t0) ** 2 score = measure_bz_rk4(bz, arclen, th_fn_scaled, 10) if as_ppm: ls = -log(score) color_th = ls darkstep = 0 if s_bz > arclen: g0 = 128 - darkstep else: g0 = 128 + darkstep sc = 127 - darkstep rr = g0 + sc * cos(color_th) gg = g0 + sc * cos(color_th + 2 * pi / 3) bb = g0 + sc * cos(color_th - 2 * pi / 3) sys.stdout.write(struct.pack("3B", rr, gg, bb)) else: print a, b, score if not as_ppm: print
def plot_arclen(t0, t1): def th_fn(s): return (s + t0)**2 y0, x0 = cornu.eval_cornu(t0) y1, x1 = cornu.eval_cornu(t1) z0 = (x0, y0) z1 = (x1, y1) chord = hypot(y1 - y0, x1 - x0) arclen = t1 - t0 th0 = th_fn(0) th1 = th_fn(arclen) for i in range(101): aab = i * .01 bz, a, b = fit_cubic_arclen_forplot(z0, z1, arclen, th0, th1, aab) print a, b
def plot_arclen(t0, t1): def th_fn(s): return (s + t0) ** 2 y0, x0 = cornu.eval_cornu(t0) y1, x1 = cornu.eval_cornu(t1) z0 = (x0, y0) z1 = (x1, y1) chord = hypot(y1 - y0, x1 - x0) arclen = t1 - t0 th0 = th_fn(0) th1 = th_fn(arclen) for i in range(101): aab = i * 0.01 bz, a, b = fit_cubic_arclen_forplot(z0, z1, arclen, th0, th1, aab) print a, b
def xy(self, s): # using fresnel integrals; polynomial approx might be better u = s / self.arclen - 0.5 k0, k1 = self.k0, self.k1 if k1 == 0: k1 = 1e-6 # hack if k1 != 0: sqrk1 = sqrt(2 * abs(k1)) t = (k0 + u * k1) / sqrk1 (y, x) = cornu.eval_cornu(t) return [self.x0 + self.mxx * x + self.mxy * y, self.y0 + self.myx * x + self.myy * y]
def cornu_to_cubic(t0, t1, figno): if figno == 1: aabmin = 0 aabmax = 0.4 elif figno == 2: aabmin = 0.5 aabmax = 1. else: aabmin = 0 aabmax = 1. fast = 0 if figno == 3: fast = 1 elif figno == 4: fast = 2 def th_fn(s): return (s + t0) ** 2 y0, x0 = cornu.eval_cornu(t0) y1, x1 = cornu.eval_cornu(t1) bz, score = fit_cubic((x0, y0), (x1, y1), t1 - t0, th_fn, fast, aabmin, aabmax) return bz, score
def cornu_to_cubic(t0, t1, figno): if figno == 1: aabmin = 0 aabmax = 0.4 elif figno == 2: aabmin = 0.5 aabmax = 1. else: aabmin = 0 aabmax = 1. fast = 0 if figno == 3: fast = 1 elif figno == 4: fast = 2 def th_fn(s): return (s + t0)**2 y0, x0 = cornu.eval_cornu(t0) y1, x1 = cornu.eval_cornu(t1) bz, score = fit_cubic((x0, y0), (x1, y1), t1 - t0, th_fn, fast, aabmin, aabmax) return bz, score