v / examples / pendulum-simulation / modules / sim / img / writer.v
68 lines · 57 sloc · 1.55 KB · bbb61ab3687afe512a1fa12492c876d011626107
Raw
1module img
2
3import gg
4import sim
5
6pub struct ValidColor {
7 gg.Color
8pub mut:
9 valid bool
10}
11
12pub struct ImageWriter {
13 settings ImageSettings
14pub mut:
15 writer PPMWriter
16 current_index int
17 buffer []ValidColor
18}
19
20pub fn new_image_writer(mut writer PPMWriter, settings ImageSettings) &ImageWriter {
21 total_pixels := settings.width * settings.height
22 mut buffer := []ValidColor{len: total_pixels, init: ValidColor{
23 valid: false
24 }}
25 return &ImageWriter{
26 writer: writer
27 settings: settings
28 buffer: buffer
29 }
30}
31
32pub fn (mut iw ImageWriter) handle(result sim.SimResult) !int {
33 total_pixels := iw.settings.width * iw.settings.height
34
35 // find the closest magnet
36 iw.buffer[result.id].Color = compute_pixel(result)
37 iw.buffer[result.id].valid = true
38
39 for iw.current_index < total_pixels && iw.buffer[iw.current_index].valid {
40 iw.writer.handle_pixel(iw.buffer[iw.current_index].Color) or {
41 sim.log(@MOD + '.' + @FN + ': pixel handler failed. Error ${err}')
42 break
43 }
44 iw.current_index++
45 }
46
47 if iw.current_index == total_pixels {
48 iw.writer.write() or { panic('Could not write image') }
49 return error('none')
50 }
51
52 return iw.current_index
53}
54
55pub fn compute_pixel(result sim.SimResult) gg.Color {
56 closest_to_m1 := result.magnet1_distance < result.magnet2_distance
57 && result.magnet1_distance < result.magnet3_distance
58 closest_to_m2 := result.magnet2_distance < result.magnet1_distance
59 && result.magnet2_distance < result.magnet3_distance
60
61 if closest_to_m1 {
62 return gg.red
63 } else if closest_to_m2 {
64 return gg.green
65 } else {
66 return gg.blue
67 }
68}
69