fractal 0.5.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
fractal/__init__.py ADDED
@@ -0,0 +1,8 @@
1
+ """
2
+ 分形相关操作封装
3
+ """
4
+ from .lsystem import Pen
5
+ from .ifs import IFS
6
+ from .julia import Julia
7
+ from .mandelbrot import Mandelbrot
8
+ from .cifs import CIFS
fractal/base.py ADDED
@@ -0,0 +1,412 @@
1
+ """
2
+ 基类
3
+ 功能说明:
4
+ - 保存图片:点击"保存"按钮 或 Ctrl+P
5
+ - 放大:左键点击显示选择框,拖动调整位置,再次点击确认放大
6
+ - 缩小:右键点击缩小
7
+ - 取消选择:右键点击或按ESC键
8
+ """
9
+
10
+ import tkinter as tk
11
+ from tkinter import messagebox, filedialog
12
+ import threading
13
+
14
+ # 尝试导入Pillow和numpy用于高性能绘图
15
+ try:
16
+ from PIL import Image, ImageTk, ImageDraw
17
+ HAS_PIL = True
18
+ except ImportError:
19
+ HAS_PIL = False
20
+
21
+ try:
22
+ import numpy as np
23
+ HAS_NUMPY = True
24
+ except ImportError:
25
+ HAS_NUMPY = False
26
+
27
+
28
+ class Base(object):
29
+
30
+ def __init__(self, size, callRun, title=""):
31
+ """
32
+ size: 画布尺寸
33
+ callRun: 子类的绘画函数回调
34
+ title: 画布标题
35
+ """
36
+ self._run = callRun
37
+ self.title = title if title else "Fractal"
38
+ self.width = size[0]
39
+ self.height = size[1]
40
+
41
+ # 绘图模式标记:'pixel'为像素绘图,'line'为线条绘图
42
+ self._draw_mode = 'pixel'
43
+
44
+ # 创建像素数组(用于存储计算结果)
45
+ if HAS_NUMPY:
46
+ self._pixel_array = np.zeros((self.height, self.width, 3), dtype=np.uint8)
47
+ self._pixel_array.fill(255) # 白色背景
48
+ else:
49
+ self._pixel_array = None
50
+
51
+ # 创建主窗口
52
+ self.root = tk.Tk()
53
+ self.root.title(self.title)
54
+ self.root.resizable(False, False)
55
+
56
+ # 创建主框架
57
+ self.main_frame = tk.Frame(self.root)
58
+ self.main_frame.pack(padx=5, pady=5)
59
+
60
+ # 创建画布
61
+ self.canvas = tk.Canvas(self.main_frame, width=self.width, height=self.height, bg='white')
62
+ self.canvas.pack()
63
+
64
+ # 创建按钮框架
65
+ self.button_frame = tk.Frame(self.root)
66
+ self.button_frame.pack(fill=tk.X, padx=5, pady=5)
67
+
68
+ # 保存按钮
69
+ self.save_btn = tk.Button(self.button_frame, text="保存图片", command=self._on_save_click,
70
+ width=12, height=1, bg="#4CAF50", fg="white", font=("Arial", 10))
71
+ self.save_btn.pack(side=tk.LEFT, padx=5)
72
+
73
+ # 另存为按钮
74
+ self.save_as_btn = tk.Button(self.button_frame, text="另存为...", command=self._on_save_as_click,
75
+ width=12, height=1, bg="#2196F3", fg="white", font=("Arial", 10))
76
+ self.save_as_btn.pack(side=tk.LEFT, padx=5)
77
+
78
+ # 状态标签
79
+ self.status_label = tk.Label(self.button_frame, text="就绪", font=("Arial", 9), fg="gray")
80
+ self.status_label.pack(side=tk.RIGHT, padx=10)
81
+
82
+ # 创建图像对象
83
+ if HAS_PIL:
84
+ self._pil_image = Image.new('RGB', (self.width, self.height), 'white')
85
+ self._draw = ImageDraw.Draw(self._pil_image) # PIL绘图对象
86
+ self.image = ImageTk.PhotoImage(self._pil_image, master=self.root)
87
+ else:
88
+ self.image = tk.PhotoImage(width=self.width, height=self.height, master=self.root)
89
+ self.image.put("white", to=(0, 0, self.width, self.height))
90
+
91
+ self.canvas_img = self.canvas.create_image(0, 0, anchor="nw", image=self.image)
92
+
93
+ self.psave = False
94
+ self.scalaRate = 4 # 放大(缩小)倍数
95
+ self.ctrl = False # Ctrl键按下
96
+ self.cnt = 1 # 连续命名时标号
97
+ self._running = True
98
+ self._drawing = False
99
+ self._draw_thread = None
100
+
101
+ # 选择框相关
102
+ self._selection_rect = None # 选择框ID
103
+ self._selecting = False # 是否在选择模式
104
+ self._selection_center = None # 选择框中心坐标
105
+ self._drag_start = None # 拖动起始坐标
106
+
107
+ # 绑定事件
108
+ self.root.protocol("WM_DELETE_WINDOW", self._on_close)
109
+ self.root.bind("<Control-p>", self._on_save)
110
+ self.root.bind("<Control-s>", self._on_save_click)
111
+ self.root.bind("<Escape>", self._cancel_selection) # ESC取消选择
112
+ self.canvas.bind("<Button-1>", self._on_left_click) # 左键
113
+ self.canvas.bind("<Button-3>", self._on_right_click) # 右键
114
+ self.canvas.bind("<B1-Motion>", self._on_drag) # 拖动
115
+ self.canvas.bind("<ButtonRelease-1>", self._on_drag_end) # 拖动结束
116
+ self.canvas.bind("<Double-Button-1>", self._on_double_click) # 双击确认
117
+
118
+ def _on_close(self):
119
+ self._running = False
120
+ self.root.quit()
121
+ self.root.destroy()
122
+
123
+ def _update_status(self, text, color="gray"):
124
+ """更新状态标签"""
125
+ self.status_label.config(text=text, fg=color)
126
+
127
+ def _on_save(self, event=None):
128
+ """快捷键保存"""
129
+ self._on_save_click()
130
+
131
+ def _cancel_selection(self, event=None):
132
+ """取消选择框"""
133
+ if self._selection_rect is not None:
134
+ self.canvas.delete(self._selection_rect)
135
+ self._selection_rect = None
136
+ self._selecting = False
137
+ self._selection_center = None
138
+ self._update_status("已取消选择", "gray")
139
+
140
+ def _get_selection_rect_coords(self, center_x, center_y):
141
+ """获取选择框的坐标"""
142
+ w = self.width // (2 * self.scalaRate)
143
+ h = self.height // (2 * self.scalaRate)
144
+ return (center_x - w, center_y - h, center_x + w, center_y + h)
145
+
146
+ def _sync_pil_image(self):
147
+ """同步PIL图像从numpy数组"""
148
+ if HAS_PIL and HAS_NUMPY and self._draw_mode == 'pixel':
149
+ self._pil_image = Image.fromarray(self._pixel_array, 'RGB')
150
+ self._draw = ImageDraw.Draw(self._pil_image)
151
+
152
+ def _on_save_click(self):
153
+ """点击保存按钮"""
154
+ if self._drawing:
155
+ messagebox.showwarning("提示", "请等待绘图完成后再保存")
156
+ return
157
+ # 确保PIL图像与像素数组同步(仅对像素绘图模式)
158
+ self._sync_pil_image()
159
+ if self.title == "":
160
+ self.title = "fractal"
161
+ if HAS_PIL:
162
+ filename = self.title + str(self.cnt) + ".png"
163
+ self._pil_image.save(filename)
164
+ self._update_status(f"已保存: {filename}", "green")
165
+ messagebox.showinfo("保存成功", f"图片已保存为 {filename}")
166
+ else:
167
+ filename = self.title + str(self.cnt) + ".ps"
168
+ self.canvas.postscript(file=filename, colormode='color')
169
+ self._update_status(f"已保存: {filename}", "green")
170
+ messagebox.showinfo("保存成功", f"图片已保存为 {filename}\n(PostScript格式)")
171
+ self.cnt += 1
172
+
173
+ def _on_save_as_click(self):
174
+ """另存为对话框"""
175
+ if self._drawing:
176
+ messagebox.showwarning("提示", "请等待绘图完成后再保存")
177
+ return
178
+ # 确保PIL图像与像素数组同步
179
+ self._sync_pil_image()
180
+ if HAS_PIL:
181
+ filetypes = [
182
+ ("PNG 图片", "*.png"),
183
+ ("JPEG 图片", "*.jpg"),
184
+ ("BMP 图片", "*.bmp"),
185
+ ("所有文件", "*.*")
186
+ ]
187
+ filename = filedialog.asksaveasfilename(
188
+ title="保存图片",
189
+ initialfile=self.title + ".png",
190
+ filetypes=filetypes,
191
+ defaultextension=".png"
192
+ )
193
+ if filename:
194
+ self._pil_image.save(filename)
195
+ self._update_status(f"已保存: {filename}", "green")
196
+ messagebox.showinfo("保存成功", f"图片已保存为 {filename}")
197
+ else:
198
+ filetypes = [("PostScript", "*.ps"), ("所有文件", "*.*")]
199
+ filename = filedialog.asksaveasfilename(
200
+ title="保存图片",
201
+ initialfile=self.title + ".ps",
202
+ filetypes=filetypes,
203
+ defaultextension=".ps"
204
+ )
205
+ if filename:
206
+ self.canvas.postscript(file=filename, colormode='color')
207
+ self._update_status(f"已保存: {filename}", "green")
208
+ messagebox.showinfo("保存成功", f"图片已保存为 {filename}")
209
+
210
+ def _on_left_click(self, event):
211
+ """左键点击处理"""
212
+ if self._drawing or not hasattr(self, "scala"):
213
+ return
214
+
215
+ # 如果正在选择模式,确认放大
216
+ if self._selecting and self._selection_rect is not None:
217
+ self._confirm_zoom(event.x, event.y)
218
+ return
219
+
220
+ # 第一次点击,显示选择框
221
+ i, j = event.x, event.y
222
+ coords = self._get_selection_rect_coords(i, j)
223
+ self._selection_rect = self.canvas.create_rectangle(
224
+ coords[0], coords[1], coords[2], coords[3],
225
+ outline="red", width=2, dash=(4, 4)
226
+ )
227
+ self._selecting = True
228
+ self._selection_center = (i, j)
229
+ self._update_status("拖动调整位置,点击确认,ESC取消", "blue")
230
+
231
+ def _on_double_click(self, event):
232
+ """双击确认放大"""
233
+ if self._selecting and self._selection_rect is not None and not self._drawing:
234
+ self._confirm_zoom(self._selection_center[0], self._selection_center[1])
235
+
236
+ def _on_drag(self, event):
237
+ """拖动选择框"""
238
+ if not self._selecting or self._selection_rect is None:
239
+ return
240
+ # 更新选择框位置
241
+ coords = self._get_selection_rect_coords(event.x, event.y)
242
+ self.canvas.coords(self._selection_rect, coords[0], coords[1], coords[2], coords[3])
243
+ self._selection_center = (event.x, event.y)
244
+
245
+ def _on_drag_end(self, event):
246
+ """拖动结束"""
247
+ if self._selecting:
248
+ self._selection_center = (event.x, event.y)
249
+
250
+ def _confirm_zoom(self, x, y):
251
+ """确认放大"""
252
+ # 删除选择框
253
+ if self._selection_rect is not None:
254
+ self.canvas.delete(self._selection_rect)
255
+ self._selection_rect = None
256
+ self._selecting = False
257
+
258
+ # 执行放大
259
+ self._clear_pixels()
260
+ self.scala(x, y, self.scalaRate)
261
+ self._start_draw()
262
+
263
+ def _on_right_click(self, event):
264
+ """右键点击处理"""
265
+ if self._drawing:
266
+ return
267
+
268
+ # 如果在选择模式,取消选择
269
+ if self._selecting:
270
+ self._cancel_selection()
271
+ return
272
+
273
+ # 否则执行缩小
274
+ if hasattr(self, "scala"):
275
+ self._clear_pixels()
276
+ self.scala(event.x, event.y, 1 / self.scalaRate)
277
+ self._start_draw()
278
+
279
+ def _clear_pixels(self):
280
+ """清空像素数据"""
281
+ if HAS_NUMPY:
282
+ self._pixel_array.fill(255)
283
+ if HAS_PIL:
284
+ self._pil_image = Image.new('RGB', (self.width, self.height), 'white')
285
+ self._draw = ImageDraw.Draw(self._pil_image)
286
+
287
+ def _start_draw(self):
288
+ """开始绘图线程"""
289
+ self._drawing = True
290
+ self._update_status("绘图中...", "orange")
291
+ self._draw_thread = threading.Thread(target=self._run_and_update, daemon=True)
292
+ self._draw_thread.start()
293
+
294
+ def _run_and_update(self):
295
+ """绘图并在完成后更新显示"""
296
+ try:
297
+ self._run()
298
+ # 绘图完成后立即同步PIL图像(在线程中执行)
299
+ if HAS_PIL and HAS_NUMPY and self._draw_mode == 'pixel':
300
+ self._pil_image = Image.fromarray(self._pixel_array, 'RGB')
301
+ self._draw = ImageDraw.Draw(self._pil_image)
302
+ except Exception as e:
303
+ print(f"绘图错误: {e}")
304
+ finally:
305
+ self._drawing = False
306
+ # 在主线程中更新显示
307
+ self.root.after(0, self._finish_draw)
308
+
309
+ def _finish_draw(self):
310
+ """绘图完成后的处理"""
311
+ self._update_display()
312
+ self._update_status("绘图完成 - 左键选择放大区域", "green")
313
+
314
+ def _update_display(self):
315
+ """更新显示(在主线程中调用)"""
316
+ if HAS_PIL and HAS_NUMPY and self._draw_mode == 'pixel':
317
+ # 从numpy数组创建PIL图像
318
+ self._pil_image = Image.fromarray(self._pixel_array, 'RGB')
319
+ self._draw = ImageDraw.Draw(self._pil_image)
320
+ if HAS_PIL:
321
+ self.image = ImageTk.PhotoImage(self._pil_image, master=self.root)
322
+ self.canvas.itemconfig(self.canvas_img, image=self.image)
323
+
324
+ def save(self, title):
325
+ """保存图片"""
326
+ if HAS_PIL:
327
+ self._pil_image.save(title)
328
+ else:
329
+ self.canvas.postscript(file=title, colormode='color')
330
+
331
+ def set_pixel(self, x, y, color):
332
+ """设置单个像素"""
333
+ if isinstance(color, (list, tuple)):
334
+ r, g, b = int(color[0]), int(color[1]), int(color[2])
335
+ else:
336
+ r, g, b = 0, 0, 0
337
+
338
+ x, y = int(x), int(y)
339
+ if 0 <= x < self.width and 0 <= y < self.height:
340
+ if HAS_NUMPY:
341
+ self._pixel_array[y, x] = [r, g, b]
342
+ elif HAS_PIL:
343
+ self._pil_image.putpixel((x, y), (r, g, b))
344
+ else:
345
+ color_str = "#{:02x}{:02x}{:02x}".format(r, g, b)
346
+ self.image.put(color_str, (x, y))
347
+
348
+ def set_pixel_fast(self, x, y, r, g, b):
349
+ """快速设置单个像素"""
350
+ x, y = int(x), int(y)
351
+ if 0 <= x < self.width and 0 <= y < self.height:
352
+ if HAS_NUMPY:
353
+ self._pixel_array[y, x] = [r, g, b]
354
+ elif HAS_PIL:
355
+ self._pil_image.putpixel((x, y), (r, g, b))
356
+ else:
357
+ color_str = "#{:02x}{:02x}{:02x}".format(r, g, b)
358
+ self.image.put(color_str, (x, y))
359
+
360
+ def set_pixels(self, pixels):
361
+ """批量设置像素"""
362
+ for (x, y), color in pixels.items():
363
+ self.set_pixel(x, y, color)
364
+
365
+ def draw_line(self, start, end, color, width=1):
366
+ """
367
+ 绘制线条
368
+ 同时在Canvas和PIL图像上绘制,确保保存时图像正确
369
+ """
370
+ self._draw_mode = 'line' # 标记为线条绘图模式
371
+
372
+ # 在Canvas上绘制
373
+ if isinstance(color, (list, tuple)):
374
+ r, g, b = int(color[0]), int(color[1]), int(color[2])
375
+ canvas_color = "#{:02x}{:02x}{:02x}".format(r, g, b)
376
+ else:
377
+ canvas_color = color
378
+ r, g, b = 0, 0, 0
379
+
380
+ self.canvas.create_line(start[0], start[1], end[0], end[1], fill=canvas_color, width=width)
381
+
382
+ # 在PIL图像上绘制(用于保存)
383
+ if HAS_PIL:
384
+ self._draw.line([start[0], start[1], end[0], end[1]], fill=(r, g, b), width=width)
385
+
386
+ def draw_rect(self, x, y, w, h, color, outline_only=True):
387
+ """绘制矩形"""
388
+ if isinstance(color, (list, tuple)):
389
+ r, g, b = color
390
+ color = "#{:02x}{:02x}{:02x}".format(int(r), int(g), int(b))
391
+ if outline_only:
392
+ self.canvas.create_rectangle(x, y, x + w, y + h, outline=color, width=1)
393
+ else:
394
+ self.canvas.create_rectangle(x, y, x + w, y + h, fill=color, outline=color)
395
+
396
+ def fill(self, color):
397
+ """填充背景色"""
398
+ if isinstance(color, (list, tuple)):
399
+ r, g, b = int(color[0]), int(color[1]), int(color[2])
400
+ else:
401
+ r, g, b = 255, 255, 255
402
+
403
+ if HAS_NUMPY:
404
+ self._pixel_array[:, :] = [r, g, b]
405
+ if HAS_PIL:
406
+ self._pil_image = Image.new('RGB', (self.width, self.height), (r, g, b))
407
+ self._draw = ImageDraw.Draw(self._pil_image)
408
+
409
+ def wait(self):
410
+ """等待用户关闭"""
411
+ self._start_draw()
412
+ self.root.mainloop()
fractal/cifs.py ADDED
@@ -0,0 +1,100 @@
1
+ """
2
+ Complex Iterated Function System.
3
+ 复迭代函数系统
4
+ """
5
+
6
+ from .base import Base, HAS_NUMPY
7
+ from .colors import *
8
+ from threading import Thread
9
+
10
+
11
+ class CIFS(Base):
12
+
13
+ def __init__(self, size, title=""):
14
+ Base.__init__(self, size, self._run, title)
15
+ self.setRadius(10)
16
+ self.width = size[0]
17
+ self.height = size[1]
18
+ self.setRange(10, 10)
19
+ self.setCentre(0 + 0j)
20
+ self.ifunc = None
21
+
22
+ def setFunction(self, ifunc):
23
+ # 设置迭代函数
24
+ self.ifunc = ifunc
25
+
26
+ def setRadius(self, R):
27
+ # 设置逃逸半径
28
+ self.R = R
29
+
30
+ def color(self, n, r=2):
31
+ if n < len(reds):
32
+ return reds[n]
33
+ else:
34
+ if r < self.R:
35
+ return blues[int((len(blues) - 1) * r / self.R)]
36
+ else:
37
+ return purples[int((len(purples) - 1) * self.R / r)]
38
+
39
+ def setColor(self, call):
40
+ self.color = call
41
+
42
+ def setCentre(self, z0):
43
+ # 设置中心点
44
+ self.z0 = z0
45
+
46
+ def setRange(self, xmax, ymax):
47
+ # 设置坐标范围,范围越小图放大倍数越高
48
+ self.xmax = xmax
49
+ self.ymax = ymax
50
+
51
+ def __getXY(self, i, j):
52
+ # 通过像素坐标获取映射后的坐标
53
+ return complex((i / self.width - 0.5) * self.xmax + self.z0.real,
54
+ (j / self.height - 0.5) * self.ymax + self.z0.imag)
55
+
56
+ def scala(self, i, j, rate):
57
+ # 将(i, j)像素点置于中心位置,放大rete倍
58
+ self.setCentre(self.__getXY(i, j))
59
+ self.xmax /= rate
60
+ self.ymax /= rate
61
+
62
+ def __calc(self, start, w, h):
63
+ # 绘制以start为起点,宽w,高h的子区域
64
+ for i in range(start[0], start[0] + w):
65
+ for j in range(start[1], start[1] + h):
66
+ ct = 0
67
+ z = self.__getXY(i, j)
68
+ for k in range(self.N):
69
+ ct = k
70
+ if abs(z) > self.R:
71
+ break
72
+ z = self.ifunc(z)
73
+ col = self.color(ct, abs(z))
74
+ if HAS_NUMPY and self._pixel_array is not None:
75
+ self._pixel_array[j, i] = [int(col[0]), int(col[1]), int(col[2])]
76
+ else:
77
+ self.set_pixel_fast(i, j, col[0], col[1], col[2])
78
+
79
+ def _run(self):
80
+ print("x range :[-%.2e,%.2e]\ny range :[-%.2e,%.2e]" % (
81
+ self.xmax, self.xmax, self.ymax, self.ymax))
82
+ if self.ifunc is None:
83
+ raise Exception("请设置迭代函数")
84
+ tn = 5
85
+ ci = self.width // tn
86
+ cj = self.height // tn
87
+ ts = []
88
+ for i in range(tn):
89
+ for j in range(tn):
90
+ t = Thread(target=self.__calc, args=([i * ci, j * cj], ci, cj))
91
+ t.start()
92
+ ts.append(t)
93
+ for t in ts:
94
+ t.join()
95
+ del ts
96
+
97
+ def doCifs(self, N):
98
+ # 进入迭代
99
+ # N: 单点最大迭代次数
100
+ self.N = N
fractal/colors.py ADDED
@@ -0,0 +1,21 @@
1
+ """
2
+
3
+ 颜色的RGB值,列表索引从小到大颜色依次加深
4
+
5
+ """
6
+
7
+ blues = [(255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (254, 254, 254), (254, 254, 254), (254, 254, 254), (254, 254, 254), (253, 253, 253), (253, 253, 253), (254, 255, 255), (254, 255, 255), (253, 254, 255), (249, 253, 255), (248, 252, 255), (246, 250, 253), (245, 249, 252), (245, 249, 252), (245, 250, 253), (245, 250, 253), (245, 250, 253), (243, 251, 253), (242, 250, 252), (242, 250, 252), (242, 250, 252), (242, 250, 252), (241, 249, 252), (241, 249, 252), (241, 249, 252), (240, 248, 251), (240, 248, 251), (239, 248, 253), (238, 247, 252), (238, 247, 252), (238, 247, 254), (237, 248, 254), (237, 248, 254), (237, 248, 254), (237, 248, 254), (236, 246, 255), (233, 246, 254), (233, 246, 254), (231, 246, 253), (230, 244, 253), (230, 244, 253), (227, 244, 252), (226, 243, 251), (226, 243, 251), (225, 242, 250), (225, 242, 252), (223, 241, 251), (223, 241, 251), (222, 240, 252), (221, 241, 252), (220, 240, 251), (219, 239, 250), (219, 239, 250), (219, 239, 250), (212, 239, 250), (212, 239, 250), (211, 237, 250), (210, 236, 249), (208, 236, 248), (207, 235, 249), (205, 234, 248), (205, 234, 250), (202, 234, 249), (201, 232, 250), (200, 233, 250), (199, 232, 251), (196, 231, 250), (195, 230, 250), (194, 229, 249), (194, 229, 249), (187, 230, 249), (187, 230, 249), (186, 229, 248), (183, 228, 249), (180, 226, 249), (178, 226, 248), (175, 225, 248), (174, 226, 250), (170, 224, 250), (167, 223, 248), (164, 221, 248), (161, 221, 249), (160, 221, 249), (160, 221, 250), (156, 220, 248), (154, 218, 246), (151, 218, 247), (150, 217, 246), (147, 216, 247), (144, 215, 245), (139, 214, 245), (136, 212, 244), (132, 212, 245), (128, 212, 246), (122, 211, 245), (118, 211, 245), (114, 211, 246), (111, 209, 246), (106, 208, 246), (103, 207, 246), (102, 206, 245), (99, 205, 244), (86, 205, 248), (82, 203, 246), (77, 200, 244), (72, 199, 244), (67, 198, 244), (61, 198, 244), (54, 196, 244), (47, 195, 243), (39, 195, 244), (32, 193, 245), (24, 191, 243), (17, 191, 242), (13, 190, 244), (9, 190, 245), (5, 189, 243), (2, 187, 243), (2, 185, 243), (1, 184, 242), (0, 183, 241), (0, 182, 242), (0, 180, 241), (0, 179, 240), (0, 178, 240), (0, 177, 239), (0, 175, 240), (0, 174, 239), (0, 173, 239), (0, 173, 239), (1, 172, 241), (0, 171, 240), (0, 171, 240), (0, 171, 240), (0, 169, 236), (1, 170, 237), (1, 170, 237), (0, 169, 234), (1, 169, 234), (0, 168, 233), (1, 166, 232), (0, 165, 231), (1, 164, 229), (1, 164, 229), (1, 163, 228), (0, 162, 226), (2, 161, 226), (1, 160, 225), (0, 159, 224), (0, 159, 224), (0, 159, 221), (0, 159, 221),
8
+ (0, 159, 221), (0, 159, 221), (0, 158, 220), (0, 157, 220), (0, 157, 220), (1, 156, 220), (0, 155, 219), (0, 154, 218), (0, 154, 218), (0, 152, 217), (0, 152, 217), (0, 151, 216), (1, 150, 216), (0, 149, 215), (2, 150, 214), (2, 150, 212), (1, 149, 211), (1, 149, 211), (0, 148, 210), (0, 147, 209), (1, 146, 209), (1, 147, 207), (1, 147, 207), (1, 145, 206), (1, 145, 205), (0, 144, 204), (0, 144, 204), (0, 143, 203), (0, 142, 202), (0, 142, 202), (1, 141, 202), (1, 141, 202), (0, 140, 201), (0, 140, 201), (0, 139, 198), (0, 138, 197), (0, 138, 197), (0, 138, 197), (1, 137, 195), (0, 136, 194), (0, 136, 194), (0, 136, 194), (1, 136, 192), (0, 135, 191), (0, 135, 191), (0, 135, 191), (0, 132, 189), (0, 132, 189), (0, 132, 189), (0, 131, 188), (0, 131, 188), (0, 131, 188), (0, 130, 188), (0, 129, 187), (0, 128, 186), (0, 128, 186), (0, 128, 186), (0, 128, 186), (0, 127, 185), (0, 127, 185), (0, 127, 185), (0, 127, 185), (0, 125, 181), (0, 125, 181), (0, 124, 180), (0, 124, 180), (0, 124, 180), (0, 123, 180), (0, 122, 179), (0, 122, 179), (0, 121, 178), (1, 122, 179), (1, 122, 179), (1, 122, 179), (1, 122, 179), (1, 120, 178), (0, 119, 177), (0, 119, 177), (0, 117, 171), (0, 117, 171), (0, 115, 170), (0, 115, 170), (0, 115, 170), (0, 114, 169), (0, 114, 169), (0, 113, 169), (0, 113, 169), (0, 113, 169), (0, 113, 169), (1, 112, 168), (1, 112, 168), (1, 112, 168), (0, 111, 167), (0, 111, 167), (0, 109, 165), (0, 109, 165), (0, 109, 165), (0, 109, 165), (0, 109, 165), (2, 109, 165), (2, 109, 165), (2, 109, 165), (0, 107, 163), (1, 106, 163), (1, 106, 163), (0, 105, 162), (0, 104, 161), (0, 104, 161), (0, 102, 160), (0, 102, 160), (0, 105, 160), (0, 105, 160), (0, 104, 159), (0, 103, 158), (0, 103, 158), (0, 102, 155), (0, 101, 155), (0, 100, 154), (0, 98, 153), (0, 97, 150), (0, 97, 150), (1, 96, 150), (1, 96, 150), (0, 95, 149), (0, 96, 147), (1, 95, 147), (1, 95, 149), (1, 95, 149), (0, 94, 148), (0, 94, 148), (0, 94, 148), (0, 94, 148), (1, 92, 145), (1, 92, 145), (0, 90, 143), (0, 90, 143), (1, 91, 143), (1, 91, 143), (1, 91, 143), (2, 92, 144), (2, 92, 144), (4, 91, 144), (0, 89, 141), (0, 89, 141), (1, 88, 141), (1, 88, 141), (0, 87, 140), (0, 87, 140), (0, 87, 140), (1, 86, 140), (0, 85, 139), (0, 85, 139), (0, 85, 139), (2, 85, 139), (2, 85, 139), (2, 85, 139), (2, 85, 139), (2, 85, 139), (0, 83, 133), (0, 83, 133), (0, 83, 133), (0, 82, 132), (0, 82, 132), (0, 82, 132), (0, 82, 132), (0, 81, 131), (0, 80, 131), (0, 80, 131), (0, 80, 131), (0, 80, 131), (0, 79, 130), (1, 78, 130), (1, 78, 130), (1, 78, 130), (0, 78, 127), (0, 76, 126), (0, 76, 126), (0, 76, 126), (0, 76, 126), (0, 75, 125), (0, 75, 125), (1, 74, 125), (1, 74, 125), (1, 74, 125), (2, 73, 125), (1, 72, 124), (1, 72, 124), (1, 72, 124), (0, 71, 123), (0, 71, 123), (0, 71, 121), (0, 71, 121), (0, 71, 121), (0, 71, 121), (0, 69, 120), (0, 69, 120), (0, 69, 120), (0, 69, 120), (0, 67, 119), (0, 67, 119), (0, 66, 118), (0, 66, 118), (0, 66, 118), (0, 65, 117), (0, 65, 117), (0, 65, 117), (1, 65, 113), (1, 65, 113), (1, 65, 113), (0, 64, 112), (0, 64, 112), (0, 64, 112), (0, 62, 111), (0, 62, 111), (1, 63, 112), (1, 63, 112), (1, 61, 111), (1, 61, 111), (0, 60, 110), (0, 59, 109), (0, 59, 109)]
9
+
10
+ reds = [(255, 254, 255), (255, 254, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), (254, 255, 255), (254, 255, 255), (255, 255, 255), (254, 254, 254), (253, 251, 252), (252, 248, 247), (250, 244, 244), (249, 240, 241), (248, 238, 239), (248, 236, 238), (248, 236, 238), (255, 228, 227), (255, 225, 225), (253, 221, 222), (252, 218, 219), (252, 216, 216), (252, 212, 213), (250, 208, 209), (251, 205, 207), (253, 203, 204), (254, 199, 202), (254, 195, 197), (254, 192, 195), (254, 190, 191), (253, 187, 189), (252, 183, 186), (250, 181, 184), (253, 177, 177), (252, 174, 174), (250, 170, 171), (249, 167, 169), (250, 164, 165), (249, 160, 162), (248, 156, 157), (251, 152, 155), (251, 148, 151), (251, 145, 149), (251, 141, 144), (252, 137, 142), (252, 136, 139), (253, 132, 137), (252, 129, 134), (249, 126, 131), (253, 120, 125), (252, 119, 122), (251, 116, 120), (249, 113, 117), (249, 108, 114), (248, 105, 109), (248, 101, 107), (249, 98, 103), (251, 96, 102), (251, 92, 97), (251, 88, 93), (250, 85, 91), (251, 82, 89), (250, 79, 85), (246, 75, 81), (246, 73, 79), (252, 67, 75), (250, 63, 72), (247, 60, 69), (248, 57, 65), (249, 55, 64), (249, 52, 62), (248, 48, 58), (249, 45, 56), (248, 41, 51), (249, 38, 47), (249, 33, 44), (248, 31, 40), (249, 27, 38), (248, 24, 35), (246, 20, 32),
11
+ (244, 18, 29), (247, 18, 25), (247, 18, 25), (247, 16, 24), (247, 16, 24), (246, 15, 23), (249, 15, 24), (249, 15, 24), (249, 15, 24), (246, 15, 23), (247, 16, 24), (246, 17, 24), (244, 17, 24), (243, 18, 24), (241, 18, 23), (238, 17, 22), (238, 17, 22), (236, 17, 23), (235, 16, 22), (235, 16, 22), (232, 15, 23), (231, 16, 23), (229, 16, 22), (226, 15, 21), (225, 16, 21), (221, 14, 20), (220, 15, 20), (219, 16, 20), (216, 15, 21), (214, 15, 20), (214, 15, 20), (211, 15, 19), (211, 15, 19), (208, 15, 18), (208, 15, 18), (207, 14, 19), (205, 14, 19), (203, 14, 18), (200, 14, 19), (199, 14, 19), (198, 15, 20), (193, 12, 17), (192, 13, 19), (189, 12, 18), (188, 13, 20), (186, 13, 19), (185, 12, 18), (183, 12, 20), (183, 12, 20), (174, 13, 19), (174, 13, 19), (172, 13, 18), (171, 12, 17), (169, 13, 17), (168, 12, 16), (167, 12, 16), (166, 11, 15), (166, 11, 15), (167, 11, 15), (169, 10, 15), (170, 11, 16), (171, 10, 16), (173, 9, 16), (174, 10, 17), (175, 10, 17), (172, 11, 17), (172, 11, 17), (171, 12, 17), (171, 12, 17), (172, 13, 18), (173, 14, 18), (175, 14, 19), (176, 15, 20), (179, 16, 19), (180, 15, 19), (182, 16, 20), (185, 14, 20), (188, 15, 21), (190, 15, 20), (191, 14, 20), (191, 14, 20), (199, 14, 20), (200, 13, 20), (201, 14, 21), (204, 15, 22), (205, 14, 22), (208, 14, 23)]
12
+
13
+
14
+ purples = [(235, 233, 236), (235, 233, 236), (235, 233, 236), (236, 231, 235), (235, 230, 236), (235, 230, 236), (234, 229, 236), (234, 229, 236), (237, 229, 240), (236, 228, 239), (235, 227, 240), (236, 225, 239), (235, 224, 240), (234, 223, 239), (234, 223, 239), (233, 222, 238), (234, 221, 239), (233, 220, 238), (232, 219, 237), (232, 219, 237), (230, 217, 237), (230, 217, 237), (230, 215, 238), (229, 214, 237), (228, 212, 238), (229, 211, 237), (228, 209, 237), (228, 209, 237), (226, 207, 237), (226, 207, 237), (225, 206, 236), (225, 204, 235), (225, 200, 239), (225, 200, 239), (224, 199, 238), (223, 198, 237), (223, 196, 237), (222, 195, 236), (223, 194, 238), (222, 193, 237), (222, 190, 237), (222, 190, 237), (222, 188, 238), (221, 187, 237), (221, 184, 236), (220, 183, 235), (219, 182, 234), (218, 181, 233), (218, 179, 236), (218, 179, 236), (217, 177, 237), (216, 176, 236), (215, 173, 236), (214, 172, 235), (215, 170, 235), (215, 170, 237), (214, 167, 237), (213, 166, 236), (214, 164, 237), (213, 162, 237), (213, 160, 238), (211, 158, 236), (210, 157, 235), (210, 157, 235), (210, 155, 238), (209, 154, 237), (210, 152, 237), (209, 151, 236), (208, 150, 237), (207, 147, 235), (206, 146, 236), (208, 144, 238), (206, 142, 238), (206, 140, 238), (205, 139, 237), (205, 137, 238), (204, 136, 239), (205, 134, 238), (204, 133, 237), (203, 132, 238), (202, 128, 239), (202, 128, 239), (203, 126, 238), (201, 124, 238), (200, 123, 237),
15
+ (200, 121, 238), (199, 120, 239), (199, 118, 238), (197, 116, 237), (198, 114, 238), (197, 112, 239), (197, 111, 238), (195, 108, 238), (196, 106, 238), (195, 105, 237), (195, 105, 237), (192, 102, 236), (191, 101, 235), (191, 99, 236), (190, 98, 235), (189, 96, 236), (189, 95, 235), (188, 93, 235), (189, 91, 236), (187, 89, 236), (188, 88, 238), (187, 87, 237), (187, 84, 237), (186, 82, 237), (186, 81, 236), (185, 80, 235), (184, 78, 236), (182, 76, 236), (183, 75, 236), (182, 74, 237), (181, 73, 236), (179, 71, 235), (180, 69, 234), (179, 68, 235), (180, 67, 237), (181, 65, 238), (181, 64, 239), (181, 62, 238), (180, 61, 239), (178, 59, 239), (178, 57, 238), (177, 56, 237), (176, 55, 238), (176, 52, 238), (175, 51, 237), (175, 50, 238), (174, 49, 237), (174, 48, 236), (173, 46, 237), (174, 45, 236), (174, 44, 238), (173, 41, 236), (172, 40, 237), (174, 39, 238), (173, 38, 237), (173, 36, 236), (172, 35, 237), (171, 34, 236), (171, 34, 236), (169, 31, 238), (168, 30, 237), (169, 29, 239), (168, 28, 238), (167, 27, 237), (166, 26, 237), (165, 25, 236), (167, 24, 238), (166, 23, 237), (165, 22, 238), (164, 21, 237), (165, 19, 239), (163, 17, 237), (163, 17, 238), (162, 16, 237), (161, 15, 236), (163, 12, 239), (162, 11, 238), (162, 11, 238), (161, 10, 237), (161, 10, 237), (160, 9, 238), (160, 7, 237), (160, 7, 237), (158, 5, 235), (160, 4, 236), (160, 4, 236), (159, 3, 235), (158, 2, 234), (158, 2, 234), (158, 0, 235)]
16
+
17
+ yellows = [(250, 248, 249), (249, 247, 248), (249, 247, 248), (249, 247, 248), (249, 248, 246), (248, 247, 245), (248, 247, 243), (248, 247, 243), (248, 247, 242), (248, 247, 242), (248, 248, 240), (248, 248, 240), (248, 248, 238), (248, 248, 238), (248, 248, 238), (248, 248, 238), (250, 248, 235), (250, 248, 235), (250, 248, 233), (250, 248, 233), (250, 249, 231), (250, 249, 231), (250, 249, 229), (250, 249, 228), (248, 248, 224), (248, 248, 222), (248, 248, 222), (248, 248, 220), (248, 249, 218), (248, 249, 218), (248, 249, 218), (248, 249, 217), (252, 249, 214), (252, 249, 214), (252, 249, 214), (251, 249, 211), (251, 249, 211), (251, 249, 210), (250, 248, 207), (250, 248, 207), (250, 249, 205), (250, 249, 203), (250, 249, 201), (250, 250, 200), (249, 249, 199), (249, 249, 197), (249, 249, 197), (249, 249, 197), (250, 249, 193), (250, 249, 192), (250, 249, 192), (250, 250, 190), (249, 249, 187), (249, 249, 187), (249, 249, 185), (249, 250, 182), (249, 250, 180), (249, 251, 178), (248, 250, 175), (248, 251, 174), (248, 251, 174), (247, 250, 171), (247, 250, 169), (247, 250, 169), (248, 250, 167), (250, 249, 166), (250, 249, 166), (249, 249, 163), (249, 249, 161), (249, 249, 161), (248, 248, 158), (249, 248, 155), (249, 249, 153), (249, 249, 151), (251, 249, 149), (250, 248, 147), (250, 248, 147), (250, 248, 145), (250, 249, 143), (249, 248, 142), (247, 249, 139), (247, 250, 137), (247, 250, 137), (249, 249, 135), (248, 249, 132), (248, 249, 132), (248, 249, 130),
18
+ (248, 250, 127), (250, 250, 126), (249, 250, 123), (249, 250, 122), (250, 250, 120), (250, 250, 120), (249, 249, 117), (249, 249, 115), (249, 249, 115), (249, 250, 112), (249, 250, 110), (248, 249, 109), (248, 250, 107), (248, 250, 105), (249, 248, 104), (249, 249, 103), (249, 249, 99), (248, 249, 96), (249, 248, 95), (249, 249, 93), (248, 248, 90), (248, 248, 90), (248, 248, 88), (250, 248, 86), (249, 247, 85), (249, 250, 84), (251, 250, 84), (251, 250, 84), (251, 250, 82), (250, 249, 79), (250, 250, 78), (250, 250, 76), (250, 249, 73), (249, 248, 70), (249, 248, 69), (250, 248, 67), (250, 248, 65), (249, 248, 62), (249, 248, 62), (249, 248, 60), (249, 248, 60), (251, 248, 57), (251, 248, 57), (250, 247, 54), (250, 247, 54), (250, 248, 52), (249, 247, 51), (249, 247, 50), (249, 247, 48), (250, 249, 47), (250, 249, 45), (249, 248, 44), (249, 248, 42), (249, 249, 41), (249, 249, 41), (248, 248, 40), (248, 248, 38), (250, 249, 35), (250, 249, 35), (250, 249, 35), (249, 248, 33), (249, 248, 33), (249, 249, 31), (248, 248, 28), (248, 248, 28), (248, 248, 26), (248, 249, 25), (248, 249, 23), (248, 249, 21), (248, 249, 21), (248, 250, 19), (248, 250, 19), (248, 250, 19), (249, 249, 15), (249, 249, 15), (249, 249, 15), (249, 249, 15), (249, 249, 13), (249, 249, 13), (249, 249, 11), (249, 249, 11), (249, 250, 9), (249, 250, 9), (249, 250, 8), (249, 250, 8), (248, 249, 5), (248, 249, 5), (248, 249, 5), (248, 249, 5), (248, 248, 0), (248, 248, 0), (248, 248, 0), (248, 248, 0)]
19
+
20
+ rainbow = [(118, 16, 11), (120, 17, 12), (125, 18, 10), (131, 20, 11), (140, 23, 13), (149, 26, 11), (158, 28, 12), (166, 29, 10), (175, 34, 7), (184, 36, 6), (193, 41, 4), (200, 44, 3), (206, 48, 3), (212, 52, 4), (218, 57, 5), (222, 61, 7), (234, 65, 0), (237, 68, 0), (243, 72, 2), (246, 74, 2), (248, 76, 2), (250, 77, 1), (252, 79, 2), (255, 81, 0), (255, 81, 0), (255, 83, 0), (255, 84, 0), (255, 86, 1), (255, 86, 1), (255, 87, 2), (255, 89, 3), (255, 89, 3), (253, 90, 0), (254, 91, 0), (254, 91, 0), (255, 92, 1), (255, 92, 1), (254, 94, 0), (254, 94, 0), (254, 94, 0), (254, 94, 0), (253, 95, 0), (254, 96, 0), (254, 96, 0), (255, 97, 0), (255, 98, 1), (255, 100, 0), (255, 100, 0), (255, 101, 3), (254, 102, 1), (255, 104, 3), (255, 106, 3), (255, 109, 5), (255, 111, 4), (255, 114, 4), (255, 115, 2), (254, 118, 0), (255, 121, 0), (254, 124, 0), (254, 126, 0), (252, 127, 0), (253, 128, 0), (254, 131, 1), (255, 134, 1), (252, 136, 0), (254, 138, 1), (254, 141, 1), (255, 144, 2), (254, 145, 2), (254, 148, 0), (253, 152, 0), (254, 155, 0), (253, 159, 1), (254, 162, 1), (253, 166, 1), (253, 168, 0), (252, 170, 0), (253, 173, 0), (255, 175, 0), (255, 178, 2), (251, 186, 0), (252, 187, 1), (252, 189, 0), (255, 192, 3), (254, 195, 3), (255, 198, 3), (255, 201, 4), (253, 205, 1), (255, 209, 2), (253, 211, 2), (253, 213, 1), (253, 217, 1), (253, 220, 1), (255, 223, 1), (254, 224, 2), (255, 226, 2), (252, 230, 0), (252, 230, 0), (252, 231, 0), (251, 233, 1), (252, 236, 1), (251, 239, 3), (248, 241, 2), (245, 243, 2), (244, 245, 3), (241, 247, 1), (239, 248, 1), (238, 250, 2), (236, 251, 0), (236, 253, 1), (234, 253, 1), (233, 254, 1), (228, 255, 0), (225, 255, 0), (224, 254, 0), (223, 254, 0), (222, 255, 0), (219, 254, 1), (215, 255, 0), (213, 254, 0), (210, 255, 0), (208, 255, 1), (204, 255, 0), (202, 255, 1), (199, 255, 0), (198, 255, 0), (195, 255, 1), (194, 254, 0), (186, 255, 0), (183, 254, 0), (177, 254, 0), (169, 254, 2), (164, 255, 4), (156, 255, 6), (150, 254, 7), (146, 254, 8), (137, 251, 6), (129, 250, 7), (120, 249, 9), (109, 247, 11), (97, 247, 15), (87, 247, 17), (78, 245, 17), (72, 245, 16), (53, 245, 22), (49, 243, 24), (43, 240, 26), (37, 239, 31), (30, 239, 36), (23, 237, 41), (15, 236, 43), (9, 235, 47),
21
+ (5, 238, 51), (3, 238, 57), (2, 239, 63), (2, 239, 71), (2, 238, 78), (3, 237, 86), (5, 237, 93), (5, 236, 96), (2, 239, 109), (2, 238, 112), (3, 238, 120), (4, 237, 128), (6, 238, 139), (8, 238, 148), (6, 238, 154), (6, 237, 159), (5, 235, 162), (5, 237, 164), (5, 235, 170), (6, 235, 176), (6, 234, 181), (7, 234, 188), (7, 233, 193), (5, 234, 195), (4, 231, 204), (6, 230, 204), (6, 230, 206), (6, 229, 208), (6, 229, 211), (6, 228, 215), (6, 227, 218), (7, 226, 222), (7, 225, 226), (7, 224, 229), (8, 222, 232), (7, 220, 234), (5, 218, 236), (3, 215, 236), (3, 215, 237), (3, 215, 237), (6, 209, 239), (6, 207, 237), (4, 204, 237), (3, 201, 236), (4, 200, 238), (5, 196, 238), (5, 193, 238), (5, 189, 239), (6, 186, 239), (7, 183, 240), (8, 180, 242), (7, 176, 241), (6, 173, 241), (6, 171, 239), (5, 167, 239), (4, 166, 238), (5, 161, 238), (4, 160, 237), (5, 158, 236), (4, 155, 236), (3, 152, 236), (3, 149, 235), (5, 146, 236), (5, 144, 237), (6, 140, 237), (6, 138, 239), (8, 135, 240), (7, 132, 240), (7, 129, 240), (6, 126, 238), (5, 125, 238), (6, 123, 237), (5, 118, 238), (5, 115, 236), (3, 113, 236), (2, 110, 236), (4, 109, 237), (4, 105, 239), (4, 102, 239), (5, 98, 238), (3, 93, 239), (5, 91, 240), (7, 88, 240), (5, 84, 237), (4, 81, 237), (3, 77, 234), (3, 75, 235), (2, 74, 234), (8, 66, 238), (7, 64, 239), (6, 63, 238), (5, 61, 236), (3, 58, 236), (3, 55, 235), (4, 52, 236), (5, 50, 237), (6, 47, 237), (9, 43, 238), (10, 39, 237), (10, 36, 235), (12, 33, 236), (15, 31, 238), (16, 31, 238), (18, 30, 238), (23, 24, 238), (24, 23, 238), (26, 23, 238), (27, 20, 237), (32, 18, 237), (35, 15, 236), (38, 13, 236), (42, 11, 236), (44, 7, 234), (48, 7, 235), (51, 5, 235), (53, 6, 236), (54, 5, 236), (57, 5, 237), (57, 5, 237), (58, 4, 237), (63, 4, 236), (65, 6, 238), (68, 6, 239), (69, 5, 239), (71, 5, 237), (73, 3, 237), (77, 5, 237), (81, 5, 238), (82, 4, 237), (85, 3, 237), (87, 3, 236), (91, 3, 237), (94, 5, 237), (98, 6, 239), (99, 5, 239), (99, 5, 239), (106, 4, 238), (106, 4, 236), (108, 4, 237), (111, 5, 238), (113, 5, 239), (116, 4, 238), (118, 4, 239), (121, 3, 237), (123, 4, 236), (128, 4, 238), (131, 5, 237), (134, 4, 238), (136, 4, 238), (137, 3, 237), (141, 5, 239), (143, 7, 241), (143, 6, 236), (143, 6, 236)]
fractal/ifs.py ADDED
@@ -0,0 +1,98 @@
1
+ """
2
+ 迭代函数系统(IFS)
3
+ """
4
+ from random import random
5
+ from math import sin, cos
6
+ from .base import Base, HAS_NUMPY
7
+
8
+
9
+ def getIfsCode(matrix):
10
+ # 极坐标形式变换到矩阵
11
+ res = []
12
+ for i in matrix:
13
+ r, s, the, fu, e, f, p = i
14
+ item = [r * cos(the), -s * sin(fu), r * sin(the), s * cos(fu), e, f, p]
15
+ res.append(item)
16
+ return res
17
+
18
+
19
+ class IFS(Base):
20
+
21
+ def __init__(self, size, title="", color=None):
22
+ Base.__init__(self, size, self._run, title)
23
+ self.setPx()
24
+ self.setIfsCode()
25
+ self.__coo = True
26
+ if color:
27
+ self.color = color
28
+ else:
29
+ self.color = [255, 255, 255]
30
+ self.fill(self.color)
31
+
32
+ def setCoordinate(self):
33
+ # 纵轴的反向
34
+ self.__coo = not self.__coo
35
+
36
+ def ifsp(self, x, y):
37
+ # 变换规则(返回迭代后的坐标)
38
+ return (x, y)
39
+
40
+ def setIfsp(self, call):
41
+ self.ifsp = call
42
+
43
+ def setIfsCode(self, ifsCode=None):
44
+ # 设置ifs码
45
+ self.ifsCode = ifsCode
46
+ if ifsCode != None:
47
+ p = [i[-1] for i in self.ifsCode]
48
+ self.__fn = len(p)
49
+ sp = sum(p)
50
+ self.__pe = [sum(p[:i + 1])/sp for i in range(self.__fn)]
51
+
52
+ def __parseIfsCode(self, x, y):
53
+ rand = random()
54
+ i = 0
55
+ while i < self.__fn:
56
+ if rand <= self.__pe[i]:
57
+ a, b, c, d, e, f, p = self.ifsCode[i]
58
+ return (a * x + b * y + e, c * x + d * y + f)
59
+ i += 1
60
+ return (0, 0)
61
+
62
+ def setPx(self, enlarge=1, pl=0, pt=0):
63
+ # 平移、放大调整
64
+ self.enlarge = enlarge
65
+ self.pl = pl
66
+ self.pt = pt
67
+
68
+ def _run(self):
69
+ start = self.start
70
+ for i in range(self.n):
71
+ px = int(self.enlarge * start[0] + self.pl)
72
+ py = int(self.enlarge * start[1] + self.pt)
73
+ if not self.__coo:
74
+ py = self.height - py
75
+ if HAS_NUMPY and self._pixel_array is not None:
76
+ if 0 <= px < self.width and 0 <= py < self.height:
77
+ self._pixel_array[py, px] = [int(self.pcolor[0]), int(self.pcolor[1]), int(self.pcolor[2])]
78
+ else:
79
+ self.set_pixel_fast(px, py, self.pcolor[0], self.pcolor[1], self.pcolor[2])
80
+ start = self.ifsp(*start)
81
+
82
+ def doIFS(self, n, start=None, color=None):
83
+ """
84
+ 开始迭代
85
+ start: 迭代起点
86
+ color: 描点的颜色
87
+ """
88
+ self.n = n
89
+ if start == None:
90
+ self.start = (0, 0)
91
+ else:
92
+ self.start = start
93
+ if color == None:
94
+ self.pcolor = [0, 0, 0]
95
+ else:
96
+ self.pcolor = color
97
+ if self.ifsCode != None:
98
+ self.ifsp = self.__parseIfsCode
fractal/julia.py ADDED
@@ -0,0 +1,106 @@
1
+ """
2
+ Julia集
3
+ """
4
+
5
+ from .base import Base, HAS_NUMPY
6
+ from .colors import *
7
+ from threading import Thread
8
+
9
+
10
+ class Julia(Base):
11
+
12
+ def __init__(self, size, title=""):
13
+ Base.__init__(self, size, self._run, title)
14
+ self.setExp(2)
15
+ self.setC(None)
16
+ self.setRadius(2)
17
+ self.width = size[0]
18
+ self.height = size[1]
19
+ self.setRange(3.5, 3.5)
20
+ self.setCentre(0 + 0j)
21
+
22
+ def setRadius(self, R):
23
+ # 设置逃逸半径
24
+ self.R = R
25
+
26
+ def setC(self, C):
27
+ # 设置参考值C
28
+ self.C = C
29
+
30
+ def setExp(self, expc):
31
+ # 设置指数,默认2
32
+ self.expc = expc
33
+
34
+ def color(self, n, r=2):
35
+ if n < len(reds):
36
+ return reds[n]
37
+ else:
38
+ if r < self.R:
39
+ return blues[int((len(blues) - 1) * r / self.R)]
40
+ else:
41
+ return purples[int((len(purples) - 1) * self.R / r)]
42
+
43
+ def setColor(self, call):
44
+ self.color = call
45
+
46
+ def setCentre(self, z0):
47
+ # 设置中心点
48
+ self.z0 = z0
49
+
50
+ def setRange(self, xmax, ymax):
51
+ # 设置坐标范围,范围越小图放大倍数越高
52
+ self.xmax = xmax
53
+ self.ymax = ymax
54
+
55
+ def __getXY(self, i, j):
56
+ # 通过像素坐标获取映射后的坐标
57
+ return complex((i / self.width - 0.5) * self.xmax + self.z0.real,
58
+ (j / self.height - 0.5) * self.ymax + self.z0.imag)
59
+
60
+ def scala(self, i, j, rate):
61
+ # 将(i, j)像素点置于中心位置,放大rete倍
62
+ self.setCentre(self.__getXY(i, j))
63
+ self.xmax /= rate
64
+ self.ymax /= rate
65
+
66
+ def __calc(self, start, w, h):
67
+ """计算子区域像素"""
68
+ for i in range(start[0], start[0] + w):
69
+ for j in range(start[1], start[1] + h):
70
+ ct = 0
71
+ z = self.__getXY(i, j)
72
+ for k in range(self.N):
73
+ ct = k
74
+ if abs(z) > self.R:
75
+ break
76
+ z = z**self.expc + self.C
77
+ col = self.color(ct, abs(z))
78
+ # 直接写入numpy数组
79
+ if HAS_NUMPY and self._pixel_array is not None:
80
+ self._pixel_array[j, i] = [int(col[0]), int(col[1]), int(col[2])]
81
+ else:
82
+ self.set_pixel_fast(i, j, col[0], col[1], col[2])
83
+
84
+ def _run(self):
85
+ # 线程中
86
+ print("x range :[-%.2e,%.2e]\ny range :[-%.2e,%.2e]" % (
87
+ self.xmax, self.xmax, self.ymax, self.ymax))
88
+ if self.C == None:
89
+ raise Exception("请设置迭代常数")
90
+ tn = 5 # 25 个子线程绘图
91
+ ci = self.width // tn
92
+ cj = self.height // tn
93
+ ts = []
94
+ for i in range(tn):
95
+ for j in range(tn):
96
+ t = Thread(target=self.__calc, args=([i * ci, j * cj], ci, cj))
97
+ t.start()
98
+ ts.append(t)
99
+ for t in ts:
100
+ t.join()
101
+ del ts
102
+
103
+ def doJulia(self, N):
104
+ # 进入迭代
105
+ # N: 单点最大迭代次数
106
+ self.N = N
fractal/lsystem.py ADDED
@@ -0,0 +1,117 @@
1
+ """
2
+ L-System for fractal
3
+ 已完成功能:
4
+ 1.简单D0L-系统
5
+ 2.合成D0L-系统
6
+ 3.简单分叉结构
7
+ 待完成功能:
8
+ 1.带年龄树(分叉)的生成
9
+ 2.随机L-系统
10
+ 3.参数L-系统
11
+ """
12
+
13
+ from math import sin, cos, pi
14
+ from .base import Base
15
+
16
+
17
+ def left(screen, st, angle, d):
18
+ # st: 起点坐标
19
+ # angle: 向左偏转的度数
20
+ # d: 距离
21
+ angle = pi * angle / 180
22
+ return [st[0] + d * cos(angle), st[1] - d * sin(angle)]
23
+
24
+
25
+ class Pen(Base):
26
+
27
+ def __init__(self, size, title=""):
28
+ # size 画布的宽高 [width, hight]
29
+ # title 画布标题
30
+ Base.__init__(self, size, self._run, title)
31
+ self.setPoint([size[0] / 2, size[1] / 2])
32
+ self.setColor([0, 0, 0])
33
+ self.setWidth(1)
34
+ self.setAngle(0)
35
+
36
+ def setAngle(self, angle):
37
+ self.angle = angle
38
+
39
+ def setPoint(self, pos):
40
+ # 设置笔的位置
41
+ self.pos = pos
42
+
43
+ def setWidth(self, width):
44
+ # 设置线宽
45
+ self.width = width
46
+
47
+ def setColor(self, color):
48
+ # 设置颜色
49
+ self.color = color
50
+
51
+ def left(self, angle):
52
+ # 向左转angle度
53
+ self.angle = self.angle + angle
54
+
55
+ def right(self, angle):
56
+ # 向右转angle度
57
+ self.angle = self.angle - angle
58
+
59
+ def forward(self, d):
60
+ # 向前走d步长
61
+ np = left(self.canvas, self.pos, self.angle, d)
62
+ self.draw_line(self.pos, np, self.color, self.width)
63
+ self.pos = np
64
+
65
+ def _run(self):
66
+ # 线程
67
+ self.draw(self.omega, self.P, self.delta, self.length)
68
+
69
+ def draw(self, omega, P, delta, length):
70
+ i = 0
71
+ while i < len(omega):
72
+ if omega[i] == '+':
73
+ self.left(delta)
74
+ elif omega[i] == '-':
75
+ self.right(delta)
76
+ elif omega[i] == '[':
77
+ k = 0
78
+ st = i
79
+ while i < len(omega):
80
+ if omega[i] == "[":
81
+ k += 1
82
+ elif omega[i] == "]":
83
+ k -= 1
84
+ if k == 0:
85
+ break
86
+ i += 1
87
+ sub = omega[st + 1:i]
88
+ curpoint = self.pos[:]
89
+ curangle = self.angle
90
+ self.draw(sub, P, delta, length)
91
+ self.pos = curpoint
92
+ self.angle = curangle
93
+ else:
94
+ self.forward(length)
95
+ i += 1
96
+
97
+ def doD0L(self, omega, P, delta, times, length, rate):
98
+ # omega: 公理(初始字符串)
99
+ # P: 产生式(映射规则)
100
+ # delta: 角度增量
101
+ # times: 迭代次数
102
+ # length: 初始线长
103
+ # rate: 每次迭代后缩小的倍数
104
+ length /= (rate**times)
105
+ for i in range(times): # 完成字符串迭代
106
+ ct = 0
107
+ for key in P:
108
+ omega = omega.replace(key, str(ct))
109
+ ct += 1
110
+ ct = 0
111
+ for key in P:
112
+ omega = omega.replace(str(ct), P[key])
113
+ ct += 1
114
+ self.omega = omega
115
+ self.P = P
116
+ self.delta = delta
117
+ self.length = length
fractal/mandelbrot.py ADDED
@@ -0,0 +1,105 @@
1
+ """
2
+ Mandelbrot集
3
+ """
4
+
5
+ from .base import Base, HAS_NUMPY
6
+ from .colors import *
7
+ from threading import Thread
8
+
9
+
10
+ class Mandelbrot(Base):
11
+
12
+ def __init__(self, size, title=""):
13
+ Base.__init__(self, size, self._run, title)
14
+ self.setExp(2)
15
+ self.setRadius(2)
16
+ self.setZ0(0 + 0j)
17
+ self.width = size[0]
18
+ self.height = size[1]
19
+ self.setRange(3.5, 3.5)
20
+ self.setCentre(0 + 0j)
21
+
22
+ def setRadius(self, R):
23
+ # 设置逃逸半径
24
+ self.R = R
25
+
26
+ def setZ0(self, Z0):
27
+ # 设置起始迭代复数(一般为0+0j)
28
+ self.Z0 = Z0
29
+
30
+ def setCentre(self, z0):
31
+ # 设置中心点
32
+ self.z0 = z0
33
+
34
+ def setRange(self, xmax, ymax):
35
+ # 设置坐标范围,范围越小图放大倍数越高
36
+ self.xmax = xmax
37
+ self.ymax = ymax
38
+
39
+ def __getXY(self, i, j):
40
+ # 通过像素坐标获取映射后的坐标
41
+ return complex((i / self.width - 0.5) * self.xmax + self.z0.real,
42
+ (j / self.height - 0.5) * self.ymax + self.z0.imag)
43
+
44
+ def scala(self, i, j, rate):
45
+ # 将(i, j)像素点置于中心位置,放大rete倍
46
+ self.setCentre(self.__getXY(i, j))
47
+ self.xmax /= rate
48
+ self.ymax /= rate
49
+
50
+ def setExp(self, expc):
51
+ # 设置指数,默认2
52
+ self.expc = expc
53
+
54
+ def color(self, n, r=2):
55
+ if n < len(reds):
56
+ return reds[n]
57
+ else:
58
+ if r < self.R:
59
+ return blues[int((len(blues) - 1) * r / self.R)]
60
+ else:
61
+ return purples[int((len(purples) - 1) * self.R / r)]
62
+
63
+ def setColor(self, call):
64
+ self.color = call
65
+
66
+ def __calc(self, start, w, h):
67
+ """计算子区域像素"""
68
+ for i in range(start[0], start[0] + w):
69
+ for j in range(start[1], start[1] + h):
70
+ ct = 0
71
+ z = self.Z0
72
+ c = self.__getXY(i, j)
73
+ for k in range(self.N):
74
+ ct = k
75
+ if abs(z) > self.R:
76
+ break
77
+ z = z**self.expc + c
78
+ col = self.color(ct, abs(z))
79
+ # 直接写入numpy数组
80
+ if HAS_NUMPY and self._pixel_array is not None:
81
+ self._pixel_array[j, i] = [int(col[0]), int(col[1]), int(col[2])]
82
+ else:
83
+ self.set_pixel_fast(i, j, col[0], col[1], col[2])
84
+
85
+ def _run(self):
86
+ # 绘图
87
+ print("x range :[-%.2e,%.2e]\ny range :[-%.2e,%.2e]" % (
88
+ self.xmax, self.xmax, self.ymax, self.ymax))
89
+ tn = 5 # 25 个子线程绘图
90
+ ci = self.width // tn
91
+ cj = self.height // tn
92
+ ts = []
93
+ for i in range(tn):
94
+ for j in range(tn):
95
+ t = Thread(target=self.__calc, args=([i * ci, j * cj], ci, cj))
96
+ t.start()
97
+ ts.append(t)
98
+ for t in ts:
99
+ t.join()
100
+ del ts
101
+
102
+ def doMandelbrot(self, N):
103
+ # 开始迭代
104
+ # N: 最大迭代次数
105
+ self.N = N
@@ -0,0 +1,291 @@
1
+ Metadata-Version: 2.4
2
+ Name: fractal
3
+ Version: 0.5.0
4
+ Summary: 分形绘图库,支持Julia集、Mandelbrot集、IFS、L-System等
5
+ Home-page: https://github.com/pysrc/fractal
6
+ Author: L.Chen
7
+ Author-email: 1570184051@qq.com
8
+ License: MIT
9
+ Keywords: fractal,分形,Julia,Mandelbrot,IFS,L-System
10
+ Platform: any
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Intended Audience :: Science/Research
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.6
18
+ Classifier: Programming Language :: Python :: 3.7
19
+ Classifier: Programming Language :: Python :: 3.8
20
+ Classifier: Programming Language :: Python :: 3.9
21
+ Classifier: Programming Language :: Python :: 3.10
22
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
23
+ Classifier: Topic :: Multimedia :: Graphics
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Requires-Dist: Pillow>=8.0.0
27
+ Requires-Dist: numpy>=1.20.0
28
+ Dynamic: author
29
+ Dynamic: author-email
30
+ Dynamic: classifier
31
+ Dynamic: description
32
+ Dynamic: description-content-type
33
+ Dynamic: home-page
34
+ Dynamic: keywords
35
+ Dynamic: license
36
+ Dynamic: license-file
37
+ Dynamic: platform
38
+ Dynamic: requires-dist
39
+ Dynamic: summary
40
+
41
+ # Draw Fractal Image By Python
42
+
43
+ A Python fractal drawing library supporting Julia Set, Mandelbrot Set, IFS, L-System and more.
44
+
45
+ ## Install
46
+
47
+ ```bash
48
+ pip install fractal
49
+ ```
50
+
51
+ Or download the package:
52
+
53
+ ```bash
54
+ pip install -e .
55
+ ```
56
+
57
+ Dependencies:
58
+ - Pillow >= 8.0.0
59
+ - numpy >= 1.20.0
60
+
61
+ ## Features
62
+
63
+ - **Julia Set** - Interactive zoom with mouse
64
+ - **Mandelbrot Set** - Classic Mandelbrot fractal
65
+ - **IFS** - Iterated Function System (fern, leaf, tree, etc.)
66
+ - **L-System** - Lindenmayer System (Koch curve, dragon, tree, etc.)
67
+ - **CIFS** - Complex Iterated Function System
68
+
69
+ ## GUI Operations
70
+
71
+ - **Save**: Click "Save" button or Ctrl+P
72
+ - **Save As**: Click "Save As..." to choose format (PNG/JPG/BMP)
73
+ - **Zoom In**: Left click to show selection box, drag to move, click again to confirm
74
+ - **Zoom Out**: Right click
75
+ - **Cancel Selection**: Press ESC or right click
76
+
77
+ ## Examples
78
+
79
+ ### L-System
80
+
81
+ ```python
82
+ from fractal import Pen
83
+ from math import sqrt
84
+ p = Pen([350, 270])
85
+ p.setPoint([140, 60])
86
+ p.setWidth(1)
87
+ p.doD0L(omega="L", P={"L": "L+R", "R": "L-R"},
88
+ delta=90, times=15, length=200, rate=sqrt(2))
89
+ p.wait()
90
+ ```
91
+
92
+ ![](fenxing_images/dragon.jpg)
93
+
94
+ ```python
95
+ from fractal import Pen
96
+
97
+ p = Pen([500, 500], title="Window")
98
+ p.setPoint([495, 495])
99
+ p.setAngle(90)
100
+ p.doD0L(omega="f+f+f+f", P={"f": "ff+f--f+f"},
101
+ delta=90, times=5, length=490, rate=3)
102
+ p.wait()
103
+ ```
104
+
105
+ ![](fenxing_images/Window.jpg)
106
+
107
+ ```python
108
+ from fractal import Pen
109
+ p = Pen([420,420])
110
+ p.setPoint([10,10])
111
+ p.doD0L(omega = "L", P = {"L": "LFRFL-FF-RFLFR+FF+LFRFL", "R": "RFLFR+FF+LFRFL-FF-RFLFR"}, delta = 90, times = 4, length = 200 , rate = 3)
112
+ p.wait()
113
+ ```
114
+
115
+ ![](fenxing_images/fass2.jpg)
116
+
117
+ ```python
118
+ from fractal import Pen
119
+ p = Pen([400, 470])
120
+ p.setAngle(90)
121
+ p.setPoint([200,470])
122
+ p.doD0L(omega = "f", P = {"f": "h[-f][+f]hf", "h": "hh"}, delta = 25.7, times = 7, length = 400, rate = 2.17)
123
+ p.wait()
124
+ ```
125
+
126
+ ![](fenxing_images/tree4.jpg)
127
+
128
+ ```python
129
+ from fractal import Pen
130
+ p = Pen([400, 470])
131
+ p.setAngle(90)
132
+ p.setPoint([170, 470])
133
+ p.doD0L(omega="f", P={"f": "h+[[f]-f]-h[-hf]+f", "h": "hh"},
134
+ delta=22.5, times=6, length=400, rate=2.3)
135
+ p.wait()
136
+ ```
137
+
138
+ ![](fenxing_images/tree5.jpg)
139
+
140
+ ### IFS
141
+
142
+ ```python
143
+ from fractal import IFS
144
+ from random import random
145
+
146
+ def ifsp(x, y):
147
+ p = random()
148
+ if p < 0.01:
149
+ return (0, 0.16 * y)
150
+ elif p < 0.07:
151
+ if random() > 0.5:
152
+ return (0.21 * x - 0.25 * y, 0.25 * x + 0.21 * y + 0.44)
153
+ else:
154
+ return (-0.2 * x + 0.26 * y, 0.23 * x + 0.22 * y + 0.6)
155
+ else:
156
+ return (0.85 * x + 0.1 * y, -0.05 * x + 0.85 * y + 0.6)
157
+
158
+ ob = IFS([400, 500], title = "Leaf")
159
+ ob.setPx(100, 100, 100)
160
+ ob.setIfsp(ifsp)
161
+ ob.doIFS(200000)
162
+ ob.wait()
163
+ ```
164
+
165
+ ![](fenxing_images/ifern.jpg)
166
+
167
+ ```python
168
+ # Box IFS
169
+ from fractal import IFS
170
+ from random import randint
171
+
172
+
173
+ def ifsp(x, y):
174
+ p = randint(1, 5)
175
+ if p == 1:
176
+ return (x / 3, y / 3)
177
+ elif p == 2:
178
+ return (x / 3 + 2 / 3, y / 3)
179
+ elif p == 3:
180
+ return (x / 3 + 1 / 3, y / 3 + 1 / 3)
181
+ elif p == 4:
182
+ return (x / 3, y / 3 + 2 / 3)
183
+ else:
184
+ return (x / 3 + 2 / 3, y / 3 + 2 / 3)
185
+
186
+ ob = IFS([500, 500], title="Box")
187
+ ob.setPx(490, 5, 5)
188
+ ob.setIfsp(ifsp)
189
+ ob.doIFS(200000)
190
+ ob.wait()
191
+ ```
192
+
193
+ ![](fenxing_images/ibox.jpg)
194
+
195
+ ```python
196
+ from fractal import IFS
197
+
198
+ ifscode = [
199
+ [0.879, 0.054, -0.051, 0.878, 0.077, 0.123, 0.123],
200
+ [0.1, -0.193, 0.285, 0.224, 0.174, 0.169, 0.169],
201
+ [0.008, 0.135, 0, 0.204, 0.075, 0.074, 0.074],
202
+ [0.402, 0.045, 0.016, -0.197, 0.111, 0.193, 0.193]
203
+ ]
204
+
205
+ ifs = IFS([500, 500])
206
+ ifs.setPx(700, 0, 0)
207
+ ifs.setIfsCode(ifscode)
208
+ ifs.doIFS(200000)
209
+ ifs.wait()
210
+ ```
211
+
212
+ ![](fenxing_images/leaf.jpg)
213
+
214
+ ```python
215
+ from fractal import IFS
216
+
217
+ code = [
218
+ [0.195, -0.488, 0.344, 0.443, 0.4431, 0.2452, 0.2],
219
+ [0.462, 0.414, -0.252, 0.361, 0.2511, 0.5692, 0.2],
220
+ [-0.637, 0, 0, 0.501, 0.8562, 0.2512, 0.2],
221
+ [-0.035, 0.07, -0.469, 0.022, 0.4884, 0.5069, 0.2],
222
+ [-0.058, -0.07, -0.453, -0.111, 0.5976, 0.0969, 0.2]
223
+ ]
224
+
225
+ ifs = IFS([500,500])
226
+ ifs.setCoordinate()
227
+ ifs.setPx(500, 0, 0)
228
+ ifs.setIfsCode(code)
229
+ ifs.doIFS(200000)
230
+ ifs.wait()
231
+ ```
232
+
233
+ ![](fenxing_images/itree.jpg)
234
+
235
+
236
+
237
+ ### Julia
238
+
239
+ ```python
240
+ from fractal import Julia
241
+ ju = Julia([500, 500])
242
+ ju.setC(0 - 1j)
243
+ ju.doJulia(500)
244
+ ju.wait()
245
+ ```
246
+
247
+ ![](fenxing_images/ju2.jpg)
248
+
249
+ **-1.25 + 0j**
250
+
251
+ ![](fenxing_images/ju6.jpg)
252
+
253
+ ![](fenxing_images/ju62.jpg)
254
+
255
+
256
+
257
+ **-0.605-0.45j**
258
+
259
+ ![](fenxing_images/(-0.605-0.45j)1.jpg)
260
+
261
+ ![](fenxing_images/(-0.605-0.45j)2.jpg)
262
+
263
+ ![](fenxing_images/(-0.605-0.45j)3.jpg)
264
+
265
+ ### Mandelbrot
266
+
267
+
268
+
269
+ ```python
270
+ from fractal import Mandelbrot
271
+ man = Mandelbrot([500, 500])
272
+ man.setRange(5, 5)
273
+ man.doMandelbrot(200)
274
+ man.wait()
275
+ ```
276
+
277
+ ![](fenxing_images/mandelbrot.jpg)
278
+
279
+ ![](fenxing_images/mandelbrot2.jpg)
280
+
281
+ ![](fenxing_images/mandelbrot3.jpg)
282
+
283
+ ![](fenxing_images/mandelbrot4.jpg)
284
+
285
+ ## License
286
+
287
+ MIT License
288
+
289
+ ## Author
290
+
291
+ L.Chen (pysrc)
@@ -0,0 +1,13 @@
1
+ fractal/__init__.py,sha256=aT4xfLoejCQqWE1nRrudKEXIP5a0osreLrPTaBxALk0,170
2
+ fractal/base.py,sha256=kqtzt01ZgmqSLIeeXJkSBsL6Z3vzTHfhJKOaeW4sGHU,15526
3
+ fractal/cifs.py,sha256=-TxYVvmLnF3OU5BtFFA3FM-zG8x-PfU6vsSzYLCmSak,2996
4
+ fractal/colors.py,sha256=3zZKljXc5x3s_Xf_nReC9xwu7kei-armjhnxwlYH1r8,19581
5
+ fractal/ifs.py,sha256=pwBViUOTHYjaynbeqbmr0_fJcla7bgfJ7hEs6M1kcB0,2815
6
+ fractal/julia.py,sha256=JReJl_KTtR5AbW1Z4Nmyk0LzDzAPM9yYBA9Lpwb65uE,3100
7
+ fractal/lsystem.py,sha256=cgTatLlprLnV1AEShPqHLU_hTd2UDqtuTVKQLoGAKlk,3221
8
+ fractal/mandelbrot.py,sha256=aAYXzOXZD8X9OAMH03yT831LWVhu2yjNukBPaY_DP7c,3083
9
+ fractal-0.5.0.dist-info/licenses/LICENSE,sha256=FVQI1mfynzIuUYjS7TllMka382YWm-oFVFwCnQfLTWU,1084
10
+ fractal-0.5.0.dist-info/METADATA,sha256=ecPS7iKVhHI_Q6Yx06ufnBwfJleMBK_IpQOkryOM074,6404
11
+ fractal-0.5.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
12
+ fractal-0.5.0.dist-info/top_level.txt,sha256=rEXdmNzoRgT8nHa7k96n4y-bmnhe0nrJ0qDl-5mnjog,8
13
+ fractal-0.5.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018 L.Chen
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ fractal