类似于这里的图片:
如何制作没有平坦部分的半椭圆形或半圆形?所以基本上只是弯曲的部分。
这就是我想出来的。这段代码打印了我需要的椭圆形的一半,但我只需要弯曲的部分。
import turtle
half = turtle.Turtle()
half.penup()
half.goto(-115,95)
half.setheading(-90)
half.pendown()
half.circle(100, 180)
half.left(90)
half.forward(200)
这是如何绘制一个旋转的椭圆形,具有起点和终点度数点以及海龟上的偏移位置,它有点慢但准确。
这是旋转椭圆方程的数学解释。
from numpy import arctan2
from math import sin, cos, radians, degrees
import turtle
# function that return 2 y from a given x, scale and rotation [ellipse function]
#https://rohankjoshi.medium.com/the-equation-for-a-rotated-ellipse-5888731da76
def get_y_ellipse(ellipse_size, x, alpha):
a, b = ellipse_size[0] / 2, ellipse_size[1] / 2
delta_sqrt = ((b**4-2*a**2*b**2+a**4)*sin(2*alpha)**2*x**2-4*a**4*x**2*cos(alpha)**2*sin(alpha)**2-4*a**2*b**2*x**2*cos(alpha)**2+4*a**4*b**2*cos(alpha)**2-4*a**2*b**2*x**2*sin(alpha)**4-4*b**4*x**2*sin(alpha)**2*cos(alpha)**2+4*a**2*b**4*sin(alpha)**2)**(1/2)
y1 = ((-b**2 + a**2)*sin(2*alpha)*x + delta_sqrt) / (2*a**2*cos(alpha)**2+2*b**2*sin(alpha)**2)
y2 = ((-b**2 + a**2)*sin(2*alpha)*x - delta_sqrt) / (2*a**2*cos(alpha)**2+2*b**2*sin(alpha)**2)
return y1, y2
# angle between 2 point on a 2d plane
def angle_to(p1, p2, rotation):
return (degrees(arctan2(p2[1] - p1[1], p2[0] - p1[0])) + rotation) % 360
window = turtle.Screen()
#############################################
# oval settings #############################
center_position = (0,0)
rotation = 0
ellipse_size = (100, 50)
draw_from_angle = 180
draw_to_angle = 360
#############################################
#############################################
#optimal min and max x axis
min_x = -int(ellipse_size[0]/2)
max_x = int(ellipse_size[0]/2)
trl = turtle.Turtle()
trl.penup()
# keep track of the first point to close the ellipse
first_point = None
# the ellipse function return a +- result, this for cycle draws the positive side the second one draws the negative one
for x in range(min_x, max_x):
#get the y from the function of x
y1, y2 = get_y_ellipse(ellipse_size, x, radians(rotation))
# check if value is not a complex number
if type(y1) in (int, float):
trl.goto(center_position[0]+x, center_position[1]+y1)
# if the angle of the new_position from the center is not between the from_angle and the to_angle list the pen
if draw_from_angle < angle_to(center_position, (center_position[0]+x, center_position[1]+y1), rotation) < draw_to_angle:
trl.pendown()
if first_point == None:
first_point = (center_position[0]+x, center_position[1]+y1)
print(first_point)
else:
trl.penup()
# elaborate a range of xs from right to left side of the screen
for x in range(max_x, min_x, -1):
y1, y2 = get_y_ellipse(ellipse_size, x, radians(rotation))
if type(y2) in (int, float):
trl.goto(center_position[0]+x, center_position[1]+y2)
if draw_from_angle < angle_to(center_position, (center_position[0]+x, center_position[1]+y2), rotation) < draw_to_angle:
trl.pendown()
else:
trl.penup()
# close the ellipse
if first_point != None:
trl.goto(first_point[0], first_point[1])
window.mainloop()
希望有帮助。
我知道的最简单的方法就是这个,
import turtle
turtle.circle(100,180)
turtle.left(90)
turtle.penup()
turtle.forward(200)
turtle.pendown()