-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathArt.java
More file actions
146 lines (129 loc) · 5.05 KB
/
Copy pathArt.java
File metadata and controls
146 lines (129 loc) · 5.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package Projects.RecursiveArt.src;
/**
* Name: Kinner Parikh
* Mrs. Kankelborg
* Period 1
* Project 2 Recursive Art Project Part 3: Art
*
* Revision History:
* 11/21 - Brainstorm Ideas
* 11/22 - Create a recursive flower
* 11/23 - Brainstormed better ideas
* 11/24 - Created psychedelic blobs
* 11/25 - Fixed bugs
* 11/26 - Added Comments
*
* Class Description:
* Creates a psychedelic looking blobs (or clouds) using recursion
*/
import java.awt.*;
import java.util.Random;
import edu.princeton.cs.algs4.StdDraw;
public class Art
{
// Creates an object of type Random with the seed being the current time
private static Random random = new Random(System.currentTimeMillis());
// Creates a random number between 0.01 and 0.1
private static double finalSize = random(0.01, 0.1);
/**
* @param n the number of iterations
*/
public static void draw(int n)
{
// Creating random colors for all four sides
double color0 = random(0, 1), color1 = random(0, 1);
double color2 = random(0, 1), color3 = random(0, 1);
// Creating random value within 0 and 10 that controls how much color changes
double deviate = random(0, 10);
// The draw method's base case is base on the size of the squares being drawn.
// This operation gathers the random value initially initialized to finalsize
// and divides it by five times the n value passed. This way, it creates an
// interesting piece of art with any n value
finalSize /= (n * 5);
// Draws art
StdDraw.enableDoubleBuffering();
draw(0.5, 0.5, color0, color1, color2, color3, 0.5, deviate);
StdDraw.show();
}
/**
* @param x position of square
* @param y position of square
* @param color0 color of surrounding square
* @param color1 color of surrounding square
* @param color2 color of surrounding square
* @param color3 color of surrounding square
* @param size size of square
* @param dev stores how much to deviate the color by
*/
private static void draw(double x, double y, double color0, double color1, double color2, double color3, double size, double dev)
{
// Base case
if (size <= finalSize) return;
// Color of new square based on the average of the surrounding four colors and the Gaussian Distribution equation
double newSquare = average(new double[]{color0, color1, color2, color3}) + (dev * distribution());
// Creates newSquare but of type float
float flNewSquare = (float)newSquare;
// Sets pen color based on HSB (hue, saturation, brightness) values
StdDraw.setPenColor(
(new Color(
Color.HSBtoRGB(flNewSquare, 1f, 1f))
)
);
// Draws a square
StdDraw.filledSquare(x, y, size);
// Creates new colors based on the average of passed colors
double colorLeft = average(new double[]{color0, color2});
double colorRight = average(new double[]{color1, color3});
double colorTop = average(new double[]{color0, color1});
double colorBottom = average(new double[]{color2, color3});
// Recursive calls
draw(x + size, y + size, colorTop , color1 , newSquare , colorRight , size / 2, dev / 2); // Right top
draw(x + size, y - size, newSquare, colorRight, colorBottom, color3 , size / 2, dev / 2); // Right bottom
draw(x - size, y - size, colorLeft, newSquare , color2 , colorBottom, size / 2, dev / 2); // Left bottom
draw(x - size, y + size, color0 , colorTop , colorLeft , newSquare , size / 2, dev / 2); // Left top
}
/**
*
* @param values a double array
* @return the average of the elements in values
*/
private static double average(double[] values)
{
double totalVal = 0;
// Loops through values, adding each value to totalVal
for (double val : values)
{
totalVal += val;
}
// Returning the average
return totalVal / (values.length * 1.0);
}
/**
* @return a random number based on Gaussian Distribution
*/
private static double distribution()
{
// Get random values between -1 and 1
double x = random(-1.0, 1.0), y = random(-1.0, 1.0);
// Square both values
double num = Math.pow(x, 2) + Math.pow(y, 2);
// Loop until desired result
while (num == 0 || num >= 1)
{
x = random(-1.0, 1.0);
y = random(-1.0, 1.0);
num = Math.pow(x, 2) + Math.pow(y, 2);
}
// Perform Gaussian formula
return x * Math.sqrt(-2 * Math.log(num / 2));
}
/**
* @param lowerBound lower bound of random value
* @param higherBound higher bound of random value
* @return a random double in between lowerBound and higherBound
*/
private static double random(double lowerBound, double higherBound)
{
return lowerBound + random.nextDouble() * (higherBound - lowerBound);
}
}