Using python and pygame to draw a complex curve, pythonpygame

Source: Internet
Author: User

Using python and pygame to draw a complex curve, pythonpygame

Some time ago I saw the first phase of "the strongest brain", in which various flowers and curves combined into a very beautiful figure. I tried to plot the flowers and curves with code, if you want to combine them, you can combine them.

The actual flower-like curve is drawn using a gadget called the flower-like curve gauge. The flower-like curve gauge consists of two circles that fit each other and is inserted into a hole in the circle with a pen, scroll close to the inner wall of the circle to draw a beautiful pattern. In this process, we can make an Abstract: There are two circles with different radius, the position of the circle is fixed, the circle is inside the circle, and the circle is closely linked to the inner wall of the circle, find the path on a small circle.

Further analysis, the movement of a small circle can be divided into two parts: the center of a small circle rotates around the center of a large circle, and the circle rotates around its center. If the center of A circle is A, the radius is Ra, the center of A small circle is B, the radius is Rb, the trajectory point is C, and the radius is Rc (BC distance ), set the radians of the circle to θ [0, ∞ ),

Because the coordinates of the center of the circle are fixed, you must first find the coordinates of the center of the circle at the current moment of the circle and then find the radians of the rotation of the circle, finally, obtain the coordinates of a point on the incircle.

Step 1: Calculate the coordinates of the circle center

The trajectory of the center of a small circle is a circle with a radius of RA-RB. Finding the coordinates of the center of a small circle is equivalent to the coordinate of the point corresponding to the θ radian on the circle with a radius of RA-RB.

The coordinate formula of the point on the circle is:

X = r * cos (θ), y = r * sin (θ)

The coordinates of the circle center are: (xa + (Ra-Rb) * cos (θ), ya + (Ra-Rb) * sin (θ ))

Step 2: Calculate the rotation radians of a small circle

Set the rotation radians of a small circle to α, and the small circle follows the motion of the big circle. The distance between the two is the same, so there are:

Ra * θ = Rb * α

Radian α = (Ra/Rb) x θ

Step 3: Calculate the coordinate of point C

Point C is a circle with the Rc radius relative to the center B of a small circle. Similar to the first step:

The coordinates of trajectory point C are: (xa + Rc * cos (θ), ya + Rc * sin (θ ))

According to the above algorithm analysis, python code is implemented as follows:

#-*-Coding: UTF-8-*-import math ''' function: obtains the center and radius of an informed circle and obtains the coordinates of the vertices corresponding to a radian. input parameter: center: center radius: radius radian: radians ''' def get_point_in_circle (center, radius, radian): return (center [0] + radius * math. cos (radian), center [1]-radius * math. sin (radian) ''' function: Inner and Outer Circle A and B, inner circle A scroll along the inner ring of outer circle B, known circle center, radius, known inner circle radius, if we know the radians and radius of the arc point, calculate the coordinate input parameter center_A: Circle Center radius_A: circle radius radius_ B: circle radius radius_C: circle radius radian: radians ''' def evaluate (center_A, radius_A, radius_ B, radius_C, radian): # Calculate the center coordinate of the inner circle center_ B = radi_a, radius_A-radius_ B, radian) # Calculate the arc of the point (clockwise if the public rotation is counter-clockwise) radian_C = 2.0 * math. pi-(radius_A/radius_ B * radian) % (2.0 * math. pi) # return get_point_in_circle (center_ B, radius_C, radian_C)

Note the following two points:

(1) the upper left corner of the screen coordinate system is the origin point, and the vertical downward is the Y positive axis, which is opposite to the Y axis of the mathematical coordinate system. Therefore, the Y coordinate of the fifth line is the subtraction method;

(2) by default, the rotation is clockwise when the public rotation is counter-clockwise. Therefore, 2 π-α % (2 π) is used for the rotation radians in the 30th rows );

The coordinates have been calculated. Next, use pygame to plot the coordinates. The idea is to take 0.01 radian as a step, constantly calculate new coordinates, and connect a series of coordinates to form a track chart.

To form a closed image, you also need to know when the drawing point will return to the starting point again. I thought of a way to use the X axis and the Half Axis as the baseline. Each time the draw point arrives at the baseline, the distance between the draw point and the start point is calculated. When the accuracy reaches a certain level, it is deemed that it has returned to the start point to form a closed image.

''' Calculate the two-point distance (sum of squares) ''' def get_instance (p1, p2): return (p1 [0]-p2 [0]) * (p1 [0]-p2 [0]) + (p1 [1]-p2 [1]) * (p1 [1]-p2 [1]) ''' function: obtains the coordinates of all vertices in the path. input parameter: center: excircle center radius_A: excircle radius radius_ B: incircle radius radius_C: radius shift_radian: the radian of each offset. The default value is 0.01. The smaller the value, the higher the precision. The larger the calculation amount is ''' def get_points (center, radius_A, radius_ B, radius_C, shift_radian = 0.01 ): # convert to the real number radius_A * = 1.0 radius_ B * = 1.0 radius_C * = 1.0 P2 = 2 * math. pi # The radians in a circle are 2PI R_PER_ROUND = int (P2/shift_radian/4) + 1 # How many steps are required for a circle (How many radians are offset) # start_point = get_point_in_child_circle (center, radius_A, radius_ B, radius_C, 0) points = [start_point] # path coordinate of the first circle for r in range (1, R_PER_ROUND): points. append (get_point_in_child_circle (center, radius_A, radius_ B, radius_C, shift_radian * r) # The unit is circle. The starting radian of each circle is 2PI * round, the distance between the start coordinate of a circle and the start coordinate of the first circle is within a certain range. It is considered that the path ends for round in range (1,100): s_radian = round * P2 s_point = get_point_in_child_circle (center, radius_A, radius_ B, radius_C, s_radian) if get_instance (s_point, start_point) <0.1: break points. append (s_point) for r in range (1, R_PER_ROUND): points. append (get_point_in_child_circle (center, radius_A, radius_ B, radius_C, s_radian + shift_radian * r) return points

The complete code is as follows:

#-*-Coding: UTF-8-*-import mathimport random ''' function: obtains the center and radius of an informed circle and obtains the coordinates of the vertices corresponding to a radian. input parameter: center: center radius: radius radian: radians ''' def get_point_in_circle (center, radius, radian): return (center [0] + radius * math. cos (radian), center [1]-radius * math. sin (radian) ''' function: Inner and Outer Circle A and B, inner circle A scroll along the inner ring of outer circle B, known circle center, radius, known inner circle radius, radians, if the radius of the incircle is known, calculate the incircle coordinate input parameter: center_A: excircle center radius_A: excircle radius radius_ B: incircle radius radius_C: incircle radius radian: radians ''' def evaluate (center_A, radius_A, radius_ B, radius_C, radian): # Calculate the center coordinate of the inner circle center_ B = radi_a, radius_A-radius_ B, radian) # Calculate the arc of the point (clockwise if the public rotation is counter-clockwise) radian_C = 2.0 * math. pi-(radius_A/radius_ B * radian) % (2.0 * math. pi) # Calculate the coordinates of the circle center_C = round (center_ B, radius_C, radian_C) center_ B _Int = (int (center_ B [0]), int (center_ B [1]) return center_ B _Int, center_C ''' calculates the two-point distance (sum of squares) ''' def get_instance (p1, p2): return (p1 [0]-p2 [0]) * (p1 [0]-p2 [0]) + (p1 [1]-p2 [1]) * (p1 [1]-p2 [1]) ''' function: obtains the coordinates of all vertices in the path. input parameter: center: excircle center radius_A: excircle radius radius_ B: incircle radius radius_C: radius shift_radian: the radian of each offset. The default value is 0.01. The smaller the value, the higher the precision. The larger the calculation amount is ''' def get_points (center_A, radius_A, radius_ B, radius_C, shift_radian = 0.01 ): # convert to the real number radius_A * = 1.0 radius_ B * = 1.0 radius_C * = 1.0 P2 = 2 * math. pi # 2PI R_PER_ROUND = int (P2/shift_radian) + 1 # steps (How many radians are offset) # start_center, start_point = centers (center_A, radius_A, radius_ B, radius_C, 0) points = [start_point] centers = [start_center] # path coordinate of the first circle for r in range (1, R_PER_ROUND ): center, point = get_point_in_child_circle (center_A, radius_A, radius_ B, radius_C, shift_radian * r) points. append (point) centers. append (center) # The unit is circle. The starting radian of each circle is 2PI * round. The distance between the start coordinate of a circle and the start coordinate of the first circle is within a certain range, assume that the path ends for round in range (1,100): s_radian = round * P2 s_center, s_point = Centers (center_A, radius_A, radius_ B, radius_C, s_radian) if get_instance (s_point, start_point) <0.1: break points. append (s_point) centers. append (s_center) for r in range (1, R_PER_ROUND): center, point = Centers (center_A, radius_A, radius_ B, radius_C, s_radian + shift_radian * r) points. append (point) centers. append (center) print (len (points)/R_PER_ROUND) return centers, pointsimport pygamefrom pygame. locals import * pygame. init () screen = pygame. display. set_mode (600,400) clock = pygame. time. clock () color_black = (0, 0, 0) color_white = (255,255,255) color_red = (255, 0, 0) color_yello = (255,255, 0) center = (300,200) radius_A = percentage = 110radius_C = 50test_centers, test_points = get_points (center, radius_A, radius_ B, radius_C) test_idx = percentage = 5 while True: for event in pygame. event. get (): if event. type = pygame. QUIT: pygame. quit () exit (0) screen. fill (color_white) pygame. draw. circle (screen, color_black, center, int (radius_A), 2) if test_idx <= len (test_points): pygame. draw. aalines (screen, (0, 0,255), False, test_points [: test_idx], 1) if test_idx <len (test_centers): pygame. draw. circle (screen, color_black, test_centers [test_idx], int (radius_ B), 1) pygame. draw. aaline (screen, color_black, test_centers [test_idx], test_points [test_idx], 1) test_idx = min (test_idx + draw_point_num_per_tti, len (test_points) clock. tick (50) pygame. display. flip ()

Effect:

The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.