FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
Java/Others/KochSnowflake.java at master · coder2hacker/Java · GitHub
Uh oh!
There was an error while loading.
Please reload this page
.
coder2hacker
/
Java
Public
forked from
TheAlgorithms/Java
Notifications
You must be signed in to change notification settings
Fork
0
Star
2
Code
Pull requests
0
Actions
Projects
Security and quality
0
Insights
Additional navigation options
Code
Pull requests
Actions
Projects
Security and quality
Insights
Expand file tree
Breadcrumbs
Java
/
Others
/
KochSnowflake.java
Copy path
More file actions
More file actions
Latest commit
History
History
History
234 lines (203 loc) · 7.86 KB
Breadcrumbs
Java
/
Others
/
KochSnowflake.java
Copy path
File metadata and controls
234 lines (203 loc) · 7.86 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
package
Others
;
import
java
.
awt
.*;
import
java
.
awt
.
image
.
BufferedImage
;
import
java
.
io
.
File
;
import
java
.
io
.
IOException
;
import
java
.
util
.
ArrayList
;
import
javax
.
imageio
.
ImageIO
;
/**
* The Koch snowflake is a fractal curve and one of the earliest fractals to have been described.
* The Koch snowflake can be built up iteratively, in a sequence of stages. The first stage is an
* equilateral triangle, and each successive stage is formed by adding outward bends to each side of
* the previous stage, making smaller equilateral triangles. This can be achieved through the
* following steps for each line: 1. divide the line segment into three segments of equal length. 2.
* draw an equilateral triangle that has the middle segment from step 1 as its base and points
* outward. 3. remove the line segment that is the base of the triangle from step 2. (description
* adapted from https://en.wikipedia.org/wiki/Koch_snowflake ) (for a more detailed explanation and
* an implementation in the Processing language, see
* https://natureofcode.com/book/chapter-8-fractals/ #84-the-koch-curve-and-the-arraylist-technique
* ).
*/
public
class
KochSnowflake
{
public
static
void
main
(
String
[]
args
) {
// Test Iterate-method
ArrayList
<
Vector2
>
vectors
=
new
ArrayList
<
Vector2
>();
vectors
.
add
(
new
Vector2
(
0
,
0
));
vectors
.
add
(
new
Vector2
(
1
,
0
));
ArrayList
<
Vector2
>
result
=
Iterate
(
vectors
,
1
);
assert
result
.
get
(
0
).
x
==
0
;
assert
result
.
get
(
0
).
y
==
0
;
assert
result
.
get
(
1
).
x
==
1.
/
3
;
assert
result
.
get
(
1
).
y
==
0
;
assert
result
.
get
(
2
).
x
==
1.
/
2
;
assert
result
.
get
(
2
).
y
==
Math
.
sin
(
Math
.
PI
/
3
) /
3
;
assert
result
.
get
(
3
).
x
==
2.
/
3
;
assert
result
.
get
(
3
).
y
==
0
;
assert
result
.
get
(
4
).
x
==
1
;
assert
result
.
get
(
4
).
y
==
0
;
// Test GetKochSnowflake-method
int
imageWidth
=
600
;
double
offsetX
=
imageWidth
/
10.
;
double
offsetY
=
imageWidth
/
3.7
;
BufferedImage
image
=
GetKochSnowflake
(
imageWidth
,
5
);
// The background should be white
assert
image
.
getRGB
(
0
,
0
) ==
new
Color
(
255
,
255
,
255
).
getRGB
();
// The snowflake is drawn in black and this is the position of the first vector
assert
image
.
getRGB
((
int
)
offsetX
, (
int
)
offsetY
) ==
new
Color
(
0
,
0
,
0
).
getRGB
();
// Save image
try
{
ImageIO
.
write
(
image
,
"png"
,
new
File
(
"KochSnowflake.png"
));
}
catch
(
IOException
e
) {
e
.
printStackTrace
();
}
}
/**
* Go through the number of iterations determined by the argument "steps". Be careful with high
* values (above 5) since the time to calculate increases exponentially.
*
* @param initialVectors The vectors composing the shape to which the algorithm is applied.
* @param steps The number of iterations.
* @return The transformed vectors after the iteration-steps.
*/
public
static
ArrayList
<
Vector2
>
Iterate
(
ArrayList
<
Vector2
>
initialVectors
,
int
steps
) {
ArrayList
<
Vector2
>
vectors
=
initialVectors
;
for
(
int
i
=
0
;
i
<
steps
;
i
++) {
vectors
=
IterationStep
(
vectors
);
}
return
vectors
;
}
/**
* Method to render the Koch snowflake to a image.
*
* @param imageWidth The width of the rendered image.
* @param steps The number of iterations.
* @return The image of the rendered Koch snowflake.
*/
public
static
BufferedImage
GetKochSnowflake
(
int
imageWidth
,
int
steps
) {
if
(
imageWidth
<=
0
) {
throw
new
IllegalArgumentException
(
"imageWidth should be greater than zero"
);
}
double
offsetX
=
imageWidth
/
10.
;
double
offsetY
=
imageWidth
/
3.7
;
Vector2
vector1
=
new
Vector2
(
offsetX
,
offsetY
);
Vector2
vector2
=
new
Vector2
(
imageWidth
/
2
,
Math
.
sin
(
Math
.
PI
/
3
) *
imageWidth
*
0.8
+
offsetY
);
Vector2
vector3
=
new
Vector2
(
imageWidth
-
offsetX
,
offsetY
);
ArrayList
<
Vector2
>
initialVectors
=
new
ArrayList
<
Vector2
>();
initialVectors
.
add
(
vector1
);
initialVectors
.
add
(
vector2
);
initialVectors
.
add
(
vector3
);
initialVectors
.
add
(
vector1
);
ArrayList
<
Vector2
>
vectors
=
Iterate
(
initialVectors
,
steps
);
return
GetImage
(
vectors
,
imageWidth
,
imageWidth
);
}
/**
* Loops through each pair of adjacent vectors. Each line between two adjacent vectors is divided
* into 4 segments by adding 3 additional vectors in-between the original two vectors. The vector
* in the middle is constructed through a 60 degree rotation so it is bent outwards.
*
* @param vectors The vectors composing the shape to which the algorithm is applied.
* @return The transformed vectors after the iteration-step.
*/
private
static
ArrayList
<
Vector2
>
IterationStep
(
ArrayList
<
Vector2
>
vectors
) {
ArrayList
<
Vector2
>
newVectors
=
new
ArrayList
<
Vector2
>();
for
(
int
i
=
0
;
i
<
vectors
.
size
() -
1
;
i
++) {
Vector2
startVector
=
vectors
.
get
(
i
);
Vector2
endVector
=
vectors
.
get
(
i
+
1
);
newVectors
.
add
(
startVector
);
Vector2
differenceVector
=
endVector
.
subtract
(
startVector
).
multiply
(
1.
/
3
);
newVectors
.
add
(
startVector
.
add
(
differenceVector
));
newVectors
.
add
(
startVector
.
add
(
differenceVector
).
add
(
differenceVector
.
rotate
(
60
)));
newVectors
.
add
(
startVector
.
add
(
differenceVector
.
multiply
(
2
)));
}
newVectors
.
add
(
vectors
.
get
(
vectors
.
size
() -
1
));
return
newVectors
;
}
/**
* Utility-method to render the Koch snowflake to an image.
*
* @param vectors The vectors defining the edges to be rendered.
* @param imageWidth The width of the rendered image.
* @param imageHeight The height of the rendered image.
* @return The image of the rendered edges.
*/
private
static
BufferedImage
GetImage
(
ArrayList
<
Vector2
>
vectors
,
int
imageWidth
,
int
imageHeight
) {
BufferedImage
image
=
new
BufferedImage
(
imageWidth
,
imageHeight
,
BufferedImage
.
TYPE_INT_RGB
);
Graphics2D
g2d
=
image
.
createGraphics
();
// Set the background white
g2d
.
setBackground
(
Color
.
WHITE
);
g2d
.
fillRect
(
0
,
0
,
imageWidth
,
imageHeight
);
// Draw the edges
g2d
.
setColor
(
Color
.
BLACK
);
BasicStroke
bs
=
new
BasicStroke
(
1
);
g2d
.
setStroke
(
bs
);
for
(
int
i
=
0
;
i
<
vectors
.
size
() -
1
;
i
++) {
int
x1
= (
int
)
vectors
.
get
(
i
).
x
;
int
y1
= (
int
)
vectors
.
get
(
i
).
y
;
int
x2
= (
int
)
vectors
.
get
(
i
+
1
).
x
;
int
y2
= (
int
)
vectors
.
get
(
i
+
1
).
y
;
g2d
.
drawLine
(
x1
,
y1
,
x2
,
y2
);
}
return
image
;
}
/** Inner class to handle the vector calculations. */
private
static
class
Vector2
{
double
x
,
y
;
public
Vector2
(
double
x
,
double
y
) {
this
.
x
=
x
;
this
.
y
=
y
;
}
@
Override
public
String
toString
() {
return
String
.
format
(
"[%f, %f]"
,
this
.
x
,
this
.
y
);
}
/**
* Vector addition
*
* @param vector The vector to be added.
* @return The sum-vector.
*/
public
Vector2
add
(
Vector2
vector
) {
double
x
=
this
.
x
+
vector
.
x
;
double
y
=
this
.
y
+
vector
.
y
;
return
new
Vector2
(
x
,
y
);
}
/**
* Vector subtraction
*
* @param vector The vector to be subtracted.
* @return The difference-vector.
*/
public
Vector2
subtract
(
Vector2
vector
) {
double
x
=
this
.
x
-
vector
.
x
;
double
y
=
this
.
y
-
vector
.
y
;
return
new
Vector2
(
x
,
y
);
}
/**
* Vector scalar multiplication
*
* @param scalar The factor by which to multiply the vector.
* @return The scaled vector.
*/
public
Vector2
multiply
(
double
scalar
) {
double
x
=
this
.
x
*
scalar
;
double
y
=
this
.
y
*
scalar
;
return
new
Vector2
(
x
,
y
);
}
/**
* Vector rotation (see https://en.wikipedia.org/wiki/Rotation_matrix)
*
* @param angleInDegrees The angle by which to rotate the vector.
* @return The rotated vector.
*/
public
Vector2
rotate
(
double
angleInDegrees
) {
double
radians
=
angleInDegrees
*
Math
.
PI
/
180
;
double
ca
=
Math
.
cos
(
radians
);
double
sa
=
Math
.
sin
(
radians
);
double
x
=
ca
*
this
.
x
-
sa
*
this
.
y
;
double
y
=
sa
*
this
.
x
+
ca
*
this
.
y
;
return
new
Vector2
(
x
,
y
);
}
}
}
Back
|
FazBrowse Home
|
New Git URL