def _build_an_egg(power, tip_addon): h = lambda cos_alpha: cos_alpha * (1 - 1 / power) + 1 / ( power * cos_alpha) - (1 + tip_addon) cos_alpha_solution = fsolve(h, x0=.5)[0] if cos_alpha_solution > 1.: cos_alpha_solution = 1 / (cos_alpha_solution * (power - 1)) if is_the_same_point(1., cos_alpha_solution): a = 0 else: a = (1 + tip_addon - cos_alpha_solution) / ( (1 - cos_alpha_solution * cos_alpha_solution)**(power / 2)) alpha_solution = acos_hours(cos_alpha_solution) _arc = build_an_arc(angle_start=0, angle_end=full_turn_angle / 2 - alpha_solution) pf_points_qty = int(my_default_vertices_qty_in_circle / 4) power_func_x = sqrt(1 - cos_alpha_solution * cos_alpha_solution) * ( 1. - np.array([n / pf_points_qty for n in range(pf_points_qty + 1)])) power_func_2D = [[x, a * (x**power)] for x in power_func_x] right_half_contour = link_contours(_arc + [0, (1 + tip_addon)], power_func_2D) # adding the left half and # moving the egg so that its centre were where needed contour = add_a_left_mirror(right_half_contour) return contour
def build_a_smile(width, depth): # if mid_point is almost at the same hor line, assume it's a straight line if is_the_same_point(depth / (width / 2), 0.0): # this will be a segment result = np.empty([2, 2]) elif abs(depth / (width / 2)) <= 1: # an arc of a circle radius = abs( (1 + (depth / (width / 2))**2) / (2 * depth / (width / 2))) angle = (asin_hours(sin_value=1 / radius)) # reusing build_arc result = build_an_arc(angle_start=-angle, angle_end=+angle) * radius - [ 0, radius - abs(depth / (width / 2)) ] if depth > 0: result[:, 1] *= -1 else: # a half-ellipse result = build_an_arc( angle_start=full_turn_angle / 4, angle_end=full_turn_angle * 3 / 4) * [-1, depth / (width / 2)] # adjusting start and end points to make sure they match the inputs exactly result[0] = [-1, 0] result[-1] = [1, 0] # scaling! result *= abs((width / 2)) # all done! return result
def build_a_wave(width, height, angle_start, nb_waves): contour, added_start, added_end = _build_an_arc(angle_start=angle_start, angle_end=angle_start + nb_waves * full_turn_angle) # y's will be sin's, the x's of _build_an_arc's output, with normalization contour[:, 1] = contour[:, 0] * height / 2 # x's are mostly equidistant. We start by putting together an array of distances contour[:, 0] = contour[:, 0] * 0 + 1 contour[0, 0] = 0 if added_start is not None: contour[1, 0] = added_start if added_end is not None: contour[-1, 0] = added_end # now computing x's and normalizing them contour[:, 0] = np.cumsum(contour[:, 0]) if not is_the_same_point(0, contour[-1, 0]): contour[:, 0] *= width / contour[-1, 0] # adjust the starting point contour -= contour[0, :] assert is_the_same_point(contour[0, :], [0, 0]) return contour
def build_a_sector(angle_start, angle_end, radius, radius_2=0): # make sure radius_1 >= radius_2 >= 0 if abs(radius) > abs(radius_2): radius, radius_2 = abs(radius), abs(radius_2) else: radius_2, radius = abs(radius), abs(radius_2) contour = build_an_arc(angle_start=angle_start, angle_end=angle_end) if is_the_same_point(radius_2, 0.0): # special case - just add the mid-point result = link_contours(contour, [[0, 0]]) * radius else: # add the arc inner_arc = np.ndarray.copy(contour) * radius_2 result = link_contours(contour * radius, inner_arc[::-1]) return result
def link_contours(*arg): result = np.empty((2, 0)) for _a in arg: if isinstance(_a, np.ndarray): a = _a else: a = np.array(_a, np.float64) if (a.size == 0): continue if (result.size == 0): result = a continue if is_the_same_point(p1=result[-1], p2=a[0]): result = conc_1_or_2_dim(result[:-1], a) else: result = conc_1_or_2_dim(result, a) return result
def _build_an_arc(angle_start, angle_end): if angle_start > angle_end: angle_start, angle_end = angle_end, angle_start angle_start_normalized = angle_start / full_turn_angle angle_end_normalized = angle_end / full_turn_angle turn_nb_start = floor(angle_start_normalized) turn_nb_end = floor(angle_end_normalized) residual_start = ceil((angle_start_normalized - turn_nb_start) * my_default_vertices_qty_in_circle) residual_end = floor((angle_end_normalized - turn_nb_end) * my_default_vertices_qty_in_circle) if is_the_same_point(turn_nb_start, turn_nb_end): contour = sin_cos_std[residual_start:(residual_end + 1)] else: contour = sin_cos_std[residual_start:] + sin_cos_std * int( turn_nb_end - turn_nb_start - 1) + sin_cos_std[:(residual_end + 1)] contour = np.array(contour, np.float64) c_len = contour.size contour = link_contours([[sin_hours(angle_start), cos_hours(angle_start)]], contour) if c_len == contour.size: added_start = None else: added_start = residual_start - (angle_start_normalized % 1) * my_default_vertices_qty_in_circle c_len = contour.size contour = link_contours( contour, [[sin_hours(angle_end), cos_hours(angle_end)]]) if c_len == contour.size: added_end = None else: added_end = -residual_end + (angle_end_normalized % 1) * my_default_vertices_qty_in_circle return contour, added_start, added_end
def test_gradient(): for test_end in ([255, 255, 255], [2, 3, 5], [2, 3, 15]): result = create_gradient_colours(rgb_start=[0, 0, 0], rgb_end=test_end) for i in range(3): assert is_the_same_point(result[-1][i], test_end[i]/255.) print("succeeded gradient test", [0, 0, 0], '->', test_end)