examples
This commit is contained in:
parent
2daaf8ec93
commit
417d980a80
|
@ -0,0 +1,42 @@
|
|||
import axi
|
||||
import math
|
||||
import random
|
||||
|
||||
def circle(cx, cy, r, n):
|
||||
points = []
|
||||
for i in range(n + 1):
|
||||
a = 2 * math.pi * i / n
|
||||
x = cx + math.cos(a) * r
|
||||
y = cy + math.sin(a) * r
|
||||
points.append((x, y))
|
||||
return points
|
||||
|
||||
def random_points_on_circle(cx, cy, r, n):
|
||||
result = []
|
||||
a = random.random() * 2 * math.pi
|
||||
da = 2 * math.pi / n
|
||||
for i in range(n):
|
||||
x = cx + math.cos(a) * r
|
||||
y = cy + math.sin(a) * r
|
||||
result.append((x, y))
|
||||
a += da
|
||||
return result
|
||||
|
||||
def add(x, y, r, paths):
|
||||
if r < 1:
|
||||
return
|
||||
paths.append(circle(x, y, r, 90))
|
||||
points = random_points_on_circle(x, y, r, 2)
|
||||
for x, y in points:
|
||||
add(x, y, r / 2, paths)
|
||||
|
||||
def main():
|
||||
paths = []
|
||||
add(0, 0, 64, paths)
|
||||
drawing = axi.Drawing(paths).rotate_and_scale_to_fit(11, 8.5).sort_paths()
|
||||
im = drawing.render()
|
||||
im.write_to_png('out.png')
|
||||
axi.draw(drawing)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -0,0 +1,70 @@
|
|||
import axi
|
||||
import random
|
||||
import time
|
||||
|
||||
from math import hypot, atan2, sin, cos, pi
|
||||
|
||||
class Model(object):
|
||||
def __init__(self):
|
||||
self.particles = []
|
||||
|
||||
def add(self, x, y, m=1.0):
|
||||
self.particles.append((x, y, m))
|
||||
|
||||
def test(self, x, y):
|
||||
dx = 0
|
||||
dy = 0
|
||||
for px, py, pm in self.particles:
|
||||
d = hypot(x - px, y - py)
|
||||
if abs(d) < 1e-8:
|
||||
return (0, 0)
|
||||
angle = atan2(y - py, x - px)
|
||||
dx += pm * cos(angle) / d
|
||||
dy += pm * sin(angle) / d
|
||||
angle = atan2(dy, dx) + pi / 2
|
||||
dx = cos(angle)
|
||||
dy = sin(angle)
|
||||
return (dx, dy)
|
||||
|
||||
def polygon(sides, d):
|
||||
x = 0.5
|
||||
y = 0.5
|
||||
rotation = 0
|
||||
angle = 2 * pi / sides
|
||||
angles = [angle * i + rotation for i in range(sides)]
|
||||
return [(x + cos(a) * d, y + sin(a) * d) for a in angles]
|
||||
|
||||
def create_path(model, scale, ox, oy, x, y, m, length):
|
||||
result = []
|
||||
n = int(length * 32)
|
||||
f = float(length) / scale / n
|
||||
for j in range(n):
|
||||
result.append((ox + x * scale, oy + y * scale))
|
||||
dx, dy = model.test(x, y)
|
||||
x += dx * f * m
|
||||
y += dy * f * m
|
||||
if x < 0 or y < 0 or x > 1 or y > 1:
|
||||
break
|
||||
return result
|
||||
|
||||
def main():
|
||||
# axi.reset()
|
||||
# return
|
||||
|
||||
model = Model()
|
||||
for x, y in polygon(5, 0.35):
|
||||
model.add(x, y, 1)
|
||||
model.add(0.5, 0.5, 0.1)
|
||||
|
||||
paths = []
|
||||
for _ in range(500):
|
||||
x = random.random()
|
||||
y = random.random()
|
||||
path = create_path(model, 8.5, 1.25, 0, x, y, -1, 3)
|
||||
paths.append(path)
|
||||
|
||||
drawing = axi.Drawing(paths).sort_paths().simplify_paths(0.001)
|
||||
axi.draw(drawing)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -1,7 +1,17 @@
|
|||
import axi
|
||||
import math
|
||||
import random
|
||||
import time
|
||||
|
||||
def circle(cx, cy, radius, n, rotation):
|
||||
points = []
|
||||
for i in range(n + 1):
|
||||
a = 2 * math.pi * i / n + rotation
|
||||
x = cx + math.cos(a) * radius
|
||||
y = cy + math.sin(a) * radius
|
||||
points.append((x, y))
|
||||
return points
|
||||
|
||||
def main():
|
||||
d = axi.Device()
|
||||
d.pen_up()
|
||||
|
@ -10,9 +20,20 @@ def main():
|
|||
points = []
|
||||
points.append((0, 0))
|
||||
for i in range(10):
|
||||
x = random.random() * 11
|
||||
y = random.random() * 8.5
|
||||
points.append((x, y))
|
||||
while True:
|
||||
x = random.random() * 11
|
||||
y = random.random() * 8.5
|
||||
r = random.random() * 4
|
||||
if x - r < 0 or x + r > 11:
|
||||
continue
|
||||
if y - r < 0 or y + r > 8.5:
|
||||
continue
|
||||
break
|
||||
rotation = random.random() * 2 * math.pi
|
||||
c = circle(x, y, r, 90, rotation)
|
||||
if random.random() < 0.5:
|
||||
c = list(reversed(c))
|
||||
points.extend(c)
|
||||
points.append((0, 0))
|
||||
d.run_path(points)
|
||||
d.wait()
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
import random
|
||||
|
||||
from math import pi, sin, cos, hypot, floor
|
||||
|
||||
class Grid(object):
|
||||
def __init__(self, r):
|
||||
self.r = r
|
||||
self.size = r / 2 ** 0.5
|
||||
self.cells = {}
|
||||
|
||||
def points(self):
|
||||
return self.cells.values()
|
||||
|
||||
def normalize(self, x, y):
|
||||
i = int(floor(x / self.size))
|
||||
j = int(floor(y / self.size))
|
||||
return (i, j)
|
||||
|
||||
def nearby(self, x, y):
|
||||
result = []
|
||||
i, j = self.normalize(x, y)
|
||||
for p in xrange(i - 2, i + 3):
|
||||
for q in xrange(j - 2, j + 3):
|
||||
if (p, q) in self.cells:
|
||||
result.append(self.cells[(p, q)])
|
||||
return result
|
||||
|
||||
def insert(self, x, y):
|
||||
for bx, by in self.nearby(x, y):
|
||||
if hypot(x - bx, y - by) < self.r:
|
||||
return False
|
||||
i, j = self.normalize(x, y)
|
||||
self.cells[(i, j)] = (x, y)
|
||||
return True
|
||||
|
||||
def poisson_disc(x1, y1, x2, y2, r, n):
|
||||
x = x1 + (x2 - x1) / 2.0
|
||||
y = y1 + (y2 - y1) / 2.0
|
||||
active = [(x, y)]
|
||||
grid = Grid(r)
|
||||
grid.insert(x, y)
|
||||
while active:
|
||||
ax, ay = random.choice(active)
|
||||
for i in xrange(n):
|
||||
a = random.random() * 2 * pi
|
||||
d = random.random() * r + r
|
||||
x = ax + cos(a) * d
|
||||
y = ay + sin(a) * d
|
||||
if x < x1 or y < y1 or x > x2 or y > y2:
|
||||
continue
|
||||
if not grid.insert(x, y):
|
||||
continue
|
||||
active.append((x, y))
|
||||
break
|
||||
else:
|
||||
active.remove((ax, ay))
|
||||
return grid.points()
|
|
@ -0,0 +1,46 @@
|
|||
import axi
|
||||
import math
|
||||
import random
|
||||
|
||||
from axi.spatial import Index
|
||||
from poisson_disc import poisson_disc
|
||||
|
||||
def perturb_points(points, deviation):
|
||||
result = []
|
||||
for x, y in points:
|
||||
a = random.random() * 2 * math.pi
|
||||
r = random.gauss(0, deviation)
|
||||
x += math.cos(a) * r
|
||||
y += math.sin(a) * r
|
||||
result.append((x, y))
|
||||
return result
|
||||
|
||||
def star(x, y, r):
|
||||
sides = 5
|
||||
a = random.random() * 2 * math.pi
|
||||
angle = 2 * math.pi / sides
|
||||
angles = [angle * i + a for i in range(sides)]
|
||||
points = [(x + math.cos(a) * r, y + math.sin(a) * r) for a in angles]
|
||||
points = perturb_points(points, 0.04)
|
||||
points.append(points[0])
|
||||
return points[0::2] + points[1::2]
|
||||
|
||||
def main():
|
||||
points = poisson_disc(0, 0, 11, 8.5, 0.4, 64)
|
||||
index = Index(points)
|
||||
paths = []
|
||||
for x1, y1 in points:
|
||||
index.remove((x1, y1))
|
||||
x2, y2 = index.nearest((x1, y1))
|
||||
index.insert((x1, y1))
|
||||
d = math.hypot(x2 - x1, y2 - y1)
|
||||
paths.append(star(x1, y1, d / 2))
|
||||
drawing = axi.Drawing(paths)
|
||||
drawing = drawing.remove_paths_outside(11, 8.5)
|
||||
drawing = drawing.sort_paths()
|
||||
# im = drawing.render()
|
||||
# im.write_to_png('out.png')
|
||||
axi.draw(drawing)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Loading…
Reference in New Issue