diff --git a/.gitignore b/.gitignore index 9b42106..f05b23d 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ .direnv/ +__pycache__/ +.DS_Store diff --git a/color-3492041321645561828-0.png b/color-3492041321645561828-0.png new file mode 100644 index 0000000..57a60a4 Binary files /dev/null and b/color-3492041321645561828-0.png differ diff --git a/color-8529397126331828772-0.png b/color-8529397126331828772-0.png new file mode 100644 index 0000000..a4faeec Binary files /dev/null and b/color-8529397126331828772-0.png differ diff --git a/color-8529397126331828772-1.png b/color-8529397126331828772-1.png new file mode 100644 index 0000000..54220e4 Binary files /dev/null and b/color-8529397126331828772-1.png differ diff --git a/color-8529397126331828772-10.png b/color-8529397126331828772-10.png new file mode 100644 index 0000000..1822eef Binary files /dev/null and b/color-8529397126331828772-10.png differ diff --git a/color-8529397126331828772-11.png b/color-8529397126331828772-11.png new file mode 100644 index 0000000..f226ca8 Binary files /dev/null and b/color-8529397126331828772-11.png differ diff --git a/color-8529397126331828772-12.png b/color-8529397126331828772-12.png new file mode 100644 index 0000000..b4ac72a Binary files /dev/null and b/color-8529397126331828772-12.png differ diff --git a/color-8529397126331828772-13.png b/color-8529397126331828772-13.png new file mode 100644 index 0000000..e7cb7a4 Binary files /dev/null and b/color-8529397126331828772-13.png differ diff --git a/color-8529397126331828772-14.png b/color-8529397126331828772-14.png new file mode 100644 index 0000000..fd03e30 Binary files /dev/null and b/color-8529397126331828772-14.png differ diff --git a/color-8529397126331828772-2.png b/color-8529397126331828772-2.png new file mode 100644 index 0000000..47b2ac5 Binary files /dev/null and b/color-8529397126331828772-2.png differ diff --git a/color-8529397126331828772-3.png b/color-8529397126331828772-3.png new file mode 100644 index 0000000..6856223 Binary files /dev/null and b/color-8529397126331828772-3.png differ diff --git a/color-8529397126331828772-4.png b/color-8529397126331828772-4.png new file mode 100644 index 0000000..fa5cf06 Binary files /dev/null and b/color-8529397126331828772-4.png differ diff --git a/color-8529397126331828772-5.png b/color-8529397126331828772-5.png new file mode 100644 index 0000000..6aa949c Binary files /dev/null and b/color-8529397126331828772-5.png differ diff --git a/color-8529397126331828772-6.png b/color-8529397126331828772-6.png new file mode 100644 index 0000000..6a275e1 Binary files /dev/null and b/color-8529397126331828772-6.png differ diff --git a/color-8529397126331828772-7.png b/color-8529397126331828772-7.png new file mode 100644 index 0000000..9491db9 Binary files /dev/null and b/color-8529397126331828772-7.png differ diff --git a/color-8529397126331828772-8.png b/color-8529397126331828772-8.png new file mode 100644 index 0000000..f898480 Binary files /dev/null and b/color-8529397126331828772-8.png differ diff --git a/color-8529397126331828772-9.png b/color-8529397126331828772-9.png new file mode 100644 index 0000000..47bd96b Binary files /dev/null and b/color-8529397126331828772-9.png differ diff --git a/perlin_noise.py b/perlin_noise.py new file mode 100644 index 0000000..7f7ab8f --- /dev/null +++ b/perlin_noise.py @@ -0,0 +1,49 @@ +import math +import random +from math import pi + + +# returns the unit vector of angle +def unitVector(angle): + return (math.cos(angle), math.sin(angle)) + + +# needs to be extended for any size vector +def dotProduct(point1, point2): + return point1[0] * point2[0] + point1[1] * point2[1] + + +# interp uses a cubic function to perform a weighted average of a0 and a1 +def interp(a0, a1, w): + weight = 3*math.pow(w, 2) - 2*math.pow(w, 3) + return a0*(1-weight) + a1*weight + + +# angles provides the four gradient angles for the grid in a tuple +# starting from top left then going clockwise +# coords provides the (x, y) coordinates on the grid, assuming top left is (0, 0) +def perlinNoise(coords, gridSize, angles): + topLeftGradient = unitVector(angles[0]) + topRightGradient = unitVector(angles[1]) + bottomRightGradient = unitVector(angles[2]) + bottomLeftGradient = unitVector(angles[3]) + coords = (((coords[0] + 1) * 1000) % gridSize, + ((coords[1] + 1) * 1000) % gridSize) + topLeftVector = coords + topRightVector = (gridSize - coords[0], coords[1]) + bottomRightVector = (gridSize - coords[0], gridSize - coords[1]) + bottomLeftVector = (coords[0], gridSize - coords[1]) + topLeft = dotProduct(topLeftGradient, topLeftVector) + topRight = dotProduct(topRightGradient, topRightVector) + bottomRight = dotProduct(bottomRightGradient, bottomRightVector) + bottomLeft = dotProduct(bottomLeftGradient, bottomLeftVector) + topAverage = interp(topLeft, topRight, coords[0]/gridSize) + bottomAverage = interp(bottomLeft, bottomRight, coords[0]/gridSize) + average = interp(topAverage, bottomAverage, coords[1]/gridSize) + return average/gridSize + + +if __name__ == "__main__": + print(perlinNoise((.002, .235), 350, (random.uniform(0, 2*pi), + random.uniform(0, 2*pi), random.uniform(0, 2*pi), + random.uniform(0, 2*pi)))) diff --git a/random1.png b/random1.png deleted file mode 100644 index 4a2f341..0000000 Binary files a/random1.png and /dev/null differ diff --git a/random_art.py b/random_art.py index b13271b..ff1435c 100644 --- a/random_art.py +++ b/random_art.py @@ -1,5 +1,6 @@ import random - +from math import pi, sin, cos, tan, atan, acos, asin +import perlin_noise as pn # Your job is to create better version of create_expression and # run_expression to create random art. # Your expression should have a __str__() function defined for it. @@ -8,7 +9,34 @@ def create_expression(): """This function takes no arguments and returns an expression that generates a number between -1.0 and 1.0, given x and y coordinates.""" - expr = lambda x, y: (random.random() * 2) - 1 + angles1 = generate_angles() + angles2 = generate_angles() + angles3 = generate_angles() + grid_size1 = generate_grid_size() + grid_size2 = generate_grid_size() + grid_size3 = generate_grid_size() + offset_1x = random.random() + offset_1y = random.random() + offset_2x = random.random() + offset_2y = random.random() + trig1 = trig_func() + trig2 = trig_func() + trig3 = trig_func() + func1 = f() + func2 = f() + func3 = f() + func4 = f() + func5 = f() + + def expr(x, y): + value1 = trig2(pi * func5(trig1(func1(pn.perlinNoise((x + offset_1x, + y + offset_1y), grid_size1, angles1)) * pi))) + value2 = trig2(func3(pn.perlinNoise((x + offset_2x, y + offset_2y), + grid_size2, angles2) * pi)) + value3 = trig1(func2(pn.perlinNoise((x + offset_2y, y + offset_1x), + grid_size3, angles3)) * pi) + return trig2(pi * func4(trig3(pi * func2(value1 * + value2 - (value3 + x * y))))) return expr @@ -17,3 +45,20 @@ def run_expression(expr, x, y): an x and y value. It runs the expression, passing the x and y values to it and returns a value between -1.0 and 1.0.""" return expr(x, y) + + +def generate_angles(): + return (random.uniform(0, 2*pi), random.uniform(0, 2*pi), + random.uniform(0, 2*pi), random.uniform(0, 2*pi)) + + +def generate_grid_size(): + return random.randint(2500, 4500) + + +def trig_func(): + return random.choice([sin, cos]) + + +def f(): + return random.choice([sin, tan, cos, atan])