/
Ridge.java
108 lines (96 loc) · 3.46 KB
/
Ridge.java
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
import applet.KrabApplet;
import processing.core.PGraphics;
import processing.core.PVector;
import java.util.ArrayList;
/**
* Created by Jakub 'Krab' Rak on 2020-02-01
*/
public class Ridge extends KrabApplet {
ArrayList<Line> lines = new ArrayList<>();
private PGraphics pg;
private float boundsRadius = 300;
public static void main(String[] args) {
KrabApplet.main("Ridge");
}
public void settings() {
size(800, 800, P2D);
}
public void setup() {
surface.setAlwaysOnTop(true);
pg = createGraphics(width, height, P2D);
pg.smooth(16);
pg.beginDraw();
pg.background(0);
pg.endDraw();
frameRecordingDuration *= 2;
}
public void draw() {
pg.beginDraw();
if(frameCount < 5){
pg.background(0);
}
pg.translate(width * .5f, height * .5f);
updateLines();
pg.stroke(picker("ellipse stroke").clr());
pg.strokeWeight(slider("ellipse weight"));
pg.noFill();
pg.ellipse(0, 0, boundsRadius * 2, boundsRadius * 2);
pg.endDraw();
image(pg, 0, 0);
rec(pg);
gui();
}
void updateLines() {
float mountainTop = slider("top", -200);
float mountainBottom = slider("bottom", 200);
int count = sliderInt("count", 60);
if (button("clear")) {
lines.clear();
pg.background(0);
}
if (lines.size() < count && frameCount % 3 == 0) {
float ridgeFreq = slider("ridge freq");
float ridgeAmp = slider("ridge amp");
float y = map(lines.size(), 0, count, mountainTop, mountainBottom);
float x = ridgeAmp * (1 - 2 * noise(t + y * ridgeFreq));
lines.add(new Line(new PVector(x, y), TWO_PI + QUARTER_PI, TWO_PI));
lines.add(new Line(new PVector(x, y), PI - QUARTER_PI, PI));
}
for (Line line : lines) {
PVector origin = line.vertices.get(0);
PVector end = line.vertices.get(line.vertices.size() - 1);
float freq = slider("noise freq", .1f);
float amp = slider("noise amp", .5f);
float vertexSpeed = slider("vertex speed", 1);
if (insideBounds(end)) {
float n = amp * (1 - 2 * noise(end.x * freq, end.y * freq));
float d = abs(origin.x - end.x);
float dNorm = norm(d, 0, boundsRadius);
float dEase = ease(dNorm, slider("slope ease", 1));
if(Float.isNaN(dEase)){
dEase = 1;
}
float angle = map(dEase, 0, 1, line.slopeAngle, line.endAngle);
PVector continuation = PVector.fromAngle(angle + n);
continuation.mult(vertexSpeed);
continuation = end.copy().add(continuation);
pg.strokeWeight(slider("line weight", 1));
pg.stroke(255);
pg.line(end.x, end.y, continuation.x, continuation.y);
line.vertices.add(continuation);
}
}
}
boolean insideBounds(PVector p) {
return dist(p.x, p.y, 0, 0) < boundsRadius;
}
class Line {
ArrayList<PVector> vertices = new ArrayList<PVector>();
float slopeAngle, endAngle;
Line(PVector origin, float slopeAngle, float endAngle) {
vertices.add(origin);
this.slopeAngle = slopeAngle;
this.endAngle = endAngle;
}
}
}