-
Notifications
You must be signed in to change notification settings - Fork 0
/
light_direction.js
122 lines (111 loc) · 3.5 KB
/
light_direction.js
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
// The Final result: a time line showing the light directions of an artist's oeuvre
// Light direction is a normalized vector from the centroid of the mesh towards the light source
// timeline represents the artist's life span
let paintings;
artistPalette = ["#E63946", "#F1FAEE", "#A8DADC", "#457B9D", "#1D3557"];
let colors = chroma.scale(['white', '#F1FAEE']).colors(10);
let particles = [];
let distanceBetweenParticles;
let currentIndex = 0;
let startX = 100; // timeline initial position
let scannerX = startX; // Scanner's initial position
let timelineDrawn = false; // Flag to check if the timeline has been drawn
let nextPaintingIndex = 0; // Index of the next painting to check
let minDate;
let maxDate;
function preload() {
loadJSON('TINTORETTO.json', function(data) {
paintings = data;
console.log("JSON loaded", paintings);
});
}
function setup() {
createCanvas(800, 400);
distanceBetweenParticles = width / paintings.length;
paintings.sort((a, b) => a.date - b.date);
}
function draw() {
background(20);
stroke(220);
strokeWeight(1);
let minDate = Math.min(...paintings.map((p) => p.date));
let maxDate = Math.max(...paintings.map((p) => p.date));
let endX = width - startX;
// Check if the timeline is fully drawn
if (timelineDrawn) {
line(startX, height / 2, endX, height / 2); // Draw the full timeline
} else {
line(startX, height / 2, scannerX, height / 2); // Draw up to the scanner's position
}
textSize(15);
textAlign(CENTER, BOTTOM);
noStroke();
let textColor = colors[Math.floor(colors.length / 2)];
let artist = "TINTORETTO";
fill(textColor);
text(artist, width / 2, height - 95);
textSize(10);
textAlign(CENTER, BOTTOM);
fill(255);
let dateText = "(" + String(minDate) + " - " + String(maxDate) + ")";
text(dateText, width / 2, height - 80);
// Move the scanner
scannerX += 1; // SPEED OF SCANNER
if (scannerX > endX) {
timelineDrawn = true;
scannerX = startX;
nextPaintingIndex = 0;
}
// Check for paintings
while (nextPaintingIndex < paintings.length) {
let painting = paintings[nextPaintingIndex];
let mappedDate = map(painting.date, minDate, maxDate, startX, endX);
if (mappedDate <= scannerX) {
// Emit a particle
let direction = createVector(
painting.lightDirection.x,
painting.lightDirection.y
);
particles.push(new Particle(mappedDate, height / 2, direction));
nextPaintingIndex++;
} else {
break;
}
}
for (let particle of particles) {
particle.update();
particle.show();
}
}
class Particle {
constructor(x, y, direction) {
this.origin = createVector(x, y);
this.position = createVector(x, y);
this.velocity = direction.copy().normalize();
this.stepSize = 1; // Fixed step size
this.maxLen = 60; // Maximum length of the particle's trajectory
this.alpha = 255; // For fading
this.currentLen = 0; //
}
update() {
if (this.currentLen < this.maxLen) {
this.position.add(this.velocity);
this.currentLen = this.currentLen + this.stepSize;
} else {
this.alpha -= 2; // Fading speed
this.alpha = max(this.alpha, 160);
}
}
show() {
let paletteIndex = floor(
map(this.velocity.heading(), -PI, PI, 0, colors.length)
);
let myColor = colors[paletteIndex];
let r = red(myColor);
let g = green(myColor);
let b = blue(myColor);
stroke(r, g, b, this.alpha);
strokeWeight(1);
line(this.origin.x, this.origin.y, this.position.x, this.position.y);
}
}