Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from math import cos, sin, dist, hypot
- from random import random
- # given a point, calculates how far it is from a square with corners (+/-1, +/-1).
- def distance_from_square(x, y):
- if y >= x and y >= -x:
- return abs(1 - y)
- elif y >= x and y < -x:
- return abs(1 + x)
- elif y < x and y < -x:
- return abs(1 + y)
- elif y < x and y >= -x:
- return abs(1 - x)
- # divide square into 16 smaller squares, place center of a whorl randomly in each one.
- charge_coords = [((i%4) / 4 + random() / 4, (i//4) / 4 + random() / 4) for i in range(16)]
- # given a point and a list of whorl centers, calculate direction of vector at that point given by sum of whorl vectors
- def force_direction(x, y, charges):
- force_x = 0
- force_y = 0
- for c in charges:
- distance_cubed = dist((x, y), c)**3
- force_x = force_x + (c[0] - x) / distance_cubed
- force_y = force_y + (c[1] - y) / distance_cubed
- norm = hypot(force_x, force_y)
- return (-force_y / norm, force_x / norm)
- # given a minimum value a, a maximum value b, and a phase, outputs the data needed to animate an SVG using a triangle wave with that phase
- def phase_offset(a, b, phase):
- if phase % 1 <= 0.5:
- value_list = [(1 - 2 * phase) * a + 2 * phase * b, a, b, (1 - 2 * phase) * a + 2 * phase * b]
- time_list = [0, phase, 0.5 + phase, 1]
- elif phase % 1 > 0.5:
- phase_adj = phase - 0.5
- value_list = [(1 - 2 * phase_adj) * b + 2 * phase_adj * a, b, a, (1 - 2 * phase_adj) * b + 2 * phase_adj * a]
- time_list = [0, phase_adj, phase, 1]
- return (value_list, time_list)
- # generate SVG
- with open('squhorls.svg', 'w') as file:
- file.write("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n")
- file.write("<svg width=\"600\" height=\"600\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n")
- for i in range(60):
- for j in range(60):
- dir_vec = force_direction(i / 60, j / 60, charge_coords)
- start_thickness = 4 / (1 + 11 * distance_from_square((i - 29.5) / 15, (j - 29.5) / 15))
- end_thickness = 1/3 * (1 + 11 * distance_from_square((i - 29.5) / 15, (j - 29.5) / 15))
- phase = (i + j) / 180
- envelope = phase_offset(start_thickness, end_thickness, phase)
- file.write("<line x1=\"{0}\" x2=\"{1}\" y1=\"{2}\" y2=\"{3}\" stroke=\"black\" stroke-width=\"{4}\">\n".format(10 * (i + 1), 10 * (i + 1) + 7 * dir_vec[0], 10 * (j + 1), 10 * (j+1) + 7 * dir_vec[1], start_thickness))
- file.write("<animate attributeName=\"stroke-width\" values=\"{0};{1};{2};{3}\" keyTimes=\"{4};{5};{6};{7}\" dur=\"6s\" repeatCount=\"indefinite\" /> \n </line>\n".format(envelope[0][0], envelope[0][1], envelope[0][2], envelope[0][3], envelope[1][0], envelope[1][1], envelope[1][2], envelope[1][3]))
- file.write("</svg>")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement