def get_bezier_path(self): b = bezier.create_bchunk_hermite(self.t_initial, self.t_final, self.fp(self.t_initial), self.fp(self.t_final), self.fv(self.t_initial), self.fv(self.t_final)) return pcurve.BezierPath([b])
def get_bezier_path(self): bchunks = [] for i, (pa, pb) in enumerate(iterutils.pairwise(self.points)): b = bezier.create_bchunk_line_segment(pa, pb) b.start_time = float(i) b.stop_time = float(i + 1) bchunks.append(b) return pcurve.BezierPath(bchunks)
def get_bezier_paths(self): bpaths = [] for va, vb in self.T: pa, pb = self.v_to_point[va], self.v_to_point[vb] b = bezier.create_bchunk_line_segment(pa, pb) b.start_time = 0.0 b.stop_time = 1.0 bpaths.append(pcurve.BezierPath([b])) return bpaths
def get_bezier_path(self): bchunks = [] npoints = len(self.points) for i, j in iterutils.pairwise(range(npoints)): pa, pb = self.points[i], self.points[j] ta, tb = self.times[i], self.times[j] b = bezier.create_bchunk_line_segment(pa, pb) b.start_time = ta b.stop_time = tb bchunks.append(b) return pcurve.BezierPath(bchunks)
def make_half_axis(axis, sign, radius): """ This is a helper function. @param axis: in {0, 1, 2} @return: bpath """ origin = np.zeros(3) target = np.zeros(3) target[axis] = sign * radius b = bezier.create_bchunk_line_segment(origin, target) bpath = pcurve.BezierPath([b]) b.parent_ref = id(bpath) return bpath
def get_scene(root_a, root_b, root_c, initial_t, final_t, intersection_radius, half_axis_radii): """ Define all of the bezier paths annotated with styles. @return: a list of strokes """ # define the strokes strokes = [] # define the half axis line segments xp_rad, xn_rad, yp_rad, yn_rad, zp_rad, zn_rad = half_axis_radii strokes.extend([ bpath_to_stroke(make_half_axis(0, +1, xp_rad), STYLE_X), bpath_to_stroke(make_half_axis(0, -1, xn_rad), STYLE_X), bpath_to_stroke(make_half_axis(1, +1, yp_rad), STYLE_Y), bpath_to_stroke(make_half_axis(1, -1, yn_rad), STYLE_Y), bpath_to_stroke(make_half_axis(2, +1, zp_rad), STYLE_Z), bpath_to_stroke(make_half_axis(2, -1, zn_rad), STYLE_Z) ]) # define the polynomial curve p3 = sympyutils.roots_to_poly((root_a, root_b, root_c)) p2 = p3.diff() p1 = p2.diff() shape = interlace.CubicPolyShape((p1, p2, p3), initial_t, final_t) strokes.append(bpath_to_stroke(shape.get_bezier_path(), STYLE_CURVE)) # define the orthocircles at curve-plane intersections axes = range(3) point_seqs = shape.get_orthoplanar_intersections() styles = (STYLE_X, STYLE_Y, STYLE_Z) for axis, point_seq, style in zip(axes, point_seqs, styles): for center in point_seq: bchunks = list( bezier.gen_bchunks_ortho_circle(center, intersection_radius, axis)) bpath = pcurve.BezierPath(bchunks) for b in bchunks: b.parent_ref = id(bpath) strokes.append(bpath_to_stroke(bpath, style)) return strokes
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_scene(sample): """ Define all of the bezier paths. @param sample: an interlacesample.Sample object @return: a list of strokes """ # define the strokes strokes = [] # For these full images as opposed to the two-color logos, # set the half axis radii per shape. # FIXME AD HOC xp_rad, xn_rad, yp_rad, yn_rad, zp_rad, zn_rad = sample.get_axis_radii() #xp_rad = xn_rad = 3 * (width + height) / 4.0 #yp_rad = yn_rad = width / 2.0 #zp_rad = zn_rad = height / 2.0 # FIXME AD HOC # Replace this junk with the right transformations. # The right way would involve turning the shapes into # bezier paths and then linearly transforming the beziers # and then estimating the width and height of the transformation # by looking at the bezier bounding boxes and recursively splitting # the beziers which are near the x or y max or min, until # the x and y max and min are known within some specified error. # Then the whole scene can be rescaled to fit within the # desired width and height dimensions. # The values should be (A^T g) where g is a screen space # 2d cardinal direction vector # and A is the matrix that rotates and projects the original shapes # into screen space. """ bchunks = [b for bpath in shape.get_bezier_paths() for b in bpath.bchunks] screen_right = bezier.get_max_dot(bchunks, np.array([-0.3, 0.8, 0])) screen_left = bezier.get_max_dot(bchunks, -np.array([-0.3, 0.8, 0])) screen_top = bezier.get_max_dot(bchunks, np.array([-0.1, 0.3, 0.8])) screen_bottom = bezier.get_max_dot(bchunks, -np.array([-0.1, 0.3, 0.8])) scaling_factor = min( (width / 2.0) / screen_right, (width / 2.0) / screen_left, (height / 2.0) / screen_top, (height / 2.0) / screen_bottom) """ # define the scaling factor and the shape sf = sample.get_large_3d_sf() shape = sample.get_shape() # add the half axis strokes strokes.extend([ bpath_to_stroke(make_half_axis(0, +1, xp_rad), STYLE_X), bpath_to_stroke(make_half_axis(0, -1, xn_rad), STYLE_X), bpath_to_stroke(make_half_axis(1, +1, yp_rad), STYLE_Y), bpath_to_stroke(make_half_axis(1, -1, yn_rad), STYLE_Y), bpath_to_stroke(make_half_axis(2, +1, zp_rad), STYLE_Z), bpath_to_stroke(make_half_axis(2, -1, zn_rad), STYLE_Z) ]) # add the scaled bezier paths of the shape for bpath in shape.get_bezier_paths(): bpath.scale(sf) strokes.append(bpath_to_stroke(bpath, STYLE_CURVE)) # define the orthocircles at curve-plane intersections intersection_radius = 0.2 axes = range(3) point_seqs = shape.get_orthoplanar_intersections() styles = (STYLE_X, STYLE_Y, STYLE_Z) for axis, point_seq, style in zip(axes, point_seqs, styles): for center in point_seq: # NOTE using four-stroke circles # NOTE to avoid problems caused by thick back-erased lines """ bchunks = list(bezier.gen_bchunks_ortho_circle( center*sf, intersection_radius, axis)) bpath = pcurve.BezierPath(bchunks) strokes.append(bpath_to_stroke(bpath, style)) """ for b in bezier.gen_bchunks_ortho_circle(center * sf, intersection_radius, axis): strokes.append(bpath_to_stroke(pcurve.BezierPath([b]), style)) # return the strokes return strokes