def get_coords_of_all_pixels(self): # These are in x, y order, to help me keep things straight full_space_dims = np.array([ self.get_frame_width(), self.get_frame_height() ]) full_pixel_dims = np.array([ self.get_pixel_width(), self.get_pixel_height() ]) # These are addressed in the same y, x order as in pixel_array, but the values in them # are listed in x, y order uncentered_pixel_coords = np.indices( [self.get_pixel_height(), self.get_pixel_width()] )[::-1].transpose(1, 2, 0) uncentered_space_coords = fdiv( uncentered_pixel_coords * full_space_dims, full_pixel_dims) # Could structure above line's computation slightly differently, but figured (without much # thought) multiplying by frame_shape first, THEN dividing by pixel_shape, is probably # better than the other order, for avoiding underflow quantization in the division (whereas # overflow is unlikely to be a problem) centered_space_coords = ( uncentered_space_coords - fdiv(full_space_dims, 2) ) # Have to also flip the y coordinates to account for pixel array being listed in # top-to-bottom order, opposite of screen coordinate convention centered_space_coords = centered_space_coords * (1, -1) return centered_space_coords
def get_cairo_context(self, pixel_array): cached_ctx = self.get_cached_cairo_context(pixel_array) if cached_ctx: return cached_ctx pw = self.get_pixel_width() ph = self.get_pixel_height() fw = self.get_frame_width() fh = self.get_frame_height() fc = self.get_frame_center() surface = cairo.ImageSurface.create_for_data(pixel_array, cairo.FORMAT_ARGB32, pw, ph) ctx = cairo.Context(surface) ctx.scale(pw, ph) ctx.set_matrix( cairo.Matrix( fdiv(pw, fw), 0, 0, -fdiv(ph, fh), (pw / 2) - fc[0] * fdiv(pw, fw), (ph / 2) + fc[1] * fdiv(ph, fh), )) self.cache_cairo_context(pixel_array, ctx) return ctx
def get_coords_of_all_pixels(self): # These are in x, y order, to help me keep things straight full_space_dims = np.array([ self.get_frame_width(), self.get_frame_height() ]) full_pixel_dims = np.array([ self.get_pixel_width(), self.get_pixel_height() ]) # These are addressed in the same y, x order as in pixel_array, but the values in them # are listed in x, y order uncentered_pixel_coords = np.indices( [self.get_pixel_height(), self.get_pixel_width()] )[::-1].transpose(1, 2, 0) uncentered_space_coords = fdiv( uncentered_pixel_coords * full_space_dims, full_pixel_dims) # Could structure above line's computation slightly differently, but figured (without much # thought) multiplying by frame_shape first, THEN dividing by pixel_shape, is probably # better than the other order, for avoiding underflow quantization in the division (whereas # overflow is unlikely to be a problem) centered_space_coords = ( uncentered_space_coords - fdiv(full_space_dims, 2) ) # Have to also flip the y coordinates to account for pixel array being listed in # top-to-bottom order, opposite of screen coordinate convention centered_space_coords = centered_space_coords * (1, -1) return centered_space_coords
def set_points_by_ends(self, start, end, buff=0, path_arc=0): # Find the right tip length and thickness vect = end - start length = max(get_norm(vect), 1e-8) thickness = self.thickness w_ratio = fdiv(self.max_width_to_length_ratio, fdiv(thickness, length)) if w_ratio < 1: thickness *= w_ratio tip_width = self.tip_width_ratio * thickness tip_length = tip_width / (2 * np.tan(self.tip_angle / 2)) t_ratio = fdiv(self.max_tip_length_to_length_ratio, fdiv(tip_length, length)) if t_ratio < 1: tip_length *= t_ratio tip_width *= t_ratio # Find points for the stem if path_arc == 0: points1 = (length - tip_length) * np.array( [RIGHT, 0.5 * RIGHT, ORIGIN]) points1 += thickness * UP / 2 points2 = points1[::-1] + thickness * DOWN else: # Solve for radius so that the tip-to-tail length matches |end - start| a = 2 * (1 - np.cos(path_arc)) b = -2 * tip_length * np.sin(path_arc) c = tip_length**2 - length**2 R = (-b + np.sqrt(b**2 - 4 * a * c)) / (2 * a) # Find arc points points1 = Arc.create_quadratic_bezier_points(path_arc) points2 = np.array(points1[::-1]) points1 *= (R + thickness / 2) points2 *= (R - thickness / 2) if path_arc < 0: tip_length *= -1 rot_T = rotation_matrix_transpose(PI / 2 - path_arc, OUT) for points in points1, points2: points[:] = np.dot(points, rot_T) points += R * DOWN self.set_points(points1) # Tip self.add_line_to(tip_width * UP / 2) self.add_line_to(tip_length * LEFT) self.tip_index = len(self.get_points()) - 1 self.add_line_to(tip_width * DOWN / 2) self.add_line_to(points2[0]) # Close it out self.append_points(points2) self.add_line_to(points1[0]) if length > 0: # Final correction super().scale(length / self.get_length()) self.rotate(angle_of_vector(vect) - self.get_angle()) self.shift(start - self.get_start()) self.refresh_triangulation()
def point_to_number(self, point): start, end = self.get_start_and_end() unit_vect = normalize(end - start) proportion = fdiv( np.dot(point - start, unit_vect), np.dot(end - start, unit_vect), ) return interpolate(self.x_min, self.x_max, proportion)
def angle_between_vectors(v1, v2): """ Returns the angle between two 3D vectors. This angle will always be btw 0 and pi """ return np.arccos(fdiv( np.dot(v1, v2), get_norm(v1) * get_norm(v2) ))
def angle_between_vectors(v1, v2): """ Returns the angle between two 3D vectors. This angle will always be btw 0 and pi """ return np.arccos(fdiv( np.dot(v1, v2), get_norm(v1) * get_norm(v2) ))
def point_to_number(self, point): points = self.get_points() start = points[0] end = points[-1] vect = end - start proportion = fdiv( np.dot(point - start, vect), np.dot(end - start, vect), ) return interpolate(self.x_min, self.x_max, proportion)
def point_to_number(self, point): start_point, end_point = self.get_start_and_end() full_vect = end_point - start_point unit_vect = normalize(full_vect) def distance_from_start(p): return np.dot(p - start_point, unit_vect) proportion = fdiv(distance_from_start(point), distance_from_start(end_point)) return interpolate(self.x_min, self.x_max, proportion)
def adjusted_thickness(self, thickness): # TODO: This seems...unsystematic big_sum = op.add( PRODUCTION_QUALITY_CAMERA_CONFIG["pixel_height"], PRODUCTION_QUALITY_CAMERA_CONFIG["pixel_width"], ) this_sum = op.add( self.get_pixel_height(), self.get_pixel_width(), ) factor = fdiv(big_sum, this_sum) return 1 + (thickness - 1) / factor
def adjusted_thickness(self, thickness): # TODO: This seems...unsystematic big_sum = op.add( PRODUCTION_QUALITY_CAMERA_CONFIG["pixel_height"], PRODUCTION_QUALITY_CAMERA_CONFIG["pixel_width"], ) this_sum = op.add( self.get_pixel_height(), self.get_pixel_width(), ) factor = fdiv(big_sum, this_sum) return 1 + (thickness - 1) / factor
def point_to_number(self, point): start_point, end_point = self.get_start_and_end() full_vect = end_point - start_point unit_vect = normalize(full_vect) def distance_from_start(p): return np.dot(p - start_point, unit_vect) proportion = fdiv( distance_from_start(point), distance_from_start(end_point) ) return interpolate(self.x_min, self.x_max, proportion)
def get_zoom_factor(self): """ Returns the Zoom factor of the Zoomed camera. Defined as the ratio between the height of the zoomed camera and the height of the zoomed mini display. Returns ------- float The zoom factor. """ return fdiv(self.zoomed_camera.frame.get_height(), self.zoomed_display.get_height())
def get_cairo_context(self, pixel_array): cached_ctx = self.get_cached_cairo_context(pixel_array) if cached_ctx: return cached_ctx pw = self.get_pixel_width() ph = self.get_pixel_height() fw = self.get_frame_width() fh = self.get_frame_height() fc = self.get_frame_center() surface = cairo.ImageSurface.create_for_data( pixel_array, cairo.FORMAT_ARGB32, pw, ph ) ctx = cairo.Context(surface) ctx.scale(pw, ph) ctx.set_matrix(cairo.Matrix( fdiv(pw, fw), 0, 0, -fdiv(ph, fh), (pw / 2) - fc[0] * fdiv(pw, fw), (ph / 2) + fc[1] * fdiv(ph, fh), )) self.cache_cairo_context(pixel_array, ctx) return ctx
def resize_frame_shape(self, fixed_dimension=0): """ Changes frame_shape to match the aspect ratio of the pixels, where fixed_dimension determines whether frame_height or frame_width remains fixed while the other changes accordingly. """ pixel_height = self.get_pixel_height() pixel_width = self.get_pixel_width() frame_height = self.get_frame_height() frame_width = self.get_frame_width() aspect_ratio = fdiv(pixel_width, pixel_height) if fixed_dimension == 0: frame_height = frame_width / aspect_ratio else: frame_width = aspect_ratio * frame_height self.set_frame_height(frame_height) self.set_frame_width(frame_width)
def resize_frame_shape(self, fixed_dimension=0): """ Changes frame_shape to match the aspect ratio of the pixels, where fixed_dimension determines whether frame_height or frame_width remains fixed while the other changes accordingly. """ pixel_height = self.get_pixel_height() pixel_width = self.get_pixel_width() frame_height = self.get_frame_height() frame_width = self.get_frame_width() aspect_ratio = fdiv(pixel_width, pixel_height) if fixed_dimension == 0: frame_height = frame_width / aspect_ratio else: frame_width = aspect_ratio * frame_height self.set_frame_height(frame_height) self.set_frame_width(frame_width)
def calculate_positive_space_ratio(self): return fdiv( self.dash_length, self.dash_length + self.dash_spacing, )
def get_zoom_factor(self): return fdiv( self.zoomed_camera.frame.get_height(), self.zoomed_display.get_height() )
def calculate_positive_space_ratio(self): return fdiv( self.dash_length, self.dash_length + self.dash_spacing, )
def get_zoom_factor(self): return fdiv(self.zoomed_camera.frame.get_height(), self.zoomed_display.get_height())