我正在尝试使用Python和PIL重新创建此图像。
这是我提供的代码:
from PIL import Image, ImageDraw
def draw_lines(draw, points):
new_points = []
for idx, point in enumerate(points):
x, y = point
if idx != len(points) - 1:
if idx == 0:
x = x + 25
elif idx == 1:
y = y + 25
elif idx == 2:
x = x - 25
elif idx == 3:
y = y - 25
else:
x = x + 25
new_points.append((x, y))
draw.line(new_points, fill="black", width=1)
return new_points
def main():
im = Image.new('RGB', (501, 501), color=(255, 255, 255))
draw = ImageDraw.Draw(im)
points = [
(0, 0),
(500, 0),
(500, 500),
(0, 500),
(0, 0),
]
draw.line(points, fill="black", width=1)
for i in range(80):
points = draw_lines(draw, points)
im.save("out.png")
if __name__ == '__main__':
main()
这是输出:
还有如何用颜色填充那些形成的三角形?
更新:
通过在此处Rotating a square in PIL修改答案,我能够做到这一点。代码:
import math
from PIL import Image, ImageDraw
def distance(ax, ay, bx, by):
return math.sqrt((by - ay) ** 2 + (bx - ax) ** 2)
def rotated_about(ax, ay, bx, by, angle):
radius = distance(ax, ay, bx, by)
angle += math.atan2(ay - by, ax - bx)
return (
round(bx + radius * math.cos(angle)),
round(by + radius * math.sin(angle))
)
image = Image.new('RGB', (510, 510), color=(255, 255, 255))
draw = ImageDraw.Draw(image)
def draw_sqr(pos, sqlen, rota):
square_center = pos
square_length = sqlen
square_vertices = (
(square_center[0] + square_length / 2, square_center[1] + square_length / 2),
(square_center[0] + square_length / 2, square_center[1] - square_length / 2),
(square_center[0] - square_length / 2, square_center[1] - square_length / 2),
(square_center[0] - square_length / 2, square_center[1] + square_length / 2)
)
square_vertices = [rotated_about(x, y, square_center[0], square_center[1], math.radians(rota)) for x, y in
square_vertices]
draw.polygon(square_vertices, outline="black")
def draw_rot_sqr(pos):
scale = 500
rot = 0
n = 1.1575
for i in range(10):
draw_sqr(pos, scale, rot)
rot = rot * n + 10
scale = scale / n - 10
draw_rot_sqr((255, 255))
image.show()
现在,如何正确缩放和旋转所有点以任意大小与边相交的正方形?
这是一个可爱的数学问题。
给出上图,其中L
是起始正方形的边长,而L'
是新正方形的边长,我们必须找到θ
,以便在旋转新正方形时,所有的角都触摸上一个正方形。
L'
可以定义为L'=L*f
,其中f
是缩放因子。例如,如果缩放因子为0.9
,则每个新的正方形边将是前一个正方形边的90%。
[使用一些基本三角函数,可以发现a
是(calc_a()
函数):
一代码>”>
然后,可以使用]计算[C0
我所做的修改产生以下输出。θ
奖励模因:使用0.98缩放因子进行1000次迭代的输出。
import math
from PIL import Image, ImageDraw
def calc_a(L, f):
return L/2.0*(1-(1-2*(1-f**2))**.5)
def calc_theta(L, f):
a = calc_a(L, f)
return math.atan2(a, L-a)
def distance(ax, ay, bx, by):
return math.sqrt((by - ay) ** 2 + (bx - ax) ** 2)
def rotated_about(ax, ay, bx, by, angle):
radius = distance(ax, ay, bx, by)
angle += math.atan2(ay - by, ax - bx)
return (
round(bx + radius * math.cos(angle)),
round(by + radius * math.sin(angle))
)
image = Image.new('RGB', (510, 510), color=(255, 255, 255))
draw = ImageDraw.Draw(image)
def draw_sqr(pos, sqlen, rota):
square_center = pos
square_length = sqlen
square_vertices = (
(square_center[0] + square_length / 2, square_center[1] + square_length / 2),
(square_center[0] + square_length / 2, square_center[1] - square_length / 2),
(square_center[0] - square_length / 2, square_center[1] - square_length / 2),
(square_center[0] - square_length / 2, square_center[1] + square_length / 2)
)
square_vertices = [rotated_about(x, y, square_center[0], square_center[1], rota) for x, y in
square_vertices]
draw.polygon(square_vertices, outline="black")
def draw_rot_sqr(pos):
side = 500 # starting square side length
theta = 0 # starting theta (in radians) -- 0 rotation on first square
f = 0.9 # scaling factor, should be bigger than sqrt(2)/2, for math reasons (refer to first equation). if over 1, new square will be bigger than previous (still works though!)
for i in range(10):
draw_sqr(pos, side, theta)
# theta is relative to previous square, so we should accumulate it
theta += calc_theta(side, f)
side *= f
draw_rot_sqr((255, 255))
image.show()