-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathcairotest.nt
136 lines (118 loc) · 3.24 KB
/
cairotest.nt
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
module cairotest;
import sdl, std.math, std.lib.cairo, std.time;
pragma(lib, "cairo");
void main() using mode cairo {
writeln "Open SDL Window .. ";
screen(640, 480);
auto surface = cairo_image_surface_create_for_data (display.surf.back.pixels,
CAIRO_FORMAT_RGB24, display.surf.back.(w, h, pitch));
struct Node {
vec2f pos;
vec2f motion;
float prop;
int[auto~] neighbors;
}
Node[auto~] grid;
int size = 10;
import std.random;
for int y <- 0..size for int x <- 0..size {
Node n;
n.pos = vec2f(x, y) / size;
int id = y * size + x;
if (x < size-1) n.neighbors ~= id+1;
if (x > 0) n.neighbors ~= id-1;
if (y < size-1) n.neighbors ~= id+size;
if (y > 0) n.neighbors ~= id-size;
if (x > 0 && y > 0) n.neighbors ~= id-size-1;
if (x > 0 && y < size-1) n.neighbors ~= id+size-1;
if (x < size-1 && y > 0) n.neighbors ~= id-size+1;
if (x < size-1 && y < size-1) n.neighbors ~= id+size+1;
n.prop = (randf(deflt) - 0.5) * 0.01;
grid ~= n;
}
void rebalance() {
vec2f offset, offsetd;
for ref node <- grid { offset += node.pos; offsetd += node.motion; }
offset /= grid.length;
offsetd /= grid.length;
offset -= vec2f 0.5;
for ref node <- grid { node.pos -= offset; node.motion -= offsetd; }
}
float f = 0.0001;
void step() {
f *= 0.96;
scope tensions = new vec2f[] grid.length;
for ref node <- grid && ref tension <- tensions using node {
for auto n <- neighbors {
ref node2 = grid[n];
{
auto delta = node2.motion - motion;
auto wanted-delta = vec2f(0);
auto wanted-motion = node2.motion;
tension += (wanted-motion - motion) * 0.001;
}
{
auto prop = node2.prop;
auto dir = node2.pos - pos;
if (|dir| > 0.01 && |dir| < 0.05) {
dir = dir / |dir|;
tension += dir * prop * f;
}
}
}
}
for ref node <- grid && ref tension <- tensions using node {
motion += tension;
pos += motion;
}
}
import std.thread;
auto tp = new ThreadPool 1;
tp.addTask λ {
auto rng = getPRNG(23);
float f;
while true {
f += 0.001;
step;
rebalance;
}
}
void draw() {
using mode cairo-context cairo_create surface {
onSuccess destroy; // social commentary lol
set_source_rgb (0.1, 0.1, 0.2);
paint;
vec2f translate(vec2f v) {
auto edge = vec2f(20, 20);
return edge + (vec2f(640, 480) - edge * 2) * v;
}
for ref node <- grid {
if (size <= 30) {
set_source_rgb (1, 1, 0.8);
set_line_width 1;
arc(translate node.pos, 5, 0, PI2);
stroke;
}
for auto n <- node.neighbors {
set_source_rgb (1, 1, 0.8);
set_line_width $ 10f / size;
move_to translate node.pos;
line_to translate grid[n].pos;
stroke;
}
}
}
}
int fps, lastTime = time null;
bool update() {
draw();
fps ++;
if (time null != lastTime) {
writeln "$fps fps";
fps = 0; lastTime = time null;
}
flip;
return false;
}
while !update() { }
}