def hourglass(window, n, point, radius, color): """ See hourglass_picture.pdf in this project for pictures that may help you better understand the following specification: Displays an "hourglass" shape of circles in the given window. -- Each circle has the given radius and given color. -- Each circle has a horizontal line drawn through it. -- The middlemost of the circles is centered at the given point. -- There is a single circle in that middlemost row. -- There are n rows (including the middlemost row) of circles going UP from the middlemost circle. -- There are n rows (including the middlemost row) of circles going DOWN from the middlemost circle. -- Each circle barely touches its neighbor circles. Preconditions: :type window: rg.RoseWindow :type n: int :type point: rg.Point :type radius: int :type color: str where n and radius are positive and color is a string that denotes a color that rosegraphics understands. """ # ------------------------------------------------------------------------- # TODO: 2. Implement and test this function. # We provided some tests for you (above). # ------------------------------------------------------------------------- ########################################################################### # BONUS: Avoid replicated code if you can. Hint: You are allowed # to define an additional function(s) if you wish. ########################################################################### # ------------------------------------------------------------------------- # DIFFICULTY AND TIME RATINGS (see top of this file for explanation) # DIFFICULTY: 8 # TIME ESTIMATE: 25 minutes (warning: this problem is challenging) # ------------------------------------------------------------------------- xc = point.x yc = point.y xc_start = xc original_xc_start = xc_start original_yc = yc up_down = 1 for k in range(n * 2): if k == n: up_down = -1 xc_start = original_xc_start yc = original_yc xc = xc_start if up_down == 1: cols = k + 1 else: cols = k + 1 - n for j in range(cols): circle = rg.Circle(rg.Point(xc, yc), radius) circle.fill_color = color circle.attach_to(window) line = rg.Line(rg.Point(xc - radius, yc), rg.Point(xc + radius, yc)) line.attach_to(window) xc += 2 * radius yc -= up_down * radius * (3 ** 0.5) xc_start -= radius xc = xc_start window.render()
def problem4(number_of_stairs, step_size, starting_point, window): starting_point.attach_to(window) for k in range(number_of_stairs): line1 = rg.Line( rg.Point(starting_point.x + k * step_size, starting_point.y - k * step_size), rg.Point(starting_point.x + k * step_size, starting_point.y - (k + 1) * step_size)) line2 = rg.Line( rg.Point(starting_point.x + k * step_size, starting_point.y - (k + 1) * step_size), rg.Point(starting_point.x + (k + 1) * step_size, starting_point.y - (k + 1) * step_size)) ending_point = rg.Point( starting_point.x + number_of_stairs * step_size, starting_point.y - number_of_stairs * step_size) line1.color = 'magenta' line2.color = 'black' line1.thickness = 3 line2.thickness = 3 ending_point.attach_to(window) line1.attach_to(window) line2.attach_to(window) window.render() """ See problem4_picture.pdf in this project for pictures that may help you better understand the following specification: What comes in: -- Two positive integers -- An rg.Point. -- A rg.RoseWindow. What goes out: Nothing (i.e., None). Side effects: Draws, on the given RoseWindow: -- The given starting_point. -- A "staircase" of rg.Line objects as DESCRIBED ON THE ATTACHED PDF (problem4_picture.pdf). -- The last (highest and furthest to the right) point. (Draw it as an rg.Point.) Must render but ** NOT close ** the window. Type hints: :type number_of_stairs: int :type step_size: int :type starting_point: rg.Point :type window: rg.RoseWindow """ # ------------------------------------------------------------------------- # DONE: 2. Implement and test this function. # Tests have been written for you (above). # IMPORTANT: For PARTIAL CREDIT, you can draw just the black "bottoms" # of the stair steps. # ------------------------------------------------------------------------- for k in range(8): start_point1 = rg.Point(40 + 40 * k, 360 - 40 * k) end_point1 = rg.Point(80 + 40 * k, 360 - 40 * k) line1 = rg.Line(start_point1, end_point1) line1.thickness = 3 line1.color = 'black' line1.attach_to(window) start_point2 = rg.Point(40 + 40 * k, 360 - 40 * k) end_point2 = rg.Point(40 + 40 * k, 400 - 40 * k) line2 = rg.Line(start_point2, end_point2) line2.thickness = 3 line2.color = 'magenta' line2.attach_to(window) window.render()
def hourglass(window, n, point, radius, color): """ See hourglass_picture.pdf in this project for pictures that may help you better understand the following specification: Displays an "hourglass" shape of circles in the given window. -- Each circle has the given radius and given color. -- Each circle has a horizontal line drawn through it. -- The middlemost of the circles is centered at the given point. -- There is a single circle in that middlemost row. -- There are n rows (including the middlemost row) of circles going UP from the middlemost circle. -- There are n rows (including the middlemost row) of circles going DOWN from the middlemost circle. -- Each circle barely touches its neighbor circles. Preconditions: :type window: rg.RoseWindow :type n: int :type point: rg.Point :type radius: int :type color: str where n and radius are positive and color is a string that denotes a color that rosegraphics understands. """ # ------------------------------------------------------------------ # DONE: 2. Implement and test this function. # We provided some tests for you (above). # ------------------------------------------------------------------ #################################################################### # BONUS: Avoid replicated code if you can. Hint: You are allowed # to define an additional function(s) if you wish. #################################################################### # ------------------------------------------------------------------ # DIFFICULTY AND TIME RATINGS (see top of this file for explanation) # DIFFICULTY: 8 # TIME ESTIMATE: 25 minutes (warning: this problem is challenging) # ------------------------------------------------------------------ import math circle = rg.Circle(point, radius) circle.fill_color = color circle.attach_to(window) line = rg.Line(rg.Point(point.x - radius, point.y), rg.Point(point.x + radius, point.y)) line.attach_to(window) new_center = rg.Point(point.x - radius, point.y - (radius * math.sqrt(3))) for k in range(n - 1): new_circle = rg.Circle(new_center, radius) new_circle.fill_color = color new_circle.attach_to(window) new_line = rg.Line(rg.Point(new_center.x - radius, new_center.y), rg.Point(new_center.x + radius, new_center.y)) new_line.attach_to(window) newer_center = rg.Point(new_center.x + (2 * radius), new_center.y) new_center = rg.Point(new_center.x - radius, new_center.y - (radius * math.sqrt(3))) for j in range(k + 1): newer_circle = rg.Circle(newer_center, radius) newer_circle.fill_color = color newer_circle.attach_to(window) newer_line = rg.Line( rg.Point(newer_center.x - radius, newer_center.y), rg.Point(newer_center.x + radius, newer_center.y)) newer_line.attach_to(window) newer_center = rg.Point(newer_center.x + (2 * radius), newer_center.y) new_center_1 = rg.Point(point.x - radius, point.y + (radius * math.sqrt(3))) for k in range(n - 1): new_circle_1 = rg.Circle(new_center_1, radius) new_circle_1.fill_color = color new_circle_1.attach_to(window) new_line = rg.Line(rg.Point(new_center_1.x - radius, new_center_1.y), rg.Point(new_center_1.x + radius, new_center_1.y)) new_line.attach_to(window) newer_center_1 = rg.Point(new_center_1.x + (2 * radius), new_center_1.y) new_center_1 = rg.Point(new_center_1.x - radius, new_center_1.y + (radius * math.sqrt(3))) for j in range(k + 1): newer_circle_1 = rg.Circle(newer_center_1, radius) newer_circle_1.fill_color = color newer_circle_1.attach_to(window) newer_line = rg.Line( rg.Point(newer_center_1.x - radius, newer_center_1.y), rg.Point(newer_center_1.x + radius, newer_center_1.y)) newer_line.attach_to(window) newer_center_1 = rg.Point(newer_center_1.x + (2 * radius), newer_center_1.y) window.render()
# 300 # # d. Write a line of code that construct a RoseWindow object # whose height is 100: (Use the HOVER trick to figure it out) # window_name = rg.RoseWindow(400,100) # # e. Use the DOT trick to answer the following: # # -- Write the names of two types of graphics objects that # you can construct OTHER than Circle and Point: windo=rg.RoseWindow(800,600) for k in range(150): oval = rg.Ellipse(rg.Point(250-k,250+k), rg.Point(450-k,350-k)) oval.fill_color = 'green' oval.attach_to(windo) polly=rg.Line(rg.Point(12+(k),200-k),rg.Point(200-(k*1),12+(k*2))) polly.fill_color='red' polly.attach_to(windo) windo.render(0.01) oval.detach_from(windo) polly.detach_from(windo) # # -- Write the names of three METHODs that Circle objects have: # WRITE_YOUR_ANSWER_HERE,_REPLACING_THIS # # -- Write the names of three INSTANCE VARIABLEs that Circle # objects have: # WRITE_YOUR_ANSWER_HERE,_REPLACING_THIS # # f. What does a RoseWindow RENDER method do? # WRITE_YOUR_ANSWER_HERE,_REPLACING_THIS
def draw_lines_from_rectangles(rectangle1, rectangle2, n, window): """ What comes in: Four arguments: -- Two rg.Rectangles. -- A positive integer n. -- An rg.RoseWindow. What goes out: Nothing (i.e., None). Side effects: See draw_lines_from_rectangles.pdf in this project for pictures that may help you better understand the following specification: First draws the given rg.Rectangles on the given rg.RoseWindow. Then draws n rg.Lines on the given rg.RoseWindow, such that: -- The 1st rg.Line goes from the center of one of the 1st rg.Rectangle to the center of the 2nd rg.Rectangle. -- The 2nd rg.Line goes from the lower-left corner of the 1st rg.Rectangle and is parallel to the 1st rg.Line, with the same length and direction as the 1st rg.Line. -- Subsequent rg.Lines are shifted from the previous rg.Line in the same way that the 2nd rg.Line is shifted from the 1st. -- Each of the rg.Lines has thickness 5. -- The colors of the rg.Lines alternate, as follows: - The 1st, 3rd, 5th, ... rg.Line has color R1_color - The 2nd, 4th, 6th, ... rg.Line has color R2_color where - R1_color is the outline color of the 1st rg.Rectangle - R2_color is the outline color of the 2nd rg.Rectangle Must ** render ** but ** NOT close ** the window. Type hints: :type rectangle1: rg.Rectangle :type rectangle2: rg.Rectangle :type n: int :type window: rg.RoseWindow """ # ------------------------------------------------------------------ # TODO: 5. Implement and test this function. # Tests have been written for you (above). # # CONSIDER using the ACCUMULATOR IN GRAPHICS pattern, # as in draw_row_of_circles in m1e, # instead of directly using the loop variable. # #################################################################### # HINT: To figure out the code that computes the necessary # endpoints for each line, # ** FIRST DO A CONCRETE EXAMPLE BY HAND! ** #(rectangle1, rectangle2, n, window) #################################################################### # ------------------------------------------------------------------ print('i instantiated that shit boiiiii') window = rg.RoseWindow(900, 700) rectangle1 = rg.Rectangle(rg.Point(300, 150), rg.Point(400, 175)) rectangle2 = rg.Rectangle(rg.Point(100, 25), rg.Point(150, 125)) rectangle1.attach_to(window) rectangle2.attach_to(window) x1 = rectangle1.corner_1.x x2 = rectangle1.corner_2.x y1 = rectangle1.corner_1.y y2 = rectangle1.corner_2.y centerx1 = (x1 + x2) / 2 centery1 = (y1 + y2) / 2 x12 = rectangle2.corner_1.x x22 = rectangle2.corner_2.x y12 = rectangle2.corner_1.y y22 = rectangle2.corner_2.y centerx2 = (x12 + x22) / 2 centery2 = (y12 + y22) / 2 point1 = rg.Point(centerx1, centery1) point2 = rg.Point(centerx2, centery2) for k in range(n): point1 = ((rg.Point(point1 - (y1 - y2)) * k), (rg.Point(point1 - (x1 - x2)) * k)) point2 = (rg.Point(point2 - (y1 - y2) * k), (point2 - (x1 - x2) * k)) line = rg.Line(point1, point2) line.attach_to(window) window.render() window.close_on_mouse_click()
def fancy_polygon(window, circle, number_of_lines, hops_to_next_point, color, thickness): """ What comes in: -- an rg.RoseWindow -- an rg.Circle -- an integer >= 2 that specifies how many rg.Lines to generate as described below -- a positive integer that specifies how many points each line "hops" over (see below for details). -- a string that can be used as a RoseGraphics color -- a positive integer that specifies the thickness to be used for each rg.Line What goes out: Nothing (i.e., None). Side effects: See the 'fancy_polygon' pictures in the pizza.pdf file in this project; they may help you better understand the following: 1. Draws the given rg.Circle in the given rg.RoseWindow. 2. Constructs and draws rg.Line objects to make the picture look like an inscribed regular polygon with the given number of segments, but with each rg.Line going from one point on the given rg.Circle to the point on the given rg.Circle that is the given number of 'hops' away (wrapping as needed). Each rg.Line has the given color and thickness. Each rg.Line should be drawn as an arrow, by setting the rg.Line's arrow instance variable to the string 'last'. For example, if hops_to_next_point is 1, then the picture is a regular polygon. Or, if hops_to_next_point is 2, the lines go: -- from point 0 to point 2 -- from point 1 to point 3 -- from point 2 to point 4 -- from point 3 to point 5 -- etc. One more example: if hops_to_next_point is 3 and number_of_segments is 5, then the lines go: -- from point 0 to point 3 -- from point 1 to point 4 -- from point 2 to point 0 (note the 'wrap' effect) -- from point 3 to point 1 -- from point 4 to point 2 Examples: See the 'fancy_polygon' pictures in the pizza.pdf file in this project. Type hints: :type window: rg.RoseWindow :type circle: rg.Circle :type number_of_lines: int :type hops_to_next_point: int :type color: str :type thickness: int """ circle.attach_to(window) window.render() points = generate_points_on_circle(circle, number_of_lines) for k in range(len(points)): line = rg.Line(points[k], points[(k + hops_to_next_point) % len(points)]) line.color = color line.thickness = thickness line.attach_to(window) window.render()
def problem3(point, circle1, circle2, window): """ See problem3_picture.pdf in this project for pictures that may help you better understand the following specification: What comes in: -- An rg.Point. -- Two rg.Circle objects (circle1 and circle2) -- An rg.RoseWindow. What goes out: Nothing (i.e., None). Side effects: Draws all the following on the given rg.RoseWindow: -- Draws the given rg.Point and rg.Circle objects. -- Then draws 3 rg.Lines: -- one from the given rg.Point to the center of circle1 -- one from the center of circle1 to the center of circle2 -- one from the center of circle2 to the given rg.Point where the color of each of those lines is the same color as the fill color of circle2. -- Then draws 3 more rg.Lines: -- one from the midpoint of the 1st line above to the midpoint of the 2nd line above -- one from the midpoint of the 2nd line above to the midpoint of the 3rd line above -- one from the midpoint of the 3rd line above to the midpoint of the 1st line above where the color of each of those lines is the same color as the fill color of circle2. Must render but ** NOT close ** the window. Type hints: :type point: rg.Point :type circle1: rg.Circle :type circle2: rg.Circle :type window: rg.RoseWindow """ # ------------------------------------------------------------------ # DONE: 2. Implement and test this function. # Tests have been written for you (above). # ------------------------------------------------------------------ point.attach_to(window) circle1.attach_to(window) circle2.attach_to(window) # first set of lines new_line1 = rg.Line(point, circle1.center) new_line1.color = circle1.fill_color new_line2 = rg.Line(circle1.center, circle2.center) new_line2.color = circle1.fill_color new_line3 = rg.Line(circle2.center, point) new_line3.color = circle1.fill_color new_line1.attach_to(window) new_line2.attach_to(window) new_line3.attach_to(window) # second set of lines new_line4 = rg.Line(new_line1.get_midpoint(), new_line2.get_midpoint()) new_line4.color = circle2.fill_color new_line5 = rg.Line(new_line2.get_midpoint(), new_line3.get_midpoint()) new_line5.color = circle2.fill_color new_line6 = rg.Line(new_line3.get_midpoint(), new_line1.get_midpoint()) new_line6.color = circle2.fill_color new_line4.attach_to(window) new_line5.attach_to(window) new_line6.attach_to(window) window.render()
def problem2a(circle, rectangle, window): """ See problem2a_picture.pdf in this project for pictures that may help you better understand the following specification: What comes in: -- An rg.Circle. -- An rg.Rectangle. -- An rg.RoseWindow. What goes out: Nothing (i.e., None). Side effects: -- Draws the given rg.Circle and rg.Rectangle on the given rg.RoseWindow, then waits for the user to click the window. -- Then draws an rg.Line from the upper-right corner of the rg.Rectangle to its lower-left corner, with the line drawn as an arrow, then waits for the user to click the window. -- Changes the fill color of the given rg.Circle to the outline color of the given rg.Rectangle, then renders the window again (with no waiting for a click from the user this time). Must ** NOT close ** the window. Type hints: :type circle: rg.Circle :type rectangle: rg.Rectangle :type window: rg.RoseWindow """ # ------------------------------------------------------------------ # DONE: 2. Implement and test this function. # Tests have been written for you (above). # ------------------------------------------------------------------ # ------------------------------------------------------------------ # DIFFICULTY AND TIME RATINGS (see top of this file for explanation) # DIFFICULTY: 6 # TIME ESTIMATE: 10 to 15 minutes. # ------------------------------------------------------------------ # window and initial display circle.attach_to(window) rectangle.attach_to(window) window.render() window.continue_on_mouse_click() # withdraw variables p1 = rectangle.get_upper_right_corner() p2 = rectangle.get_lower_left_corner() color_change = rectangle.outline_color # 1st click, draw arrow line = rg.Line(p1, p2) line.arrow = 'last' line.attach_to(window) window.render() window.continue_on_mouse_click() # 2nc click, change color circle.fill_color = color_change window.render()
def draw_lines_from_rectangles(rectangle1, rectangle2, n, window): """ What comes in: Four arguments: -- Two rg.Rectangles. -- A positive integer n. -- An rg.RoseWindow. What goes out: Nothing (i.e., None). Side effects: See draw_lines_from_rectangles.pdf in this project for pictures that may help you better understand the following specification: First draws the given rg.Rectangles on the given rg.RoseWindow. Then draws n rg.Lines on the given rg.RoseWindow, such that: -- The 1st rg.Line goes from the center of one of the 1st rg.Rectangle to the center of the 2nd rg.Rectangle. -- The 2nd rg.Line goes from the lower-left corner of the 1st rg.Rectangle and is parallel to the 1st rg.Line, with the same length and direction as the 1st rg.Line. -- Subsequent rg.Lines are shifted from the previous rg.Line in the same way that the 2nd rg.Line is shifted from the 1st. -- Each of the rg.Lines has thickness 5. -- The colors of the rg.Lines alternate, as follows: - The 1st, 3rd, 5th, ... rg.Line has color R1_color - The 2nd, 4th, 6th, ... rg.Line has color R2_color where - R1_color is the outline color of the 1st rg.Rectangle - R2_color is the outline color of the 2nd rg.Rectangle Must ** render ** but ** NOT close ** the window. Type hints: :type rectangle1: rg.Rectangle :type rectangle2: rg.Rectangle :type n: int :type window: rg.RoseWindow """ # ------------------------------------------------------------------------- # TODO: 5. Implement and test this function. # Tests have been written for you (above). # # CONSIDER using the ACCUMULATOR IN GRAPHICS pattern, # as in draw_row_of_circles in m1e, # instead of directly using the loop variable. # ########################################################################### # HINT: To figure out the code that computes the necessary # endpoints for each line, # ** FIRST DO A CONCRETE EXAMPLE BY HAND! ** ########################################################################### # ------------------------------------------------------------------------- rectangle1.attach_to(window) rectangle2.attach_to(window) #define useful variables #orient rectangle1 if rectangle1.corner_1.x < rectangle1.corner_2.x: left_x1 = rectangle1.corner_1.x right_x1 = rectangle1.corner_2.x else: left_x1 = rectangle1.corner_2.x right_x1 = rectangle1.corner_1.x if rectangle1.corner_1.y < rectangle1.corner_2.y: top_y1 = rectangle1.corner_1.y bottom_y1 = rectangle1.corner_2.y else: top_y1 = rectangle1.corner_2.y bottom_y1 = rectangle1.corner_1.y #orient rectangle2 if rectangle2.corner_1.x < rectangle2.corner_2.x: left_x2 = rectangle2.corner_1.x right_x2 = rectangle2.corner_2.x else: left_x2 = rectangle2.corner_2.x right_x2 = rectangle2.corner_1.x if rectangle2.corner_1.y < rectangle2.corner_2.y: top_y2 = rectangle2.corner_1.y bottom_y2 = rectangle2.corner_2.y else: top_y2 = rectangle2.corner_2.y bottom_y2 = rectangle2.corner_1.y #find center bottom_to_center1 = (bottom_y1 - top_y1) / 2 bottom_to_center2 = (bottom_y2 - top_y2) / 2 left_to_center1 = (right_x1 - left_x1) / 2 left_to_center2 = (right_x2 - left_x2) / 2 #consturct graphics for k in range(n): line_begin = rg.Point( (left_x1 + left_to_center1) - left_to_center1 * k, (bottom_y1 - bottom_to_center1) + bottom_to_center1 * k) line_end = rg.Point( (left_x2 + left_to_center2) - left_to_center1 * k, (bottom_y2 - bottom_to_center2) + bottom_to_center1 * k) line = rg.Line(line_begin, line_end) line.attach_to(window) line.thickness = 5 if k % 2 == 0: line.color = rectangle1.outline_color else: line.color = rectangle2.outline_color window.render()
def problem3b(m, point1): """ See problem3b_picture.pdf in this project for pictures that may help you better understand the following specification: What comes in: -- A positive integer m. -- An rg.Point. What goes out: -- Returns the sum of the thicknesses of ALL of the lines drawn (over all m sets of lines). Side effects: -- Constructs and displays an rg.RoseWindow that is 400 wide by 650 tall. -- Draws, on the rg.RoseWindow, m SETS of lines, where: -- Each SET of lines is drawn *** by a call to ** problem3a **. *** -- The first set has 3 lines that start at point1 (the given point). -- The second set has 5 lines that start 60 pixels directly below point1. -- The third set has 7 lines that start 120 pixels directly below point1. -- The fourth set has 9 lines that start 180 pixels directly below point1. -- etc until m SETS of lines are drawn (where m is given). -- Each set of lines should have widths (thicknesses) per problem3a. -- Waits for the user to click the mouse (and displays an appropriate message prompting the user to do so), then closes the window. Type hints: :type m: int :type point1: rg.Point """ # ------------------------------------------------------------------ # DONE: 4. Implement and test this function. # Tests have been written for you (above). # #################################################################### # IMPORTANT: # ** For full credit you must appropriately use (call) # ** the problem3a function that you implemented above. #################################################################### # ------------------------------------------------------------------ # DIFFICULTY AND TIME RATINGS (see top of this file for explanation) # DIFFICULTY: 8 or 9 # TIME ESTIMATE: 20 to 30 minutes. # ------------------------------------------------------------------ window = rg.RoseWindow(400, 650) thickness2 = 0 for k in range(m): x = point1.x y = point1.y + k * 60 for i in range(2 * (k + 1) + 1): point = rg.Point(x, y) endpoint = rg.Point(x, y + 50) line1 = rg.Line(point, endpoint) line1.thickness = 1 + 2 * i if line1.thickness >= 13: line1.thickness = 13 thickness2 = thickness2 + line1.thickness line1.attach_to(window) x = x + 20 y = y + 10 window.render() window.close_on_mouse_click() return thickness2
def draw_lines_from_rectangles(rectangle1, rectangle2, n, window): """ What comes in: Four arguments: -- Two rg.Rectangles. -- A positive integer n. -- An rg.RoseWindow. What goes out: Nothing (i.e., None). Side effects: See draw_lines_from_rectangles.pdf in this project for pictures that may help you better understand the following specification: First draws the given rg.Rectangles on the given rg.RoseWindow. Then draws n rg.Lines on the given rg.RoseWindow, such that: -- The 1st rg.Line goes from the center of one of the 1st rg.Rectangle to the center of the 2nd rg.Rectangle. -- The 2nd rg.Line goes from the lower-left corner of the 1st rg.Rectangle and is parallel to the 1st rg.Line, with the same length and direction as the 1st rg.Line. -- Subsequent rg.Lines are shifted from the previous rg.Line in the same way that the 2nd rg.Line is shifted from the 1st. -- Each of the rg.Lines has thickness 5. -- The colors of the rg.Lines alternate, as follows: - The 1st, 3rd, 5th, ... rg.Line has color R1_color - The 2nd, 4th, 6th, ... rg.Line has color R2_color where - R1_color is the outline color of the 1st rg.Rectangle - R2_color is the outline color of the 2nd rg.Rectangle Must ** render ** but ** NOT close ** the window. Type hints: :type rectangle1: rg.Rectangle :type rectangle2: rg.Rectangle :type n: int :type window: rg.RoseWindow """ rectangle1.attach_to(window) rectangle2.attach_to(window) window.render() counter = 1 for k in range(n): r1height = rectangle1.get_height() r1width = rectangle1.get_width() r1cent = rectangle1.get_center() r2cent = rectangle2.get_center() leftpoint = rg.Point(r1cent.x - r1width / 2 * k, r1cent.y + r1height / 2 * k) rightpoint = rg.Point(r2cent.x - r1width / 2 * k, r2cent.y + r1height / 2 * k) line = rg.Line(leftpoint, rightpoint) if counter % 2 == 0: counter = counter + 1 line.color = rectangle2.outline_color else: counter = counter + 1 line.color = rectangle1.outline_color line.thickness = 5 line.attach_to(window) window.render()
def draw_lines_from_rectangles(rectangle1, rectangle2, n, window): """ What comes in: Four arguments: -- Two rg.Rectangles. -- A positive integer n. -- An rg.RoseWindow. What goes out: Nothing (i.e., None). Side effects: See draw_lines_from_rectangles.pdf in this project for pictures that may help you better understand the following specification: First draws the given rg.Rectangles on the given rg.RoseWindow. Then draws n rg.Lines on the given rg.RoseWindow, such that: -- The 1st rg.Line goes from the center of one of the 1st rg.Rectangle to the center of the 2nd rg.Rectangle. -- The 2nd rg.Line goes from the lower-left corner of the 1st rg.Rectangle and is parallel to the 1st rg.Line, with the same length and direction as the 1st rg.Line. -- Subsequent rg.Lines are shifted from the previous rg.Line in the same way that the 2nd rg.Line is shifted from the 1st. -- Each of the rg.Lines has thickness 5. -- The colors of the rg.Lines alternate, as follows: - The 1st, 3rd, 5th, ... rg.Line has color R1_color - The 2nd, 4th, 6th, ... rg.Line has color R2_color where - R1_color is the outline color of the 1st rg.Rectangle - R2_color is the outline color of the 2nd rg.Rectangle Must ** render ** but ** NOT close ** the window. Type hints: :type rectangle1: rg.Rectangle :type rectangle2: rg.Rectangle :type n: int :type window: rg.RoseWindow """ # ------------------------------------------------------------------------- # done9: 5. Implement and test this function. # Tests have been written for you (above). # # CONSIDER using the ACCUMULATOR IN GRAPHICS pattern, # as in draw_row_of_circles in m1e, # instead of directly using the loop variable. # ########################################################################### # HINT: To figure out the code that computes the necessary # endpoints for each line, # ** FIRST DO A CONCRETE EXAMPLE BY HAND! ** ########################################################################### # ------------------------------------------------------------------------- rectangle1.attach_to(window) rectangle2.attach_to(window) x1 = rectangle1.corner_1.x x2 = rectangle1.corner_2.x y1 = rectangle1.corner_1.y y2 = rectangle1.corner_2.y xm = (x2 - x1) / 2 ym = (y2 - y1) / 2 center1 = (rg.Point((xm + x1), (ym + y1))) xn1 = rectangle2.corner_1.x xn2 = rectangle2.corner_2.x yn1 = rectangle2.corner_1.y yn2 = rectangle2.corner_2.y xnm = (xn2 - xn1) / 2 ynm = (yn2 - yn1) / 2 center2 = rg.Point((xnm + xn1), (yn1 + ynm)) line1 = rg.Line(center1, center2) line1.thickness = 5 line1.attach_to(window) for k in range(n): start = rg.Point(center1.x, center1.y) end = rg.Point(center2.x, center2.y) newcenter1 = rg.Point((start.x - abs(k * xm)), (start.y + abs(k * ym))) newcenter2 = rg.Point((end.x - abs(k * xm)), (end.y + abs(k * ym))) newline = rg.Line(newcenter1, newcenter2) newline.thickness = 5 if k % 2 != 0: newline.color = rectangle2.outline_color else: newline.color = rectangle1.outline_color newline.attach_to(window) window.render(1)
def hourglass(window, n, point, radius, color): """ See hourglass_picture.pdf in this project for pictures that may help you better understand the following specification: Displays an "hourglass" shape of circles in the given window. -- Each circle has the given radius and given color. -- Each circle has a horizontal line drawn through it. -- The middlemost of the circles is centered at the given point. -- There is a single circle in that middlemost row. -- There are n rows (including the middlemost row) of circles going UP from the middlemost circle. -- There are n rows (including the middlemost row) of circles going DOWN from the middlemost circle. -- Each circle barely touches its neighbor circles. Preconditions: :type window: rg.RoseWindow :type n: int :type point: rg.Point :type radius: int :type color: str where n and radius are positive and color is a string that denotes a color that rosegraphics understands. """ # ------------------------------------------------------------------ # DONE: 2. Implement and test this function. # We provided some tests for you (above). # ------------------------------------------------------------------ #################################################################### # BONUS: Avoid replicated code if you can. Hint: You are allowed # to define an additional function(s) if you wish. #################################################################### # ------------------------------------------------------------------ # DIFFICULTY AND TIME RATINGS (see top of this file for explanation) # DIFFICULTY: 8 # TIME ESTIMATE: 25 minutes (warning: this problem is challenging) # ------------------------------------------------------------------ o_x = point.x o_y = point.y x1 = point.x y1 = point.y x2 = point.x y2 = point.y for i in range(n): for j in range(i + 1): circle = rg.Circle(rg.Point(x1, y1), radius) line = rg.Line(rg.Point(x1 - radius, y1), rg.Point(x1 + radius, y1)) circle.fill_color = color circle.attach_to(window) line.attach_to(window) window.render() x1 += 2 * radius y1 -= math.sqrt(3) * radius x1 = o_x - radius * (i + 1) for j in range(i + 1): circle = rg.Circle(rg.Point(x2, y2), radius) line = rg.Line(rg.Point(x2 - radius, y2), rg.Point(x2 + radius, y2)) circle.fill_color = color circle.attach_to(window) line.attach_to(window) window.render() x2 -= 2 * radius y2 += math.sqrt(3) * radius x2 = o_x + radius * (i + 1)
def problem1(square, thickness, window): """ See problem1_picture.pdf in this project for pictures that may help you better understand the following specification: What comes in: -- An rg.Square. -- A positive integer -- An rg.RoseWindow. What goes out: Nothing (i.e., None). Side effects: -- Draws, on the given rg.RoseWindow: -- The given rg.Square. -- An rg.Circle that: -- is directly below and touching the given rg.Square, -- has diameter the same as the length of each side of the given rg.Square, -- has fill color the same as the fill color of the given rg.Square, and -- has the given thickness as its outline thickness. (SEE THE PICTURES.) -- An rg.Line that: -- has one endpoint is at the center of the above rg.Circle, -- has another endpoint that is at the midpoint of the left side of the given rg.Square, -- has color the same as the outline color of the given rg.Square, and -- has the given thickness. (SEE THE PICTURES.) Note: Attach the rg.Line AFTER attaching the rg.Square and rg.Circle. Must render but ** NOT close ** the window. Type hints: :type square: rg.Square :type thickness: int :type window: rg.RoseWindow """ # ------------------------------------------------------------------------- # Done: 3. Implement and test this function. SEE THE PICTURES in the PDF! # Tests have been written for you (above). # ------------------------------------------------------------------------- square.attach_to(window) x1 = square.center.x y1 = square.center.y + square.length_of_each_side p1 = rg.Point(x1, y1) circle = rg.Circle(p1, (0.5 * square.length_of_each_side)) circle.fill_color = square.fill_color circle.outline_thickness = thickness circle.attach_to(window) x2 = square.center.x - (0.5 * square.length_of_each_side) y2 = square.center.y p2 = rg.Point(x2, y2) line = rg.Line(p1,p2) line.color = square.outline_color line.thickness = thickness line.attach_to(window) window.render()
def draw_lines_from_rectangles(rectangle1, rectangle2, n, window): """ What comes in: Four arguments: -- Two rg.Rectangles. -- A positive integer n. -- An rg.RoseWindow. What goes out: Nothing (i.e., None). Side effects: See draw_lines_from_rectangles.pdf in this project for pictures that may help you better understand the following specification: First draws the given rg.Rectangles on the given rg.RoseWindow. Then draws n rg.Lines on the given rg.RoseWindow, such that: -- The 1st rg.Line goes from the center of one of the 1st rg.Rectangle to the center of the 2nd rg.Rectangle. -- The 2nd rg.Line goes from the lower-left corner of the 1st rg.Rectangle and is parallel to the 1st rg.Line, with the same length and direction as the 1st rg.Line. -- Subsequent rg.Lines are shifted from the previous rg.Line in the same way that the 2nd rg.Line is shifted from the 1st. -- Each of the rg.Lines has thickness 5. -- The colors of the rg.Lines alternate, as follows: - The 1st, 3rd, 5th, ... rg.Line has color R1_color - The 2nd, 4th, 6th, ... rg.Line has color R2_color where - R1_color is the outline color of the 1st rg.Rectangle - R2_color is the outline color of the 2nd rg.Rectangle Must ** render ** but ** NOT close ** the window. Type hints: :type rectangle1: rg.Rectangle :type rectangle2: rg.Rectangle :type n: int :type window: rg.RoseWindow """ # ------------------------------------------------------------------------- # Done: 5. Implement and test this function. # Tests have been written for you (above). # # CONSIDER using the ACCUMULATOR IN GRAPHICS pattern, # as in draw_row_of_circles in m1e, # instead of directly using the loop variable. # ########################################################################### # HINT: To figure out the code that computes the necessary # endpoints for each line, # ** FIRST DO A CONCRETE EXAMPLE BY HAND! ** ########################################################################### # ------------------------------------------------------------------------- import math rectangle1.attach_to(window) rectangle2.attach_to(window) center_of_rec1_x = math.fabs( (rectangle1.corner_1.x + rectangle1.corner_2.x)) / 2 center_of_rec1_y = math.fabs( (rectangle1.corner_1.y + rectangle1.corner_2.y)) / 2 center_of_rec2_x = math.fabs( (rectangle2.corner_1.x + rectangle2.corner_2.x)) / 2 center_of_rec2_y = math.fabs( (rectangle2.corner_1.y + rectangle2.corner_2.y)) / 2 rec1_width = math.fabs(rectangle1.corner_1.x - rectangle1.corner_2.x) rec1_height = math.fabs(rectangle1.corner_1.y - rectangle1.corner_2.y) count = 0 start_x = center_of_rec1_x start_y = center_of_rec1_y end_x = center_of_rec2_x end_y = center_of_rec2_y for _ in range(n): if count % 2 == 0: color = rectangle1.outline_color else: color = rectangle2.outline_color line = rg.Line(rg.Point(start_x, start_y), rg.Point(end_x, end_y)) line.color = color line.thickness = 5 line.attach_to(window) count = count + 1 start_x = start_x - rec1_width / 2 start_y = start_y + rec1_height / 2 end_x = end_x - rec1_width / 2 end_y = end_y + rec1_height / 2 window.render()
def problem1(circle, rectangle, color, length, window): """ See problem1_picture.pdf in this project for pictures that may help you better understand the following specification: What comes in: -- An rg.Circle. -- An rg.Rectangle -- A string that represents a Rosegraphics color -- A positive integer -- An rg.RoseWindow. What goes out: Nothing (i.e., None) Side effects: -- Draws, on the given rg.RoseWindow, in the following order: -- The given rg.Circle. -- The given rg.Rectangle -- An rg.Line from the center of the given rg.Circle to the center of the given rg.Rectangle, such that: -- The rg.Line has the given color -- The rg.Line has thickness the same as the outline thickness of the given rg.Circle. (SEE THE PICTURES.) -- A vertical rg.Line whose: -- midpoint is the midpoint of the above rg.Line, -- length is the given length, -- color is the fill color of the given rg.Circle, and -- thickness is the sum of the thicknesses of the given rg.Circle and rg.Rectangle. (SEE THE PICTURES.) Note: Attach the rg.Line AFTER attaching the rg.Circle and rg.Rectangle. Must render but ** NOT close ** the window. Type hints: :type circle: rg.Circle :type rectangle: rg.Rectangle :type color: str :type length: int :type window: rg.RoseWindow """ # ------------------------------------------------------------------------- # DONE: 3. Implement and test this function. SEE THE PICTURES in the PDF! # Tests have been written for you (above). # ------------------------------------------------------------------------- circle.attach_to(window) window.render() rectangle.attach_to(window) window.render() line = rg.Line(circle.center, rectangle.get_center()) line.color = color line.thickness = circle.outline_thickness line.attach_to(window) window.render() midpoint = line.get_midpoint() half = length / 2 vertical = rg.Line(rg.Point(midpoint.x, midpoint.y - half), rg.Point(midpoint.x, midpoint.y + half)) vertical.color = circle.fill_color vertical.thickness = circle.outline_thickness + rectangle.outline_thickness vertical.attach_to(window) window.render()
def problem3(point, circle1, circle2, window): """ See problem3_picture.pdf in this project for pictures that may help you better understand the following specification: What comes in: -- An rg.Point. -- Two rg.Circle objects (circle1 and circle2) -- An rg.RoseWindow. What goes out: Nothing (i.e., None). Side effects: Draws all the following on the given rg.RoseWindow: -- Draws the given rg.Point and rg.Circle objects. -- Then draws 3 rg.Lines: -- one from the given rg.Point to the center of circle1 -- one from the center of circle1 to the center of circle2 -- one from the center of circle2 to the given rg.Point where the color of each of those lines is the same color as the fill color of circle2. -- Then draws 3 more rg.Lines: -- one from the midpoint of the 1st line above to the midpoint of the 2nd line above -- one from the midpoint of the 2nd line above to the midpoint of the 3rd line above -- one from the midpoint of the 3rd line above to the midpoint of the 1st line above where the color of each of those lines is the same color as the fill color of circle2. Must render but ** NOT close ** the window. Type hints: :type point: rg.Point :type circle1: rg.Circle :type circle2: rg.Circle :type window: rg.RoseWindow """ point.attach_to(window) circle1.attach_to(window) circle2.attach_to(window) line1 = rg.Line(point, circle1.center) line2 = rg.Line(circle1.center, circle2.center) line3 = rg.Line(circle2.center, point) line1.color = circle1.fill_color line2.color = circle1.fill_color line3.color = circle1.fill_color line1.attach_to(window) line2.attach_to(window) line3.attach_to(window) midpoint1 = rg.Point((line1.start.x + line1.end.x) / 2, (line1.start.y + line1.end.y) / 2) midpoint2 = rg.Point((line2.start.x + line2.end.x) / 2, (line2.start.y + line2.end.y) / 2) midpoint3 = rg.Point((line3.start.x + line3.end.x) / 2, (line3.start.y + line3.end.y) / 2) midline1 = rg.Line(midpoint1, midpoint2) midline2 = rg.Line(midpoint2, midpoint3) midline3 = rg.Line(midpoint3, midpoint1) midline1.color = circle2.fill_color midline2.color = circle2.fill_color midline3.color = circle2.fill_color midline1.attach_to(window) midline2.attach_to(window) midline3.attach_to(window) window.render()
def lines(): """ -- Constructs a rg.RoseWindow. -- Constructs and draws on the window two rg.Lines such that: -- They both fit in the window and are easily visible. -- One rg.Line has the default thickness. -- The other rg.Line is thicker (i.e., has a bigger width). -- Uses a rg.Line method to get the midpoint (center) of the thicker rg.Line. -- Then prints (on the console, on SEPARATE lines): -- the midpoint itself -- the x-coordinate of the midpoint -- the y-coordinate of the midpoint Here is an example of the output on the console, if the two endpoints of the thicker line are at (100, 100) and (121, 200): Point(110.5, 150.0) 110.5 150.0 -- Waits for the user to press the mouse, then closes the window. """ # ------------------------------------------------------------------ # DONE: 4. Implement and test this function. # ------------------------------------------------------------------ # ------------------------------------------------------------------ # RoseWindow: optionally takes its width and height. # ------------------------------------------------------------------ width = 500 height = 500 window = rg.RoseWindow(width, height) # ------------------------------------------------------------------ # line: needs # ------------------------------------------------------------------ point1 = rg.Point(100, 150) point2 = rg.Point(200, 50) line = rg.Line(point1, point2) line.attach_to(window) # ------------------------------------------------------------------ # line: needs # ------------------------------------------------------------------ point1 = rg.Point(300, 250) point2 = rg.Point(200, 200) line2 = rg.Line(point1, point2) line2.thickness = 3 line2.attach_to(window) midpoint_2 = line2.get_midpoint() x_coor = midpoint_2.x y_coor = midpoint_2.y print(midpoint_2) print(x_coor) print(y_coor) # ------------------------------------------------------------------ # render: Draw ALL the objects attached to this window. # ------------------------------------------------------------------ window.render() # ------------------------------------------------------------------ # close_on_mouse_click: Keeps the window open until user clicks. # ------------------------------------------------------------------ window.close_on_mouse_click()
def hourglass(window, n, point, radius, color): """ See hourglass_picture.pdf in this project for pictures that may help you better understand the following specification: Displays an "hourglass" shape of circles in the given window. -- Each circle has the given radius and given color. -- Each circle has a horizontal line drawn through it. -- The middlemost of the circles is centered at the given point. -- There is a single circle in that middlemost row. -- There are n rows (including the middlemost row) of circles going UP from the middlemost circle. -- There are n rows (including the middlemost row) of circles going DOWN from the middlemost circle. -- Each circle barely touches its neighbor circles. Preconditions: :type window: rg.RoseWindow :type n: int :type point: rg.Point :type radius: int :type color: str where n and radius are positive and color is a string that denotes a color that rosegraphics understands. """ # ------------------------------------------------------------------ # Done: 2. Implement and test this function. # We provided some tests for you (above). # ------------------------------------------------------------------ #################################################################### # BONUS: Avoid replicated code if you can. Hint: You are allowed # to define an additional function(s) if you wish. #################################################################### # ------------------------------------------------------------------ # DIFFICULTY AND TIME RATINGS (see top of this file for explanation) # DIFFICULTY: 8 # TIME ESTIMATE: 25 minutes (warning: this problem is challenging) # ------------------------------------------------------------------ circle = rg.Circle(point, radius) x_org = circle.center.x center_y_up = circle.center.y center_y_down = circle.center.y for k in range(n): center_x_up = x_org - radius * k center_x_down = x_org - radius * k for j in range(k + 1): circle_up = rg.Circle(rg.Point(center_x_up, center_y_up), radius) circle_up.fill_color = color circle_up.attach_to(window) line_up = rg.Line(rg.Point(center_x_up - radius, center_y_up), rg.Point( center_x_up + radius, center_y_up)) line_up.attach_to(window) circle_down = rg.Circle(rg.Point(center_x_down, center_y_down), radius) circle_down.fill_color = color circle_down.attach_to(window) line_low = rg.Line(rg.Point(center_x_down - radius, center_y_down), rg.Point( center_x_down + radius, center_y_down)) line_low.attach_to(window) center_x_down = center_x_down + 2 * radius center_x_up = center_x_up + 2 * radius center_y_up = center_y_up - radius * 1.75 center_y_down = center_y_down + radius * 1.75 window.render()
def hourglass(window, n, point, radius, color): """ See hourglass_picture.pdf in this project for pictures that may help you better understand the following specification: Displays an "hourglass" shape of circles in the given window. -- Each circle has the given radius and given color. -- Each circle has a horizontal line drawn through it. -- The middlemost of the circles is centered at the given point. -- There is a single circle in that middlemost row. -- There are n rows (including the middlemost row) of circles going UP from the middlemost circle. -- There are n rows (including the middlemost row) of circles going DOWN from the middlemost circle. -- Each circle barely touches its neighbor circles. Preconditions: :type window: rg.RoseWindow :type n: int :type point: rg.Point :type radius: int :type color: str where n and radius are positive and color is a string that denotes a color that rosegraphics understands. """ # ------------------------------------------------------------------ # Done: 2. Implement and test this function. # We provided some tests for you (above). # ------------------------------------------------------------------ #################################################################### # BONUS: Avoid replicated code if you can. Hint: You are allowed # to define an additional function(s) if you wish. #################################################################### # ------------------------------------------------------------------ # DIFFICULTY AND TIME RATINGS (see top of this file for explanation) # DIFFICULTY: 8 # TIME ESTIMATE: 25 minutes (warning: this problem is challenging) # ------------------------------------------------------------------ shift_x1 = radius shift_y1 = radius*(3)**.5 shift_x2 = 2*radius for k in range(n): circlea = rg.Circle(rg.Point(point.x + shift_x1 * (k), point.y + shift_y1 * (k)), radius) circlea.fill_color = color circlea.attach_to(window) circleb = rg.Circle(rg.Point(point.x - shift_x1 * (k), point.y - shift_y1 * (k)), radius) circleb.fill_color = color circleb.attach_to(window) for j in range(k+1): circle1 = rg.Circle(rg.Point(circlea.center.x - shift_x2*(j), circlea.center.y), radius) circle1.fill_color = color circle1.attach_to(window) line1 = rg.Line(rg.Point(circle1.center.x - shift_x2/2,circlea.center.y),rg.Point(circle1.center.x + shift_x2/2,circlea.center.y)) line1.attach_to(window) circle2 = rg.Circle(rg.Point(circleb.center.x +shift_x2*j,circleb.center.y),radius) circle2.fill_color = color circle2.attach_to(window) line1 = rg.Line(rg.Point(circle2.center.x - shift_x2 / 2, circleb.center.y), rg.Point(circle2.center.x + shift_x2 / 2, circleb.center.y)) line1.attach_to(window) window.render()
def problem2a(circle, rectangle, window): """ See problem2a_picture.pdf in this project for pictures that may help you better understand the following specification: What comes in: -- An rg.Circle. -- An rg.Rectangle. -- An rg.RoseWindow. What goes out: Nothing (i.e., None). Side effects: -- Draws the given rg.Circle and rg.Rectangle on the given rg.RoseWindow, then waits for the user to click the window. -- Then draws an rg.Line from the upper-right corner of the rg.Rectangle to its lower-left corner, with the line drawn as an arrow, then waits for the user to click the window. -- Changes the fill color of the given rg.Circle to the outline color of the given rg.Rectangle, then renders the window again (with no waiting for a click from the user this time). Must ** NOT close ** the window. Type hints: :type circle: rg.Circle :type rectangle: rg.Rectangle :type window: rg.RoseWindow """ # ------------------------------------------------------------------ # TODO: 2. Implement and test this function. # Tests have been written for you (above). # ------------------------------------------------------------------ # ------------------------------------------------------------------ # DIFFICULTY AND TIME RATINGS (see top of this file for explanation) # DIFFICULTY: 6 # TIME ESTIMATE: 10 to 15 minutes. # ------------------------------------------------------------------ circle.attach_to(window) rectangle.attach_to(window) window.continue_on_mouse_click() start = rg.Point(0, 0) end = rg.Point(0, 0) start.y = min(rectangle.corner_1.y, rectangle.corner_2.y) start.x = max(rectangle.corner_1.x, rectangle.corner_2.x) end.y = max(rectangle.corner_1.y, rectangle.corner_2.y) end.x = min(rectangle.corner_1.x, rectangle.corner_2.x) line = rg.Line(start, end) line.arrow = 'last' line.attach_to(window) window.continue_on_mouse_click() circle.fill_color = rectangle.outline_color window.render()
-- the x-coordinate of the midpoint -- the y-coordinate of the midpoint Here is an example of the output on the console, if the two endpoints of the thicker line are at (100, 100) and (121, 200): Point(110.5, 150.0) 110.5 150.0 -- Waits for the user to press the mouse, then closes the window. """ # DONE: 4. Implement and test this function. window = rg.RoseWindow() line1 = rg.Line(rg.Point(50, 50), rg.Point(350, 50)) line2 = rg.Line(rg.Point(100, 100), rg.Point(121, 200)) line2.thickness = 20 line1.attach_to(window) line2.attach_to(window) m = line2.get_midpoint() print(m) print(m.x) print(m.y) window.render() window.close_on_mouse_click() # ----------------------------------------------------------------------------- # Calls main to start the ball rolling. # -----------------------------------------------------------------------------
def problem3a(window, point, n): """ See problem3a_picture.pdf in this project for pictures that may help you better understand the following specification: What comes in: -- An rg.RoseWindow. -- An rg.Point. -- A nonnegative integer n. What goes out: -- Returns the sum of the thicknesses of the rg.Lines that are drawn as described in the Side effects (below). Side effects: Draws n rg.Lines on the given rg.RoseWindow, as follows: -- There are the given number (n) of rg.Lines. -- Each rg.Line is vertical and has length 50. (All units are pixels.) -- The top of the first (leftmost) rg.Line is at the given rg.Point. -- Each successive rg.Line is 20 pixels to the right and 10 pixels down from the previous rg.Line. -- The first rg.Line has thickness 1. -- Each successive rg.Line has thickness 2 greater than the rg.Line to its left, but no greater than 13. (So once a rg.Line has thickness 13, it and all the rg.Lines to its right have thickness 13.) Type hints: :type window: rg.RoseWindow :type point: rg.Point :type n: int """ # ------------------------------------------------------------------ # Done: 3. Implement and test this function. # Note that you should write its TEST function first (above). # ------------------------------------------------------------------ # ------------------------------------------------------------------ # DIFFICULTY AND TIME RATINGS (see top of this file for explanation) # DIFFICULTY: 7 or 8 # TIME ESTIMATE: 20 to 35 minutes. # ------------------------------------------------------------------ changex = 20 changey = 10 thickness = 1 count = 0 for k in range(n): point = rg.Point(point.x, point.y) end = rg.Point(point.x, point.y + 50) line1 = rg.Line(point, end) line1.thickness = thickness if thickness >= 13: thickness = 13 line1.attach_to(window) point.x = point.x + changex point.y = point.y + changey end.x = end.x + changex end.y = end.x + changey window.render() count = count + thickness thickness = thickness + 2 return count
def hourglass(window, n, point, radius, color): """ See hourglass_picture.pdf in this project for pictures that may help you better understand the following specification: Displays an "hourglass" shape of circles in the given window. -- Each circle has the given radius and given color. -- Each circle has a horizontal line drawn through it. -- The middlemost of the circles is centered at the given point. -- There is a single circle in that middlemost row. -- There are n rows (including the middlemost row) of circles going UP from the middlemost circle. -- There are n rows (including the middlemost row) of circles going DOWN from the middlemost circle. -- Each circle barely touches its neighbor circles. Preconditions: :type window: rg.RoseWindow :type n: int :type point: rg.Point :type radius: int :type color: str where n and radius are positive and color is a string that denotes a color that rosegraphics understands. """ # ------------------------------------------------------------------ # DONE: 2. Implement and test this function. # We provided some tests for you (above). # ------------------------------------------------------------------ #################################################################### # BONUS: Avoid replicated code if you can. Hint: You are allowed # to define an additional function(s) if you wish. #################################################################### # ------------------------------------------------------------------ # DIFFICULTY AND TIME RATINGS (see top of this file for explanation) # DIFFICULTY: 8 # TIME ESTIMATE: 25 minutes (warning: this problem is challenging) # ------------------------------------------------------------------ og_point = point up_point = rg.Point(og_point.x, og_point.y) down_point = rg.Point(og_point.x, og_point.y) hypt = (2 * radius) ** 2 x_length = radius ** 2 y_distance = math.sqrt(hypt - x_length) x_distance = radius * 2 for k in range(n): for i in range(k + 1): circle_up = rg.Circle(up_point, radius) circle_up.fill_color = color circle_up.attach_to(window) circle_down = rg.Circle(down_point, radius) circle_down.fill_color = color circle_down.attach_to(window) line_up = rg.Line(rg.Point(up_point.x - radius, up_point.y), rg.Point(up_point.x + radius, up_point.y)) line_up.attach_to(window) line_down = rg.Line(rg.Point(down_point.x - radius, down_point.y), rg.Point(down_point.x + radius, down_point.y)) line_down.attach_to(window) window.render() up_point.x = up_point.x + x_distance down_point.x = down_point.x + x_distance up_point.x = og_point.x - (radius * (k + 1)) down_point.x = og_point.x - (radius * (k + 1)) up_point.y -= y_distance down_point.y += y_distance
def draw_lines_from_rectangles(rectangle1, rectangle2, n, window): """ What comes in: Four arguments: -- Two rg.Rectangles. -- A positive integer n. -- An rg.RoseWindow. What goes out: Nothing (i.e., None). Side effects: See draw_lines_from_rectangles.pdf in this project for pictures that may help you better understand the following specification: First draws the given rg.Rectangles on the given rg.RoseWindow. Then draws n rg.Lines on the given rg.RoseWindow, such that: -- The 1st rg.Line goes from the center of one of the 1st rg.Rectangle to the center of the 2nd rg.Rectangle. -- The 2nd rg.Line goes from the lower-left corner of the 1st rg.Rectangle and is parallel to the 1st rg.Line, with the same length and direction as the 1st rg.Line. -- Subsequent rg.Lines are shifted from the previous rg.Line in the same way that the 2nd rg.Line is shifted from the 1st. -- Each of the rg.Lines has thickness 5. -- The colors of the rg.Lines alternate, as follows: - The 1st, 3rd, 5th, ... rg.Line has color R1_color - The 2nd, 4th, 6th, ... rg.Line has color R2_color where - R1_color is the outline color of the 1st rg.Rectangle - R2_color is the outline color of the 2nd rg.Rectangle Must ** render ** but ** NOT close ** the window. Type hints: :type rectangle1: rg.Rectangle :type rectangle2: rg.Rectangle :type n: int :type window: rg.RoseWindow """ rectangle1.attach_to(window) rectangle2.attach_to(window) upper_left1 = rectangle1.corner_1 lower_right1 = rectangle1.corner_2 lower_left1 = rg.Point(rectangle1.corner_1.x, rectangle1.corner_2.y) center1 = rg.Point(((lower_right1.x - lower_left1.x) / 2) + lower_left1.x, ((lower_right1.y - upper_left1.y) / 2) + upper_left1.y) upper_left2 = rectangle2.corner_1 lower_right2 = rectangle2.corner_2 lower_left2 = rg.Point(upper_left2.x, lower_right2.y) center2 = rg.Point(((lower_right2.x - lower_left2.x) / 2) + lower_left2.x, ((lower_right2.y - upper_left2.y) / 2) + upper_left2.y) line = rg.Line(center1, center2) line.color = rectangle1.outline_color line.thickness = 5 line.attach_to(window) change_x = abs((lower_right1.x - lower_left1.x) / 2) change_y = abs((lower_right1.y - upper_left1.y) / 2) for k in range(n - 1): center1.x = center1.x - change_x center1.y = center1.y + change_y center2.x = center2.x - change_x center2.y = center2.y + change_y line = rg.Line(center2, center1) if k % 2 == 0: line.color = rectangle2.outline_color else: line.color = rectangle1.outline_color line.thickness = 5 line.attach_to(window) window.render() window.render()
def draw_lines(n, point, window): """ What comes in: The three arguments are: -- A integer n that is at least 2. -- An rg.Point. -- An rg.RoseWindow. What goes out: Nothing (i.e., None). Side effects: See draw_lines.pdf in this project for pictures that may help you better understand the following specification: Draws n rg.Lines on the given rg.RoseWindow, such that: -- The leftmost point of each of the rg.Lines is the given rg.Point. -- For the rightmost point of each of the lines: -- Its x-coordinate is (pX + 100), where pX is the x-coordinate of the given rg.Point. -- The y-coordinates of the lines vary evenly from (pY - 100) to (pY + 100), where pY is the y-coordinate of the given rg.Point. Must ** render ** but ** NOT close ** the window. Type hints: :type n: int :type point: rg.Point :type window: rg.RoseWindow """ # ------------------------------------------------------------------ # DONE: 3. Implement and test this function. # Tests have been written for you (above). # # CONSIDER using the ACCUMULATOR IN GRAPHICS pattern, # as in draw_row_of_circles in m1e, # instead of directly using the loop variable. # #################################################################### # HINT: To figure out the code that computes the necessary # endpoints for each line, # ** FIRST DO A CONCRETE EXAMPLE BY HAND! ** #################################################################### # ------------------------------------------------------------------ x = point.x # Initialize x and y BEFORE the loop y = point.y # Choose values that make the FIRST object easy to draw for _ in range(n): # Loop that does NOT use its index variable # -------------------------------------------------------------- # Construct the relevant object(s), # based on the current x, y and other variables. # -------------------------------------------------------------- end = rg.Point(x+100, y-100) line = rg.Line(point, end) # Attach the object(s) to the window. line.attach_to(window) # -------------------------------------------------------------- # Increment x (and in other problems, other variables) # for the thing(s) to draw in the NEXT iteration of the loop. # -------------------------------------------------------------- y = y + 200/(n-1) window.render()
def fancy_polygon(window, circle, number_of_lines, hops_to_next_point, color, thickness): """ What comes in: -- an rg.RoseWindow -- an rg.Circle -- an integer >= 2 that specifies how many rg.Lines to generate as described below -- a positive integer that specifies how many points each line "hops" over (see below for details). -- a string that can be used as a RoseGraphics color -- a positive integer that specifies the thickness to be used for each rg.Line What goes out: Nothing (i.e., None). Side effects: See the 'fancy_polygon' pictures in the pizza.pdf file in this project; they may help you better understand the following: 1. Draws the given rg.Circle in the given rg.RoseWindow. 2. Constructs and draws rg.Line objects to make the picture look like an inscribed regular polygon with the given number of segments, but with each rg.Line going from one point on the given rg.Circle to the point on the given rg.Circle that is the given number of 'hops' away (wrapping as needed). Each rg.Line has the given color and thickness. Each rg.Line should be drawn as an arrow, by setting the rg.Line's arrow instance variable to the string 'last'. For example, if hops_to_next_point is 1, then the picture is a regular polygon. Or, if hops_to_next_point is 2, the lines go: -- from point 0 to point 2 -- from point 1 to point 3 -- from point 2 to point 4 -- from point 3 to point 5 -- etc. One more example: if hops_to_next_point is 3 and number_of_segments is 5, then the lines go: -- from point 0 to point 3 -- from point 1 to point 4 -- from point 2 to point 0 (note the 'wrap' effect) -- from point 3 to point 1 -- from point 4 to point 2 Examples: See the 'fancy_polygon' pictures in the pizza.pdf file in this project. Type hints: :type window: rg.RoseWindow :type circle: rg.Circle :type number_of_lines: int :type hops_to_next_point: int :type color: str :type thickness: int """ # ------------------------------------------------------------------ # DONE: 10. Implement and test this function. # Note that you should write its TEST function first (above). # # IMPLEMENTATION REQUIREMENT: # You MUST USE (call) the generate_points_on_circle # (defined above) to generate the relevant points, # and then draw lines that are based in part on those points. # #################################################################### # IMPORTANT: One way to do "wrapping" is to use the % operator # appropriately. ASK YOUR INSTRUCTOR FOR AN EXAMPLE. #################################################################### # ------------------------------------------------------------------ circle.attach_to(window) points = generate_points_on_circle(circle,number_of_lines) for i in range(len(points)): if i+hops_to_next_point >= len(points): somemath = i+hops_to_next_point - len(points) new_line = rg.Line(points[i],points[(somemath)]) new_line.attach_to(window) else: new_line = rg.Line(points[i],points[i+hops_to_next_point]) new_line.attach_to(window) new_line.color = color new_line.thickness = thickness window.render()
def draw_parallel_lines(n, point, length, window): """ What comes in: The four arguments are: -- A positive integer n. -- An rg.Point. -- A positive integer length. -- An rg.RoseWindow. What goes out: Nothing (i.e., None). Side effects: See draw_parallel_lines.pdf in this project for pictures that may help you better understand the following specification: Draws n rg.Lines parallel to each other, all on the given rg.RoseWindow, such that: -- The first rg.Line has its left-most end at the given rg.Point. -- Each rg.Line is a horizontal line (i.e., parallel to the x-axis). -- Each rg.Line has the given length. -- Each rg.Line is 30 pixels below the previous rg.Line. Must ** render ** but ** NOT close ** the window. Type hints: :type n: int :type point: rg.Point :type length: int :type window: rg.RoseWindow """ # ------------------------------------------------------------------ # DONE: 2. Implement and test this function. # Tests have been written for you (above). # # CONSIDER using the ACCUMULATOR IN GRAPHICS pattern, # as in draw_row_of_circles in m1e, # instead of directly using the loop variable. # #################################################################### # HINT: To figure out the code that computes the necessary # endpoints for each line, # ** FIRST DO A CONCRETE EXAMPLE BY HAND! ** #################################################################### # ------------------------------------------------------------------ x = point.x # Initialize x and y BEFORE the loop y = point.y # Choose values that make the FIRST object easy to draw for _ in range(n): # Loop that does NOT use its index variable # -------------------------------------------------------------- # Construct the relevant object(s), # based on the current x, y and other variables. # -------------------------------------------------------------- start = rg.Point(x, y) end = rg.Point(x + length, y) line = rg.Line(start, end) # Attach the object(s) to the window. line.attach_to(window) # -------------------------------------------------------------- # Increment x (and in other problems, other variables) # for the thing(s) to draw in the NEXT iteration of the loop. # -------------------------------------------------------------- y = y + 30 window.render()
def draw_lines_from_rectangles(rectangle1, rectangle2, n, window): """ What comes in: Four arguments: -- Two rg.Rectangles. -- A positive integer n. -- An rg.RoseWindow. What goes out: Nothing (i.e., None). Side effects: See draw_lines_from_rectangles.pdf in this project for pictures that may help you better understand the following specification: First draws the given rg.Rectangles on the given rg.RoseWindow. Then draws n rg.Lines on the given rg.RoseWindow, such that: -- The 1st rg.Line goes from the center of one of the 1st rg.Rectangle to the center of the 2nd rg.Rectangle. -- The 2nd rg.Line goes from the lower-left corner of the 1st rg.Rectangle and is parallel to the 1st rg.Line, with the same length and direction as the 1st rg.Line. -- Subsequent rg.Lines are shifted from the previous rg.Line in the same way that the 2nd rg.Line is shifted from the 1st. -- Each of the rg.Lines has thickness 5. -- The colors of the rg.Lines alternate, as follows: - The 1st, 3rd, 5th, ... rg.Line has color R1_color - The 2nd, 4th, 6th, ... rg.Line has color R2_color where - R1_color is the outline color of the 1st rg.Rectangle - R2_color is the outline color of the 2nd rg.Rectangle Must ** render ** but ** NOT close ** the window. Type hints: :type rectangle1: rg.Rectangle :type rectangle2: rg.Rectangle :type n: int :type window: rg.RoseWindow """ # ------------------------------------------------------------------ # DONE: 5. Implement and test this function. # Tests have been written for you (above). # # CONSIDER using the ACCUMULATOR IN GRAPHICS pattern, # as in draw_row_of_circles in m1e, # instead of directly using the loop variable. # #################################################################### # HINT: To figure out the code that computes the necessary # endpoints for each line, # ** FIRST DO A CONCRETE EXAMPLE BY HAND! ** #################################################################### # ------------------------------------------------------------------ rectangle1.attach_to(window) rectangle2.attach_to(window) window.render(0.05) for k in range(n): rectangle1center = rectangle1.get_center() start = rg.Point(rectangle1center.x + 10 * k, rectangle1center.y + 10 * k) rectangle2center = rectangle2.get_center() end = rg.Point(rectangle2center.x + 10 * k, rectangle2center.y + 10 * k) R1_color = rectangle1.outline_color R2_color = rectangle2.outline_color line = rg.Line(start, end) line.thickness = 5 if k % 2 == 0: line.color = R1_color else: line.color = R2_color line.attach_to(window) window.render(0.05)
def hourglass(window, n, point, radius, color): """ See hourglass_picture.pdf in this project for pictures that may help you better understand the following specification: Displays an "hourglass" shape of circles in the given window. -- Each circle has the given radius and given color. -- Each circle has a horizontal line drawn through it. -- The middlemost of the circles is centered at the given point. -- There is a single circle in that middlemost row. -- There are n rows (including the middlemost row) of circles going UP from the middlemost circle. -- There are n rows (including the middlemost row) of circles going DOWN from the middlemost circle. -- Each circle barely touches its neighbor circles. Preconditions: :type window: rg.RoseWindow :type n: int :type point: rg.Point :type radius: int :type color: str where n and radius are positive and color is a string that denotes a color that rosegraphics understands. """ original_x = point.x original_y = point.y x = point.x y = point.y x1 = point.x - radius x2 = point.x + radius original_x1 = x1 original_x2 = x2 for j in range(n): for k in range(j + 1): circle = rg.Circle(rg.Point(x, y), radius) circle.fill_color = color line = rg.Line(rg.Point(x1, y), rg.Point(x2, y)) circle.attach_to(window) line.attach_to(window) window.render(.1) x += 2 * radius x1 += 2 * radius x2 += 2 * radius y = y - math.sqrt(3 * (radius ** 2)) x = original_x - radius * (j + 1) x1 = original_x1 - radius * (j + 1) x2 = original_x2 - radius * (j + 1) x = original_x y = original_y x1 = point.x - radius x2 = point.x + radius for i in range(n): for m in range(i + 1): circle = rg.Circle(rg.Point(x, y), radius) circle.fill_color = color line = rg.Line(rg.Point(x1, y), rg.Point(x2, y)) circle.attach_to(window) line.attach_to(window) window.render(.1) x += 2 * radius x1 += 2 * radius x2 += 2 * radius y = y + math.sqrt(3 * (radius ** 2)) x = original_x - radius * (i + 1) x1 = original_x1 - radius * (i + 1) x2 = original_x2 - radius * (i + 1)