Repository navigation
Expand file tree
/
Copy pathSimulation.pde
More file actions
128 lines (110 loc) · 4.06 KB
/
Copy pathSimulation.pde
File metadata and controls
128 lines (110 loc) · 4.06 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
public class Simulation {
Shapes shapes;
PlasticMask plastic_mask;
SimWindow simulation_window;
final int INTENSITY_MAP_SIZE = 50; // A square grid of pixels, with the LED at the center.
float[] intensity_map;
PImage intensity_image;
int canvas_width, canvas_height;
Simulation(Shapes shapes, int canvas_width, int canvas_height, PlasticMask plastic_mask)
{
this.shapes = shapes;
this.canvas_width = canvas_width;
this.canvas_height = canvas_height;
this.plastic_mask = plastic_mask;
initIntensityMap();
simulation_window = new SimWindow(this, canvas_width, canvas_height);
}
public void start()
{
String[] args = {"TwoFrameTest"};
PApplet.runSketch(args, simulation_window);
}
protected void initIntensityMap() {
PVector led_position = new PVector(INTENSITY_MAP_SIZE/2, INTENSITY_MAP_SIZE/2);
intensity_map = new float[INTENSITY_MAP_SIZE * INTENSITY_MAP_SIZE];
intensity_image = createImage(INTENSITY_MAP_SIZE, INTENSITY_MAP_SIZE, ARGB);
// These parameters affect the falloff rate.
//float p1 = 1.0, p2 = 1.0;
for(int y = 0; y < INTENSITY_MAP_SIZE; y++) {
for(int x = 0; x < INTENSITY_MAP_SIZE; x++) {
// Generate an intensity (from 0 -> 1) for this pixel. The middle of the map is where the LED pixel is.
float distance = led_position.dist(new PVector(x, y));
float intensity = 1.0;
if (distance >= 0.0005) {
//intensity = 1.0 / (p1 * distance + p2 * distance * distance);
// intensity = 1.0 / (float)(INTENSITY_MAP_SIZE / 2);
intensity = 1.0 - distance / (float)(INTENSITY_MAP_SIZE / 2);
intensity = Math.min(1.0, Math.max(0.0, intensity));
}
intensity_map[y * INTENSITY_MAP_SIZE + x] = intensity;
}
}
}
/**
* Uses the LED color values to render a simulation of what it looks like in real life.
*/
public void render(PApplet canvas) {
canvas.background(0);
for(Shape shape: shapes.shapes) {
for(LedPixel led_pixel: shape.leds) {
renderPixel(canvas, led_pixel);
}
}
// All pixels rendered. Now let's apply the mask to blank out the areas that are not covered by plastic.
canvas.blend(plastic_mask.inverse_mask,
0, 0, canvas_width, canvas_height,
0, 0, canvas_width, canvas_height,
SUBTRACT
);
// Add a hint of where the plastic is.
canvas.blend(plastic_mask.mask,
0, 0, canvas_width, canvas_height,
0, 0, canvas_width, canvas_height,
ADD
);
}
protected void renderPixel(PApplet canvas, LedPixel led_pixel) {
color led_col = led_pixel.col & 0xFFFFFF; // Mask out the alpha
// Create the image of the pixel with falloff (in the alpha channel).
intensity_image.loadPixels();
for(int i = 0; i < intensity_map.length; i++) {
int intensity = (int)(intensity_map[i] * 255);
intensity_image.pixels[i] = intensity << 24 | led_col;
}
intensity_image.updatePixels();
// Render the image to the canvas, with alpha.
int left = (int)led_pixel.canvas_position.x - INTENSITY_MAP_SIZE / 2;
int top = (int)led_pixel.canvas_position.y - INTENSITY_MAP_SIZE / 2;
canvas.blend(intensity_image,
0, 0, INTENSITY_MAP_SIZE, INTENSITY_MAP_SIZE, // Source x,y, width, height
left, top, INTENSITY_MAP_SIZE, INTENSITY_MAP_SIZE, // Dest x,y, width, height
ADD
);
}
}
public class SimWindow extends PApplet {
boolean is_window_positioned = false;
Simulation simulation;
int canvas_width, canvas_height;
SimWindow(Simulation simulation, int canvas_width, int canvas_height) {
super();
this.simulation = simulation;
this.canvas_width = canvas_width;
this.canvas_height = canvas_height;
}
public void settings() {
size(canvas_width, canvas_height);
}
public void setup() {
fill(64);
}
public void draw() {
if(!is_window_positioned) {
// Place this side by side with the main window.
surface.setLocation(canvas_width, 200);
is_window_positioned = true;
}
simulation.render(this);
}
}