PILPeanut

Apr 6th, 2021 (edited)
337
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
1. from PIL import Image, ImageDraw
2.
3. def get_ellipse_penalty(f0, f1, r):
4.     def ellipse_penalty(point):
5.         x, y = point
6.         d0 = ((x - f0[0]) ** 2 + (y - f0[1]) ** 2) ** 0.5
7.         d1 = ((x - f1[0]) ** 2 + (y - f1[1]) ** 2) ** 0.5
8.         return abs(r - d0 - d1)
9.     return ellipse_penalty
10.
11. def get_cassini_penalty(f0, f1, r):
12.     def cassini_penalty(point):
13.         x, y = point
14.         d0 = (x - f0[0]) ** 2 + (y - f0[1]) ** 2
15.         d1 = (x - f1[0]) ** 2 + (y - f1[1]) ** 2
16.         return abs(r ** 4 - d0 * d1)
17.     return cassini_penalty
18.
19. def surrounding_points(point):
20.     x, y = point
21.     offsets = [(-1, -1), (-1, 0), (-1, 1), (0, -1),
22.                (0, 1), (1, -1), (1, 0), (1, 1)]
23.     return {(x + i, y + j) for i, j in offsets}
24.
25. def gen_points(penalty, init):
26.
27.     # initialize first two points
28.     # I'll need two to track pathing in order to find where
29.     # path should be complete.
30.     next_point = tuple(init)
31.     maybe_points = surrounding_points(next_point)
32.     last_point, next_point = next_point, min(maybe_points, key=penalty)
33.
34.     i = 0 # start counter
35.     points = {} # kinda depending on dictionary maintaining order
36.
37.     while (next_point, last_point) not in points:
38.
39.         points[(next_point, last_point)] = i
40.         maybe_points = surrounding_points(next_point) - {last_point} - surrounding_points(last_point)
41.         last_point, next_point = next_point, min(maybe_points, key=penalty)
42.
43.         i += 1
44.
45.     return [point for (point, _), i in points.items() if i >= points[(next_point, last_point)]]
46.
47. # im = Image.new("RGB", (500, 500), "black")
48. # draw = ImageDraw.Draw(im)
49.
50. # penalty = get_ellipse_penalty(f0=(400, 150), f1=(100, 200), r=350)
51. # points = gen_points(penalty, init=(1, 0))
52.
53. # draw.point(points, 'yellow')
54. # im.show()
55.
56. im = Image.new("RGB", (500, 500), "black")
57. draw = ImageDraw.Draw(im)
58.
59. penalty = get_cassini_penalty(f0=(125, 125), f1=(375, 375), r=250 / 2 ** .5)
60. points = gen_points(penalty, init=(250, 306))
61.
62. draw.point(points, 'yellow')
63. im.show()
RAW Paste Data