def get_tikz_bezier_2d(bpath): lines = [] # draw everything except for the last point of the last chunk for b in bpath.bchunks: pts = [tikz.point_to_tikz(p) for p in b.get_points()[:-1]] lines.append('%s .. controls %s and %s ..' % tuple(pts)) # draw the last point of the last chunk lines.append('%s;' % tikz.point_to_tikz(bpath.bchunks[-1].p3)) return '\n'.join(lines)
def get_tikz_bezier(bpath): lines = [] # draw everything except for the last point of the last chunk for b in bpath.bchunks: pts = [tikz.point_to_tikz(p[1:]) for p in b.get_points()[:-1]] lines.append("%s .. controls %s and %s .." % tuple(pts)) # draw the last point of the last chunk lines.append("%s;" % tikz.point_to_tikz(bpath.bchunks[-1].p3[1:])) return "\n".join(lines)
def get_tikz_body(fs): out = StringIO() # define user variables plot_width = fs.plot_width plot_height = fs.plot_height timescale = fs.t_max # create the function objects f_a = JC69.IdentitySlopeInformation(fs.a_mu, fs.a_N) f_b = JC69.IdentitySlopeInformation(fs.b_mu, fs.b_N) # Define some times for evaluation of the curve. times = [timescale*2**-i for i in range(10)] # define some more intermediate values ymax = max(f_a(min(times)), f_b(min(times))) * 1.2 plotscale = np.array((plot_width / timescale, plot_height / ymax)) origin = (0, 0) # draw the boundary of the plot print >> out, r'\draw[color=gray] %s %s {%s} %s;' % ( tikz.point_to_tikz(origin), 'edge node[color=black,below]', '$t$', tikz.point_to_tikz((plot_width, 0))) print >> out, r'\draw[color=gray] ' + get_segment( origin, (0, plot_height)) # draw the bezier curves hitting the right knots for f in (f_a, f_b): bchunks = [] for a, b in iterutils.pairwise(sorted(times)): pta = np.array((a, f(a))) ptb = np.array((b, f(b))) dta = np.array((1, f.deriv(a))) dtb = np.array((1, f.deriv(b))) bchunk = bezier.create_bchunk_hermite( a, b, pta * plotscale, ptb * plotscale, dta * plotscale, dtb * plotscale) bchunks.append(bchunk) print >> out, r'\draw[color=gray] ' + get_tikz_bezier(bchunks) # draw filled black dots at some intersections dot_points = [origin] dot_points.append((0, f_a(0))) dot_points.append((0, f_b(0))) for p in dot_points: print >> out, r'\fill[color=black,inner sep=0pt]', print >> out, tikz.point_to_tikz(np.array(p) * plotscale), print >> out, 'circle (1pt);' # draw some text annotations pt_txt_pairs = [ ((0, 0), '0'), ] for i, (pt, txt) in enumerate(pt_txt_pairs): print >> out, r'\node[anchor=east] (%s) at %s {%s};' % ( 'ylabel%d' % i, tikz.point_to_tikz(pt), txt) # return out.getvalue().rstrip()
def get_tikz_pane(sample): """ At this point the tikz styles main-style and axis-style have been defined. @param sample: an interlacesample.Sample object @return: a tikz text string """ min_gridsize = 0.001 strokes = get_scene(sample) # rotate every control point in every bchunk in each curve for stroke in strokes: stroke.transform(rotate_to_view) # get the intersection times time_lists = bezintersect.get_intersection_times(strokes, project_to_2d, min_gridsize, 3 * min_gridsize) # shatter the strokes, tracking the times of interest and the styles shattered_strokes = [] for time_list, stroke in zip(time_lists, strokes): shattered_strokes.extend(stroke.shatter(time_list)) depth_stroke_pairs = [] for stroke in shattered_strokes: x, y, z = stroke.evaluate(stroke.characteristic_time) depth_stroke_pairs.append((x, stroke)) ordered_strokes = [s for d, s in sorted(depth_stroke_pairs)] # get the patches, tracking the times of interest and the styles patches = [] for time_list, stroke in zip(time_lists, strokes): for patch in stroke.get_patches(time_list): if stroke.style == STYLE_MAIN: patch.style = STYLE_MAIN_PATCH elif stroke.style == STYLE_AXIS: patch.style = STYLE_AXIS_PATCH patches.append(patch) depth_patch_pairs = [] for patch in patches: x, y, z = patch.evaluate(patch.characteristic_time) depth_patch_pairs.append((x, patch)) ordered_patches = [s for d, s in sorted(depth_patch_pairs)] # draw the depth sorted strokes and patches arr = [] for stroke in ordered_strokes + ordered_patches: # draw a linear curve or a bezier curve if len(stroke.bchunks) == 1 and stroke.bchunks[0].is_almost_linear(): p0 = stroke.bchunks[0].p0 p3 = stroke.bchunks[0].p3 line = "\\draw[%s] %s -- %s;" % ( stroke.style, tikz.point_to_tikz(stroke.bchunks[0].p0[1:]), tikz.point_to_tikz(stroke.bchunks[0].p3[1:]), ) arr.append(line) else: line = "\\draw[%s]" % stroke.style arr.append(line) arr.append(get_tikz_bezier(stroke)) return "\n".join(arr)
def get_tikz_pane(sample): """ At this point the tikz styles main-style and axis-style have been defined. @param sample: an interlacesample.Sample object @return: a tikz text string """ min_gridsize = 0.001 strokes = get_scene(sample) # rotate every control point in every bchunk in each curve for stroke in strokes: stroke.transform(rotate_to_view) # get the intersection times time_lists = bezintersect.get_intersection_times(strokes, project_to_2d, min_gridsize, 3 * min_gridsize) # shatter the strokes, tracking the times of interest and the styles shattered_strokes = [] for time_list, stroke in zip(time_lists, strokes): shattered_strokes.extend(stroke.shatter(time_list)) depth_stroke_pairs = [] for stroke in shattered_strokes: x, y, z = stroke.evaluate(stroke.characteristic_time) depth_stroke_pairs.append((x, stroke)) ordered_strokes = [s for d, s in sorted(depth_stroke_pairs)] # get the patches, tracking the times of interest and the styles patches = [] for time_list, stroke in zip(time_lists, strokes): for patch in stroke.get_patches(time_list): if stroke.style == STYLE_MAIN: patch.style = STYLE_MAIN_PATCH elif stroke.style == STYLE_AXIS: patch.style = STYLE_AXIS_PATCH patches.append(patch) depth_patch_pairs = [] for patch in patches: x, y, z = patch.evaluate(patch.characteristic_time) depth_patch_pairs.append((x, patch)) ordered_patches = [s for d, s in sorted(depth_patch_pairs)] # draw the depth sorted strokes and patches arr = [] for stroke in ordered_strokes + ordered_patches: # draw a linear curve or a bezier curve if len(stroke.bchunks) == 1 and stroke.bchunks[0].is_almost_linear(): p0 = stroke.bchunks[0].p0 p3 = stroke.bchunks[0].p3 line = '\\draw[%s] %s -- %s;' % ( stroke.style, tikz.point_to_tikz(stroke.bchunks[0].p0[1:]), tikz.point_to_tikz(stroke.bchunks[0].p3[1:])) arr.append(line) else: line = '\\draw[%s]' % stroke.style arr.append(line) arr.append(get_tikz_bezier(stroke)) return '\n'.join(arr)
def get_tikz_bezier(bchunks): """ @param bchunks: a sequence of 2d bezier chunks @return: multiline bezier text """ lines = [] # draw everything except for the last point of the last chunk for b in bchunks: pts = [tikz.point_to_tikz(p) for p in b.get_points()[:-1]] lines.append('%s .. controls %s and %s ..' % tuple(pts)) # draw the last point of the last chunk lines.append('%s;' % tikz.point_to_tikz(bchunks[-1].p3)) return '\n'.join(lines)
def get_tikz_body(fs): out = StringIO() # define user variables plot_width = fs.plot_width plot_height = fs.plot_height timescale = fs.t_max # create the function objects f_a = JC69.IdentitySlopeInformation(fs.a_mu, fs.a_N) f_b = JC69.IdentitySlopeInformation(fs.b_mu, fs.b_N) # Define some times for evaluation of the curve. times = [timescale * 2**-i for i in range(10)] # define some more intermediate values ymax = max(f_a(min(times)), f_b(min(times))) * 1.2 plotscale = np.array((plot_width / timescale, plot_height / ymax)) origin = (0, 0) # draw the boundary of the plot print >> out, r'\draw[color=gray] %s %s {%s} %s;' % ( tikz.point_to_tikz(origin), 'edge node[color=black,below]', '$t$', tikz.point_to_tikz((plot_width, 0))) print >> out, r'\draw[color=gray] ' + get_segment(origin, (0, plot_height)) # draw the bezier curves hitting the right knots for f in (f_a, f_b): bchunks = [] for a, b in iterutils.pairwise(sorted(times)): pta = np.array((a, f(a))) ptb = np.array((b, f(b))) dta = np.array((1, f.deriv(a))) dtb = np.array((1, f.deriv(b))) bchunk = bezier.create_bchunk_hermite(a, b, pta * plotscale, ptb * plotscale, dta * plotscale, dtb * plotscale) bchunks.append(bchunk) print >> out, r'\draw[color=gray] ' + get_tikz_bezier(bchunks) # draw filled black dots at some intersections dot_points = [origin] dot_points.append((0, f_a(0))) dot_points.append((0, f_b(0))) for p in dot_points: print >> out, r'\fill[color=black,inner sep=0pt]', print >> out, tikz.point_to_tikz(np.array(p) * plotscale), print >> out, 'circle (1pt);' # draw some text annotations pt_txt_pairs = [ ((0, 0), '0'), ] for i, (pt, txt) in enumerate(pt_txt_pairs): print >> out, r'\node[anchor=east] (%s) at %s {%s};' % ( 'ylabel%d' % i, tikz.point_to_tikz(pt), txt) # return out.getvalue().rstrip()
def get_tikz_lines(fs): """ @param fs: user input @return: a sequence of tikz lines """ # define characteristics for all circles radius = 1 nsegments = 5 # define the first circle center = np.array([1.0, 1.0, 1.0]) axis = 0 owned_bchunks = bezier.gen_bchunks_ortho_circle(center, radius, axis, pcurve.OwnedBezierChunk) first_curve = pcurve.BezierPath(owned_bchunks) # define the second circle center = np.array([1.0, 1.0, 0.0]) axis = 1 owned_bchunks = bezier.gen_bchunks_ortho_circle(center, radius, axis, pcurve.OwnedBezierChunk) second_curve = pcurve.BezierPath(owned_bchunks) # rotate every control point in every bchunk in each curve for curve in (first_curve, second_curve): for b in curve.bchunks: b.p0 = rotate_to_view(b.p0) b.p1 = rotate_to_view(b.p1) b.p2 = rotate_to_view(b.p2) b.p3 = rotate_to_view(b.p3) # define some new flat curves whose bchunks reference the deep curves deep_curves = (first_curve, second_curve) flat_curves = [] for deep_curve in deep_curves: flat_bchunks = [] for deep_b in deep_curve.bchunks: flat_b = pcurve.OwnedBezierChunk( deep_b.start_time, deep_b.stop_time, deep_b.p0[1:], deep_b.p1[1:], deep_b.p2[1:], deep_b.p3[1:] ) flat_b.parent_ref = id(deep_curve) flat_bchunks.append(flat_b) flat_curves.append(pcurve.BezierPath(flat_bchunks)) # break up the piecewise curves for z-ordering child_parent_curve_pairs = list(pcurve.decompose_scene(deep_curves, flat_curves, fs.min_gridsize)) # extract the child curves child_curves = zip(*child_parent_curve_pairs)[0] # sort the child curves according to depth order # TODO chain together the bezier curve into a single drawing command depth_curve_pairs = [] for curve in child_curves: x, y, z = rotate_to_view(curve.evaluate(curve.characteristic_time)) depth_curve_pairs.append((x, curve)) lines = [] for x, curve in sorted(depth_curve_pairs): colors = ["yellow", "orange", "red", "green", "blue", "purple"] c = random.choice(colors) for b in curve.bchunks: controls = (b.p0, b.p1, b.p2, b.p3) points = [tikz.point_to_tikz(p[1:]) for p in controls] args = tuple([c] + points) line = "\\draw[draw=white,double=%s,thick] %s .. controls %s and %s .. %s;" % args lines.append(line) # line = '\\draw %s -- %s -- %s -- %s;' % points # lines.append(line) return lines
def get_tikz_body(fs): out = StringIO() # init the processes from user data fast_process = Process(fs.plot_width, fs.plot_height, fs.t_max, fs.p_width, fs.fast_mu, fs.fast_low, fs.fast_high) slow_process = Process(fs.plot_width, fs.plot_height, fs.t_max, fs.p_width, fs.slow_mu, fs.slow_low, fs.slow_high) # predefined variables origin = (0, 0) # define user variables plot_width = fs.plot_width plot_height = fs.plot_height timescale = fs.t_max plotscale = np.array((plot_width, plot_height)) # draw the beams print >> out, slow_process.draw_high_beam('blue!60') print >> out, slow_process.draw_low_beam('blue!60') print >> out, fast_process.draw_high_beam('red!60') print >> out, fast_process.draw_low_beam('red!60') # draw the boundary of the plot print >> out, r'\draw[color=gray] ' + get_segment(origin, (plot_width, 0)) print >> out, r'\draw[color=gray] ' + get_segment(origin, (0, plot_height)) print >> out, r'\draw[color=gray] ' + get_segment( (0, plot_height), (plot_width, plot_height)) print >> out, r'\draw[dotted,color=gray] ' + get_segment( (0, 0.25 * plot_height), (plot_width, 0.25 * plot_height)) # draw the bezier curves hitting the right knots for p in (slow_process, fast_process): print >> out, p.draw_curve() # draw filled black dots at some intersections dot_points = [ origin, (0, plot_height), (0, 0.25 * plot_height), ] for dot_point in dot_points: print >> out, r'\fill[color=black,inner sep=0pt]', print >> out, tikz.point_to_tikz(dot_point), print >> out, 'circle (1pt);' # draw some text annotations pt_txt_pairs = [((0, 0), '0'), ((0, 0.25 * plot_height), r'$\frac{1}{4}$'), ((0, 1.0 * plot_height), '1')] for i, (pt, txt) in enumerate(pt_txt_pairs): print >> out, r'\node[anchor=east] (%s) at %s {%s};' % ( 'ylabel%d' % i, tikz.point_to_tikz(pt), txt) # return out.getvalue().rstrip()
def get_tikz_lines(fs): """ @param fs: user input @return: a sequence of tikz lines """ lines = [] min_gridsize = 0.001 half_axis_radii = ( fs.x_rad_pos, fs.x_rad_neg, fs.y_rad_pos, fs.y_rad_neg, fs.z_rad_pos, fs.z_rad_neg) strokes = get_scene( fs.root_a, fs.root_b, fs.root_c, fs.initial_t, fs.final_t, fs.circle_radius, half_axis_radii) # rotate every control point in every bchunk in each curve for stroke in strokes: stroke.transform(rotate_to_view) # get the intersection times time_lists = bezintersect.get_intersection_times( strokes, project_to_2d, min_gridsize, 3*min_gridsize) # shatter the strokes, tracking the times of interest and the styles shattered_strokes = [] for time_list, stroke in zip(time_lists, strokes): shattered_strokes.extend(stroke.shatter(time_list)) # sort the strokes according to depth order depth_stroke_pairs = [] for stroke in shattered_strokes: x, y, z = stroke.evaluate(stroke.characteristic_time) depth_stroke_pairs.append((x, stroke)) # draw the curves for x, stroke in sorted(depth_stroke_pairs): # draw a linear curve or a bezier curve c = g_style_colors[stroke.style] if len(stroke.bchunks)==1 and stroke.bchunks[0].is_almost_linear(): p0 = stroke.bchunks[0].p0 p3 = stroke.bchunks[0].p3 line = '\\draw[draw=white,double=%s,thick] %s -- %s;' % ( c, tikz.point_to_tikz(stroke.bchunks[0].p0[1:]), tikz.point_to_tikz(stroke.bchunks[0].p3[1:])) lines.append(line) else: line = '\\draw[draw=white,double=%s,thick]' % c lines.append(line) lines.append(get_tikz_bezier(stroke)) return lines
def get_tikz_lines(fs): """ @param fs: user input @return: a sequence of tikz lines """ # define a straightforward bezier curve p0 = np.array([-1.0, -1.0]) p1 = np.array([-1.0, 1.0]) p2 = np.array([1.0, 1.0]) p3 = np.array([1.0, -1.0]) # define a messier bezier curve q0 = np.array([-2.0, 0.0]) q1 = np.array([1.0, 1.0]) q2 = np.array([-1.0, -1.0]) q3 = np.array([2.0, 0.0]) # plot the bezier curves using tikz arr = [] points = tuple(tikz.point_to_tikz(p) for p in (p0, p1, p2, p3)) arr.append('\\draw %s .. controls %s and %s .. %s;' % points) points = tuple(tikz.point_to_tikz(p) for p in (q0, q1, q2, q3)) arr.append('\\draw %s .. controls %s and %s .. %s;' % points) # a = bezier.BezierChunk() a.p0 = p0 a.p1 = p1 a.p2 = p2 a.p3 = p3 a.start_time = 0.0 a.stop_time = 1.0 a.parent_ref = 10 # b = bezier.BezierChunk() b.p0 = q0 b.p1 = q1 b.p2 = q2 b.p3 = q3 b.start_time = 0.0 b.stop_time = 1.0 b.parent_ref = 11 # find the intersections beziers = pcurve.find_bezier_intersections([a, b], fs.min_gridsize) for b in beziers: points = tuple(tikz.point_to_tikz(p) for p in (b.p0, b.p1, b.p2, b.p3)) arr.append('\\draw[red] %s .. controls %s and %s .. %s;' % points) # return the lines return arr
def get_tikz_lines(fs): """ @param fs: user input @return: a sequence of tikz lines """ lines = [] min_gridsize = 0.001 half_axis_radii = (fs.x_rad_pos, fs.x_rad_neg, fs.y_rad_pos, fs.y_rad_neg, fs.z_rad_pos, fs.z_rad_neg) strokes = get_scene(fs.root_a, fs.root_b, fs.root_c, fs.initial_t, fs.final_t, fs.circle_radius, half_axis_radii) # rotate every control point in every bchunk in each curve for stroke in strokes: stroke.transform(rotate_to_view) # get the intersection times time_lists = bezintersect.get_intersection_times(strokes, project_to_2d, min_gridsize, 3 * min_gridsize) # shatter the strokes, tracking the times of interest and the styles shattered_strokes = [] for time_list, stroke in zip(time_lists, strokes): shattered_strokes.extend(stroke.shatter(time_list)) # sort the strokes according to depth order depth_stroke_pairs = [] for stroke in shattered_strokes: x, y, z = stroke.evaluate(stroke.characteristic_time) depth_stroke_pairs.append((x, stroke)) # draw the curves for x, stroke in sorted(depth_stroke_pairs): # draw a linear curve or a bezier curve c = g_style_colors[stroke.style] if len(stroke.bchunks) == 1 and stroke.bchunks[0].is_almost_linear(): p0 = stroke.bchunks[0].p0 p3 = stroke.bchunks[0].p3 line = '\\draw[draw=white,double=%s,thick] %s -- %s;' % ( c, tikz.point_to_tikz(stroke.bchunks[0].p0[1:]), tikz.point_to_tikz(stroke.bchunks[0].p3[1:])) lines.append(line) else: line = '\\draw[draw=white,double=%s,thick]' % c lines.append(line) lines.append(get_tikz_bezier(stroke)) return lines
def tikz_superposition(t_seq, y_seqs, width, height): """ Return the body of a tikzpicture environment. The input defines k piecewise-linear parametric functions. The domain is a real interval. The kth sequence of y values should have k zero-crossings. The returned drawing has arbitrary horizontal and vertical scale. @param t_seq: sequence of t values @param y_seqs: sequence of y value sequences @param width: a horizontal scaling factor @param height: a vertical scaling factor @return: LaTeX code for a tikzpicture """ # check the form of the input sequences assert_support(t_seq, y_seqs) # Get the y scaling factor. # This is the value by which the observed y values are multiplied # to give a number that is relevant to the tikz coordinate system. ymin = min(min(seq) for seq in y_seqs) ymax = max(max(seq) for seq in y_seqs) yscale = height / float(ymax - ymin) # Get the x scaling factor. xmin = t_seq[0] xmax = t_seq[-1] xscale = width / float(xmax - xmin) # Get the rescaled sequences. t_seq_rescaled = [t * xscale for t in t_seq] y_seqs_rescaled = [[y * yscale for y in seq] for seq in y_seqs] # Start the text array. arr = [] # Plot the horizontal domain segment. pa = tikz.point_to_tikz((t_seq_rescaled[0], 0)) pb = tikz.point_to_tikz((t_seq_rescaled[-1], 0)) arr.append('\\draw %s -- %s;' % (pa, pb)) # Plot the scaled functions. for seq, c in zip(y_seqs_rescaled, color.wolfram): arr.append('\\draw[color=%s]' % c) points = zip(t_seq_rescaled, seq) arr.append(tikz.curve_to_tikz(points, 3) + ';') # Return the text. return '\n'.join(arr)
def tikz_superposition(t_seq, y_seqs, width, height): """ Return the body of a tikzpicture environment. The input defines k piecewise-linear parametric functions. The domain is a real interval. The kth sequence of y values should have k zero-crossings. The returned drawing has arbitrary horizontal and vertical scale. @param t_seq: sequence of t values @param y_seqs: sequence of y value sequences @param width: a horizontal scaling factor @param height: a vertical scaling factor @return: LaTeX code for a tikzpicture """ # check the form of the input sequences assert_support(t_seq, y_seqs) # Get the y scaling factor. # This is the value by which the observed y values are multiplied # to give a number that is relevant to the tikz coordinate system. ymin = min(min(seq) for seq in y_seqs) ymax = max(max(seq) for seq in y_seqs) yscale = height / float(ymax - ymin) # Get the x scaling factor. xmin = t_seq[0] xmax = t_seq[-1] xscale = width / float(xmax - xmin) # Get the rescaled sequences. t_seq_rescaled = [t*xscale for t in t_seq] y_seqs_rescaled = [[y*yscale for y in seq] for seq in y_seqs] # Start the text array. arr = [] # Plot the horizontal domain segment. pa = tikz.point_to_tikz((t_seq_rescaled[0], 0)) pb = tikz.point_to_tikz((t_seq_rescaled[-1], 0)) arr.append('\\draw %s -- %s;' % (pa, pb)) # Plot the scaled functions. for seq, c in zip(y_seqs_rescaled, color.wolfram): arr.append('\\draw[color=%s]' % c) points = zip(t_seq_rescaled, seq) arr.append(tikz.curve_to_tikz(points, 3) + ';') # Return the text. return '\n'.join(arr)
def _draw_beam(self, p_mid, color): scale = np.array((self.plot_width / self.timescale, self.plot_height)) xproj = np.array((1, 0)) yproj = np.array((0, 1)) out = StringIO() print >> out, r'\path[fill=%s,fill opacity=0.5]' % color p_upper = p_mid + 0.5 * self.p_width p_lower = p_mid - 0.5 * self.p_width t_upper = self.f.inv(p_lower) t_lower = self.f.inv(p_upper) pta = np.array((t_lower, p_upper)) ptb = np.array((t_upper, p_lower)) dta = np.array((1, self.f.deriv(t_lower))) dtb = np.array((1, self.f.deriv(t_upper))) print >> out, tikz.point_to_tikz(pta * scale * yproj) + ' --' bchunk = bezier.create_bchunk_hermite(t_lower, t_upper, pta * scale, ptb * scale, dta * scale, dtb * scale) pts = tuple(tikz.point_to_tikz(p) for p in bchunk.get_points()) print >> out, '%s .. controls %s and %s .. %s --' % pts print >> out, tikz.point_to_tikz(ptb * scale * xproj) + ' --' print >> out, tikz.point_to_tikz(pta * scale * xproj) + ' --' ptc = np.array((t_lower, p_lower)) print >> out, tikz.point_to_tikz(ptc * scale) + ' --' print >> out, tikz.point_to_tikz(ptb * scale * yproj) + ' -- cycle;' return out.getvalue().rstrip()
def get_tikz_body(fs): out = StringIO() # init the processes from user data fast_process = Process(fs.plot_width, fs.plot_height, fs.t_max, fs.p_width, fs.fast_mu, fs.fast_low, fs.fast_high) slow_process = Process(fs.plot_width, fs.plot_height, fs.t_max, fs.p_width, fs.slow_mu, fs.slow_low, fs.slow_high) # predefined variables origin = (0, 0) # define user variables plot_width = fs.plot_width plot_height = fs.plot_height timescale = fs.t_max plotscale = np.array((plot_width, plot_height)) # draw the beams print >> out, slow_process.draw_high_beam("blue!60") print >> out, slow_process.draw_low_beam("blue!60") print >> out, fast_process.draw_high_beam("red!60") print >> out, fast_process.draw_low_beam("red!60") # draw the boundary of the plot print >> out, r"\draw[color=gray] " + get_segment(origin, (plot_width, 0)) print >> out, r"\draw[color=gray] " + get_segment(origin, (0, plot_height)) print >> out, r"\draw[color=gray] " + get_segment((0, plot_height), (plot_width, plot_height)) print >> out, r"\draw[dotted,color=gray] " + get_segment((0, 0.25 * plot_height), (plot_width, 0.25 * plot_height)) # draw the bezier curves hitting the right knots for p in (slow_process, fast_process): print >> out, p.draw_curve() # draw filled black dots at some intersections dot_points = [origin, (0, plot_height), (0, 0.25 * plot_height)] for dot_point in dot_points: print >> out, r"\fill[color=black,inner sep=0pt]", print >> out, tikz.point_to_tikz(dot_point), print >> out, "circle (1pt);" # draw some text annotations pt_txt_pairs = [((0, 0), "0"), ((0, 0.25 * plot_height), r"$\frac{1}{4}$"), ((0, 1.0 * plot_height), "1")] for i, (pt, txt) in enumerate(pt_txt_pairs): print >> out, r"\node[anchor=east] (%s) at %s {%s};" % ("ylabel%d" % i, tikz.point_to_tikz(pt), txt) # return out.getvalue().rstrip()
def get_linear_tikz_pane( shape, width, height, time_lists, t_initial, t_final, vgap, cut_radius): abstol = 1e-6 duration = float(t_final - t_initial) arr = [] for i in range(4): c = g_colors[i] xa = t_initial * (width / duration) xb = t_final * (width / duration) # draw the thin line of the correct color line = '\\draw[%s] %s -- %s;' % ( c, tikz.point_to_tikz((xa, -i*vgap)), tikz.point_to_tikz((xb, -i*vgap))) arr.append(line) # draw the thick segments of the correct color if i: augmented_times = [t_initial] + time_lists[i-1] + [t_final] for ta, tb in iterutils.pairwise(augmented_times): t = (ta + tb) / 2.0 xa = ta * (width / duration) xb = tb * (width / duration) value = shape.fps[i-1](t) if value > 0: line = '\\draw[very thick,%s] %s -- %s;' % ( c, tikz.point_to_tikz((xa, -i*vgap)), tikz.point_to_tikz((xb, -i*vgap))) arr.append(line) # draw the cuts in black ink if i < 3: times = time_lists[i] for t in times: x = t * (width / duration) line = '\\draw %s -- %s;' % ( tikz.point_to_tikz((x, cut_radius-i*vgap)), tikz.point_to_tikz((x, -cut_radius-i*vgap))) arr.append(line) return '\n'.join(arr)
def get_linear_tikz_pane(shape, width, height, time_lists, t_initial, t_final, vgap, cut_radius): abstol = 1e-6 duration = float(t_final - t_initial) arr = [] for i in range(4): c = g_colors[i] xa = t_initial * (width / duration) xb = t_final * (width / duration) # draw the thin line of the correct color line = '\\draw[%s] %s -- %s;' % (c, tikz.point_to_tikz( (xa, -i * vgap)), tikz.point_to_tikz((xb, -i * vgap))) arr.append(line) # draw the thick segments of the correct color if i: augmented_times = [t_initial] + time_lists[i - 1] + [t_final] for ta, tb in iterutils.pairwise(augmented_times): t = (ta + tb) / 2.0 xa = ta * (width / duration) xb = tb * (width / duration) value = shape.fps[i - 1](t) if value > 0: line = '\\draw[very thick,%s] %s -- %s;' % ( c, tikz.point_to_tikz((xa, -i * vgap)), tikz.point_to_tikz((xb, -i * vgap))) arr.append(line) # draw the cuts in black ink if i < 3: times = time_lists[i] for t in times: x = t * (width / duration) line = '\\draw %s -- %s;' % (tikz.point_to_tikz( (x, cut_radius - i * vgap)), tikz.point_to_tikz( (x, -cut_radius - i * vgap))) arr.append(line) return '\n'.join(arr)
def _draw_beam(self, p_mid, color): scale = np.array((self.plot_width / self.timescale, self.plot_height)) xproj = np.array((1, 0)) yproj = np.array((0, 1)) out = StringIO() print >> out, r"\path[fill=%s,fill opacity=0.5]" % color p_upper = p_mid + 0.5 * self.p_width p_lower = p_mid - 0.5 * self.p_width t_upper = self.f.inv(p_lower) t_lower = self.f.inv(p_upper) pta = np.array((t_lower, p_upper)) ptb = np.array((t_upper, p_lower)) dta = np.array((1, self.f.deriv(t_lower))) dtb = np.array((1, self.f.deriv(t_upper))) print >> out, tikz.point_to_tikz(pta * scale * yproj) + " --" bchunk = bezier.create_bchunk_hermite(t_lower, t_upper, pta * scale, ptb * scale, dta * scale, dtb * scale) pts = tuple(tikz.point_to_tikz(p) for p in bchunk.get_points()) print >> out, "%s .. controls %s and %s .. %s --" % pts print >> out, tikz.point_to_tikz(ptb * scale * xproj) + " --" print >> out, tikz.point_to_tikz(pta * scale * xproj) + " --" ptc = np.array((t_lower, p_lower)) print >> out, tikz.point_to_tikz(ptc * scale) + " --" print >> out, tikz.point_to_tikz(ptb * scale * yproj) + " -- cycle;" return out.getvalue().rstrip()
def get_tikz_body(fs): out = StringIO() # define user variables plot_width = fs.plot_width plot_height = fs.plot_height timescale = fs.t_max fast_mu = fs.fast_mu slow_mu = fs.slow_mu if fs.info_identity_slope: f_fast = JC69.IdentitySlopeInformation(fast_mu) f_slow = JC69.IdentitySlopeInformation(slow_mu) elif fs.info_mi: f_fast = JC69.MutualInformation(fast_mu) f_slow = JC69.MutualInformation(slow_mu) elif fs.info_fi: #f_fast = JC69.FisherInformationTheano(fast_mu) #f_slow = JC69.FisherInformationTheano(slow_mu) f_fast = JC69.FisherInformation(fast_mu) f_slow = JC69.FisherInformation(slow_mu) # Define some times for evaluation of the curve. times = [timescale*2**-i for i in range(10)] if fs.info_identity_slope: # Compute the intersection time. t_x = math.log(fast_mu / slow_mu) / (fast_mu - slow_mu) times.extend([t_x / 2, t_x, (t_x + timescale)/2]) # define some more intermediate values ymax = max(f_fast(min(times)), f_slow(min(times))) * 1.2 plotscale = np.array((plot_width / timescale, plot_height / ymax)) origin = (0, 0) # draw the boundary of the plot print >> out, r'\draw[color=gray] %s %s {%s} %s;' % ( tikz.point_to_tikz(origin), 'edge node[color=black,below]', '$t$', tikz.point_to_tikz((plot_width, 0))) print >> out, r'\draw[color=gray] ' + get_segment( origin, (0, plot_height)) # draw the bezier curves hitting the right knots for f in (f_slow, f_fast): bchunks = [] for a, b in iterutils.pairwise(sorted(times)): pta = np.array((a, f(a))) ptb = np.array((b, f(b))) dta = np.array((1, f.deriv(a))) dtb = np.array((1, f.deriv(b))) bchunk = bezier.create_bchunk_hermite( a, b, pta * plotscale, ptb * plotscale, dta * plotscale, dtb * plotscale) bchunks.append(bchunk) print >> out, r'\draw[color=gray] ' + get_tikz_bezier(bchunks) # draw filled black dots at some intersections dot_points = [origin] if not fs.info_fi: dot_points.append((0, f_fast(0))) dot_points.append((0, f_slow(0))) if fs.info_identity_slope: dot_points.append((t_x, f_slow(t_x))) for p in dot_points: print >> out, r'\fill[color=black,inner sep=0pt]', print >> out, tikz.point_to_tikz(np.array(p) * plotscale), print >> out, 'circle (1pt);' # draw some text annotations pt_txt_pairs = [ ((0, 0), '0'), ] for i, (pt, txt) in enumerate(pt_txt_pairs): print >> out, r'\node[anchor=east] (%s) at %s {%s};' % ( 'ylabel%d' % i, tikz.point_to_tikz(pt), txt) # return out.getvalue().rstrip()
def get_tree_tikz_pane(sample, width, height, vgap, cut_radius): # Use the target width to scale the layout. # TODO rotate the layout for greatest width to height ratio. unscaled_layout_points = sample.v_to_layout_point.values() pmin = np.min(unscaled_layout_points, axis=0) pmax = np.max(unscaled_layout_points, axis=0) sf_width = width / (pmax[0] - pmin[0]) sf_height = height / ((pmax[1] - pmin[1]) * 4 + vgap * 3) sf = min(sf_width, sf_height) v_to_layout_point = dict( (v, p * sf) for v, p in sample.v_to_layout_point.items()) # Compute the amount (in tikz units) to skip per tree. vskip = (pmax[1] - pmin[1]) * sf + vgap # Draw the tikz. arr = [] vskip_accum = 0.0 for i in range(4): # define the current offset for drawing offset = np.array([0, -vskip_accum]) # define the color of the tree c = g_colors[i] # draw the tree using thin line segments for va, vb in sample.T: pa, pb = v_to_layout_point[va], v_to_layout_point[vb] # draw the thin line segment of the correct color line = '\\draw[%s] %s -- %s;' % (c, tikz.point_to_tikz(pa + offset), tikz.point_to_tikz(pb + offset)) arr.append(line) # draw the thick segments of the correct color if i: axis = i - 1 for va, vb in sample.T: vala = sample.v_to_point[va][axis] valb = sample.v_to_point[vb][axis] pa, pb = v_to_layout_point[va], v_to_layout_point[vb] if vala > 0 and valb > 0: # If both endpoints are positive # then redraw the whole segment using a very thick line. line = '\\draw[very thick,%s] %s -- %s;' % ( c, tikz.point_to_tikz(pa + offset), tikz.point_to_tikz(pb + offset)) arr.append(line) elif vala * valb < 0: # If the endpoints have opposite sign # then redraw only part of the line. t = vala / (vala - valb) p = (1 - t) * pa + t * pb if vala > 0: p_begin = pa p_end = p else: b_begin = p p_end = pb line = '\\draw[very thick,%s] %s -- %s;' % ( c, tikz.point_to_tikz(p_begin + offset), tikz.point_to_tikz(p_end + offset)) arr.append(line) #TODO draw tick marks if i < 3: axis = i for va, vb in sample.T: vala = sample.v_to_point[va][axis] valb = sample.v_to_point[vb][axis] pa, pb = v_to_layout_point[va], v_to_layout_point[vb] if vala * valb < 0: # If the endpoints have opposite sign # then draw a tick mark. t = vala / (vala - valb) p = (1 - t) * pa + t * pb theta = math.atan2((pb - pa)[1], (pb - pa)[0]) phi = theta + math.pi / 2 cuta = p + offset cutb = p + offset cuta[0] += cut_radius * math.cos(phi) cuta[1] += cut_radius * math.sin(phi) cutb[0] -= cut_radius * math.cos(phi) cutb[1] -= cut_radius * math.sin(phi) line = '\\draw %s -- %s;' % (tikz.point_to_tikz(cuta), tikz.point_to_tikz(cutb)) arr.append(line) # skip some space vskip_accum += vskip # return the tikz text return '\n'.join(arr)
def get_tikz_body(fs): out = StringIO() # define user variables plot_width = fs.plot_width plot_height = fs.plot_height timescale = fs.t_max fast_mu = fs.fast_mu slow_mu = fs.slow_mu if fs.info_identity_slope: f_fast = JC69.IdentitySlopeInformation(fast_mu) f_slow = JC69.IdentitySlopeInformation(slow_mu) elif fs.info_mi: f_fast = JC69.MutualInformation(fast_mu) f_slow = JC69.MutualInformation(slow_mu) elif fs.info_fi: #f_fast = JC69.FisherInformationTheano(fast_mu) #f_slow = JC69.FisherInformationTheano(slow_mu) f_fast = JC69.FisherInformation(fast_mu) f_slow = JC69.FisherInformation(slow_mu) # Define some times for evaluation of the curve. times = [timescale * 2**-i for i in range(10)] if fs.info_identity_slope: # Compute the intersection time. t_x = math.log(fast_mu / slow_mu) / (fast_mu - slow_mu) times.extend([t_x / 2, t_x, (t_x + timescale) / 2]) # define some more intermediate values ymax = max(f_fast(min(times)), f_slow(min(times))) * 1.2 plotscale = np.array((plot_width / timescale, plot_height / ymax)) origin = (0, 0) # draw the boundary of the plot print >> out, r'\draw[color=gray] %s %s {%s} %s;' % ( tikz.point_to_tikz(origin), 'edge node[color=black,below]', '$t$', tikz.point_to_tikz((plot_width, 0))) print >> out, r'\draw[color=gray] ' + get_segment(origin, (0, plot_height)) # draw the bezier curves hitting the right knots for f in (f_slow, f_fast): bchunks = [] for a, b in iterutils.pairwise(sorted(times)): pta = np.array((a, f(a))) ptb = np.array((b, f(b))) dta = np.array((1, f.deriv(a))) dtb = np.array((1, f.deriv(b))) bchunk = bezier.create_bchunk_hermite(a, b, pta * plotscale, ptb * plotscale, dta * plotscale, dtb * plotscale) bchunks.append(bchunk) print >> out, r'\draw[color=gray] ' + get_tikz_bezier(bchunks) # draw filled black dots at some intersections dot_points = [origin] if not fs.info_fi: dot_points.append((0, f_fast(0))) dot_points.append((0, f_slow(0))) if fs.info_identity_slope: dot_points.append((t_x, f_slow(t_x))) for p in dot_points: print >> out, r'\fill[color=black,inner sep=0pt]', print >> out, tikz.point_to_tikz(np.array(p) * plotscale), print >> out, 'circle (1pt);' # draw some text annotations pt_txt_pairs = [ ((0, 0), '0'), ] for i, (pt, txt) in enumerate(pt_txt_pairs): print >> out, r'\node[anchor=east] (%s) at %s {%s};' % ( 'ylabel%d' % i, tikz.point_to_tikz(pt), txt) # return out.getvalue().rstrip()
def get_seg(pta, ptb): return '%s -- %s' % (tikz.point_to_tikz(pta), tikz.point_to_tikz(ptb))
def get_tree_tikz_pane(sample, width, height, vgap, cut_radius): # Use the target width to scale the layout. # TODO rotate the layout for greatest width to height ratio. unscaled_layout_points = sample.v_to_layout_point.values() pmin = np.min(unscaled_layout_points, axis=0) pmax = np.max(unscaled_layout_points, axis=0) sf_width = width / (pmax[0] - pmin[0]) sf_height = height / ((pmax[1] - pmin[1]) * 4 + vgap * 3) sf = min(sf_width, sf_height) v_to_layout_point = dict( (v, p*sf) for v, p in sample.v_to_layout_point.items()) # Compute the amount (in tikz units) to skip per tree. vskip = (pmax[1] - pmin[1])*sf + vgap # Draw the tikz. arr = [] vskip_accum = 0.0 for i in range(4): # define the current offset for drawing offset = np.array([0, -vskip_accum]) # define the color of the tree c = g_colors[i] # draw the tree using thin line segments for va, vb in sample.T: pa, pb = v_to_layout_point[va], v_to_layout_point[vb] # draw the thin line segment of the correct color line = '\\draw[%s] %s -- %s;' % ( c, tikz.point_to_tikz(pa + offset), tikz.point_to_tikz(pb + offset)) arr.append(line) # draw the thick segments of the correct color if i: axis = i-1 for va, vb in sample.T: vala = sample.v_to_point[va][axis] valb = sample.v_to_point[vb][axis] pa, pb = v_to_layout_point[va], v_to_layout_point[vb] if vala > 0 and valb > 0: # If both endpoints are positive # then redraw the whole segment using a very thick line. line = '\\draw[very thick,%s] %s -- %s;' % ( c, tikz.point_to_tikz(pa + offset), tikz.point_to_tikz(pb + offset)) arr.append(line) elif vala * valb < 0: # If the endpoints have opposite sign # then redraw only part of the line. t = vala / (vala - valb) p = (1 - t) * pa + t * pb if vala > 0: p_begin = pa p_end = p else: b_begin = p p_end = pb line = '\\draw[very thick,%s] %s -- %s;' % ( c, tikz.point_to_tikz(p_begin + offset), tikz.point_to_tikz(p_end + offset)) arr.append(line) #TODO draw tick marks if i < 3: axis = i for va, vb in sample.T: vala = sample.v_to_point[va][axis] valb = sample.v_to_point[vb][axis] pa, pb = v_to_layout_point[va], v_to_layout_point[vb] if vala * valb < 0: # If the endpoints have opposite sign # then draw a tick mark. t = vala / (vala - valb) p = (1 - t) * pa + t * pb theta = math.atan2((pb-pa)[1], (pb-pa)[0]) phi = theta + math.pi/2 cuta = p + offset cutb = p + offset cuta[0] += cut_radius * math.cos(phi) cuta[1] += cut_radius * math.sin(phi) cutb[0] -= cut_radius * math.cos(phi) cutb[1] -= cut_radius * math.sin(phi) line = '\\draw %s -- %s;' % ( tikz.point_to_tikz(cuta), tikz.point_to_tikz(cutb)) arr.append(line) # skip some space vskip_accum += vskip # return the tikz text return '\n'.join(arr)
def get_tikz_body(fs): out = StringIO() # predefined variables mu = 1.0 origin = (0, 0) f = MyCurve(mu) # define user variables plot_width = fs.plot_width plot_height = fs.plot_height timescale = fs.t_max ta = f.inv(fs.p_high) / timescale tb = f.inv(fs.p_low) / timescale # validate if tb <= ta: raise ValueError('interval lower bound should be below upper bound') plotscale = np.array((plot_width, plot_height)) # draw the boundary of the plot print >> out, r'\draw[color=gray] ' + get_segment( origin, (plot_width, 0)) print >> out, r'\draw[color=gray] ' + get_segment( origin, (0, plot_height)) print >> out, r'\draw[color=gray] ' + get_segment( (0,plot_height), (plot_width, plot_height)) print >> out, r'\draw[dotted,color=gray] ' + get_segment( (0,0.25*plot_height), (plot_width, 0.25*plot_height)) # define times of interest t0 = 0 tx = (tb + 1) / 2 t1 = 1 # draw the bezier curve hitting the right knots scale = np.array((plot_width / timescale, plot_height)) times = (t0, ta, tb, tx, t1) bchunks = [] for a, b in iterutils.pairwise(times): a = timescale * a b = timescale * b pta = np.array((a, f(a))) ptb = np.array((b, f(b))) dta = np.array((1, f.deriv(a))) dtb = np.array((1, f.deriv(b))) bchunk = bezier.create_bchunk_hermite( a, b, pta * scale, ptb * scale, dta * scale, dtb * scale) bchunks.append(bchunk) print >> out, r'\draw[color=gray] ' + get_tikz_bezier(bchunks) # redraw a piece of the curve a = timescale * ta b = timescale * tb pta = np.array((a, f(a))) ptb = np.array((b, f(b))) dta = np.array((1, f.deriv(a))) dtb = np.array((1, f.deriv(b))) bchunk = bezier.create_bchunk_hermite( a, b, pta * scale, ptb * scale, dta * scale, dtb * scale) pts = tuple(tikz.point_to_tikz(p) for p in bchunk.get_points()) print >> out, r'\draw[color=black] %s .. controls %s and %s .. %s;' % pts """ print >> out, r'\draw[color=black] ' + get_segment( pta * scale, ptb * scale) """ # draw the projections of the secant onto the axes xproj = np.array((1, 0)) yproj = np.array((0, 1)) print >> out, r'\draw[color=black] ' + get_segment( pta * scale * xproj, ptb * scale * xproj) print >> out, r'\draw[color=black] ' + get_segment( pta * scale * yproj, ptb * scale * yproj) print >> out, r'\draw[dotted,color=gray] ' + get_segment( pta * scale, pta * scale * xproj) print >> out, r'\draw[dotted,color=gray] ' + get_segment( ptb * scale, ptb * scale * xproj) print >> out, r'\draw[dotted,color=gray] ' + get_segment( pta * scale, pta * scale * yproj) print >> out, r'\draw[dotted,color=gray] ' + get_segment( ptb * scale, ptb * scale * yproj) # draw filled black dots at some intersections dot_points = [ origin, (0, plot_height), (0, 0.25 * plot_height), pta * scale, ptb * scale, pta * scale * xproj, pta * scale * yproj, ptb * scale * xproj, ptb * scale * yproj, ] for dot_point in dot_points: print >> out, r'\fill[color=black,inner sep=0pt]', print >> out, tikz.point_to_tikz(dot_point), print >> out, 'circle (1pt);' # draw braces brace_terms = [ r'\draw[decorate,decoration={brace},yshift=-2pt] ', get_seg(ptb * scale * xproj, pta * scale * xproj), r'node [black,midway,yshift=-2pt]', #r'{$\Delta t_{\text{divergence}}$};'] r'{$\Delta t$};'] print >> out, ' '.join(brace_terms) brace_terms = [ r'\draw[decorate,decoration={brace},xshift=-2pt] ', get_seg(ptb * scale * yproj, pta * scale * yproj), r'node [black,midway,xshift=-2pt]', #r'{$\Delta P_{\text{identity}}$};'] r'{$\Delta p$};'] print >> out, ' '.join(brace_terms) # draw some text annotations pt_txt_pairs = [ ((0, 0), '0'), ((0, 0.25 * plot_height), r'$\frac{1}{4}$'), ((0, 1.0 * plot_height), '1')] for i, (pt, txt) in enumerate(pt_txt_pairs): print >> out, r'\node[anchor=east] (%s) at %s {%s};' % ( 'ylabel%d' % i, tikz.point_to_tikz(pt), txt) # return out.getvalue().rstrip()
def get_tikz_body(fs): out = StringIO() # predefined variables mu = 1.0 origin = (0, 0) f = MyCurve(mu) # define user variables plot_width = fs.plot_width plot_height = fs.plot_height timescale = fs.t_max ta = f.inv(fs.p_high) / timescale tb = f.inv(fs.p_low) / timescale # validate if tb <= ta: raise ValueError('interval lower bound should be below upper bound') plotscale = np.array((plot_width, plot_height)) # draw the boundary of the plot print >> out, r'\draw[color=gray] ' + get_segment(origin, (plot_width, 0)) print >> out, r'\draw[color=gray] ' + get_segment(origin, (0, plot_height)) print >> out, r'\draw[color=gray] ' + get_segment( (0, plot_height), (plot_width, plot_height)) print >> out, r'\draw[dotted,color=gray] ' + get_segment( (0, 0.25 * plot_height), (plot_width, 0.25 * plot_height)) # define times of interest t0 = 0 tx = (tb + 1) / 2 t1 = 1 # draw the bezier curve hitting the right knots scale = np.array((plot_width / timescale, plot_height)) times = (t0, ta, tb, tx, t1) bchunks = [] for a, b in iterutils.pairwise(times): a = timescale * a b = timescale * b pta = np.array((a, f(a))) ptb = np.array((b, f(b))) dta = np.array((1, f.deriv(a))) dtb = np.array((1, f.deriv(b))) bchunk = bezier.create_bchunk_hermite(a, b, pta * scale, ptb * scale, dta * scale, dtb * scale) bchunks.append(bchunk) print >> out, r'\draw[color=gray] ' + get_tikz_bezier(bchunks) # redraw a piece of the curve a = timescale * ta b = timescale * tb pta = np.array((a, f(a))) ptb = np.array((b, f(b))) dta = np.array((1, f.deriv(a))) dtb = np.array((1, f.deriv(b))) bchunk = bezier.create_bchunk_hermite(a, b, pta * scale, ptb * scale, dta * scale, dtb * scale) pts = tuple(tikz.point_to_tikz(p) for p in bchunk.get_points()) print >> out, r'\draw[color=black] %s .. controls %s and %s .. %s;' % pts """ print >> out, r'\draw[color=black] ' + get_segment( pta * scale, ptb * scale) """ # draw the projections of the secant onto the axes xproj = np.array((1, 0)) yproj = np.array((0, 1)) print >> out, r'\draw[color=black] ' + get_segment(pta * scale * xproj, ptb * scale * xproj) print >> out, r'\draw[color=black] ' + get_segment(pta * scale * yproj, ptb * scale * yproj) print >> out, r'\draw[dotted,color=gray] ' + get_segment( pta * scale, pta * scale * xproj) print >> out, r'\draw[dotted,color=gray] ' + get_segment( ptb * scale, ptb * scale * xproj) print >> out, r'\draw[dotted,color=gray] ' + get_segment( pta * scale, pta * scale * yproj) print >> out, r'\draw[dotted,color=gray] ' + get_segment( ptb * scale, ptb * scale * yproj) # draw filled black dots at some intersections dot_points = [ origin, (0, plot_height), (0, 0.25 * plot_height), pta * scale, ptb * scale, pta * scale * xproj, pta * scale * yproj, ptb * scale * xproj, ptb * scale * yproj, ] for dot_point in dot_points: print >> out, r'\fill[color=black,inner sep=0pt]', print >> out, tikz.point_to_tikz(dot_point), print >> out, 'circle (1pt);' # draw braces brace_terms = [ r'\draw[decorate,decoration={brace},yshift=-2pt] ', get_seg(ptb * scale * xproj, pta * scale * xproj), r'node [black,midway,yshift=-2pt]', #r'{$\Delta t_{\text{divergence}}$};'] r'{$\Delta t$};' ] print >> out, ' '.join(brace_terms) brace_terms = [ r'\draw[decorate,decoration={brace},xshift=-2pt] ', get_seg(ptb * scale * yproj, pta * scale * yproj), r'node [black,midway,xshift=-2pt]', #r'{$\Delta P_{\text{identity}}$};'] r'{$\Delta p$};' ] print >> out, ' '.join(brace_terms) # draw some text annotations pt_txt_pairs = [((0, 0), '0'), ((0, 0.25 * plot_height), r'$\frac{1}{4}$'), ((0, 1.0 * plot_height), '1')] for i, (pt, txt) in enumerate(pt_txt_pairs): print >> out, r'\node[anchor=east] (%s) at %s {%s};' % ( 'ylabel%d' % i, tikz.point_to_tikz(pt), txt) # return out.getvalue().rstrip()
def get_tikz_lines(fs): """ @param fs: user input @return: a sequence of tikz lines """ # define characteristics for all circles radius = 1 nsegments = 5 # define the first circle center = np.array([1.0, 1.0, 1.0]) axis = 0 owned_bchunks = bezier.gen_bchunks_ortho_circle( center, radius, axis, pcurve.OwnedBezierChunk) first_curve = pcurve.BezierPath(owned_bchunks) # define the second circle center = np.array([1.0, 1.0, 0.0]) axis = 1 owned_bchunks = bezier.gen_bchunks_ortho_circle( center, radius, axis, pcurve.OwnedBezierChunk) second_curve = pcurve.BezierPath(owned_bchunks) # rotate every control point in every bchunk in each curve for curve in (first_curve, second_curve): for b in curve.bchunks: b.p0 = rotate_to_view(b.p0) b.p1 = rotate_to_view(b.p1) b.p2 = rotate_to_view(b.p2) b.p3 = rotate_to_view(b.p3) # define some new flat curves whose bchunks reference the deep curves deep_curves = (first_curve, second_curve) flat_curves = [] for deep_curve in deep_curves: flat_bchunks = [] for deep_b in deep_curve.bchunks: flat_b = pcurve.OwnedBezierChunk( deep_b.start_time, deep_b.stop_time, deep_b.p0[1:], deep_b.p1[1:], deep_b.p2[1:], deep_b.p3[1:]) flat_b.parent_ref = id(deep_curve) flat_bchunks.append(flat_b) flat_curves.append(pcurve.BezierPath(flat_bchunks)) # break up the piecewise curves for z-ordering child_parent_curve_pairs = list(pcurve.decompose_scene( deep_curves, flat_curves, fs.min_gridsize)) # extract the child curves child_curves = zip(*child_parent_curve_pairs)[0] # sort the child curves according to depth order # TODO chain together the bezier curve into a single drawing command depth_curve_pairs = [] for curve in child_curves: x, y, z = rotate_to_view(curve.evaluate(curve.characteristic_time)) depth_curve_pairs.append((x, curve)) lines = [] for x, curve in sorted(depth_curve_pairs): colors = ['yellow', 'orange', 'red', 'green', 'blue', 'purple'] c = random.choice(colors) for b in curve.bchunks: controls = (b.p0, b.p1, b.p2, b.p3) points = [tikz.point_to_tikz(p[1:]) for p in controls] args = tuple([c] + points) line = '\\draw[draw=white,double=%s,thick] %s .. controls %s and %s .. %s;' % args lines.append(line) #line = '\\draw %s -- %s -- %s -- %s;' % points #lines.append(line) return lines