1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdint.h>
4 #include <string.h>
5 #include <math.h>
6 #include <stdarg.h>
7 #include <errno.h>
8
err(int ex,const char * fmt,...)9 void err(int ex, const char *fmt, ...)
10 {
11 va_list list;
12 int e = errno;
13 va_start(list, fmt);
14 vfprintf(stderr, fmt, list);
15 fputs(": ", stderr);
16 fputs(strerror(e), stderr);
17 fputs("\n", stderr);
18 exit(ex);
19 }
20
errx(int ex,const char * fmt,...)21 void errx(int ex, const char *fmt, ...)
22 {
23 va_list list;
24 va_start(list, fmt);
25 vfprintf(stderr, fmt, list);
26 fputs("\n", stderr);
27 exit(ex);
28 }
29
30 typedef void (*colorfunc_t) (double x, double y, double dx, double dy, double *r, double *g, double *b);
31
rnd()32 double rnd()
33 {
34 return rand() / (RAND_MAX + 1.0);
35 }
36
softclip(double x,double a)37 double softclip(double x, double a)
38 {
39 // don't ask what this does - but it works
40 double cse = (2*a*x - x - a + 1) * x;
41 return cse / (cse + (1 - a));
42 }
43
writepic(colorfunc_t f,const char * fn,int width,int height)44 void writepic(colorfunc_t f, const char *fn, int width, int height)
45 {
46 int x, y;
47 uint8_t tga[18];
48
49 FILE *file = fopen(fn, "wb");
50 if(!file)
51 err(1, "fopen >%s", fn);
52
53 memset(tga, 0, sizeof(tga));
54 tga[2] = 2; // uncompressed type
55 tga[12] = (width >> 0) & 0xFF;
56 tga[13] = (width >> 8) & 0xFF;
57 tga[14] = (height >> 0) & 0xFF;
58 tga[15] = (height >> 8) & 0xFF;
59 tga[16] = 24; // pixel size
60
61 if(fwrite(&tga, sizeof(tga), 1, file) != 1)
62 err(1, "fwrite >%s", fn);
63 //for(y = height-1; y >= 0; --y)
64 for(y = 0; y < height; ++y)
65 for(x = 0; x < width; ++x)
66 {
67 uint8_t rgb[3];
68 double rr, gg, bb;
69 double xx, yy;
70 xx = (x + 0.5) / width;
71 yy = (y + 0.5) / height;
72 f(xx, yy, 0.5 / width, 0.5 / height, &rr, &gg, &bb);
73 rgb[2] = floor(rnd() + rr * 255);
74 rgb[1] = floor(rnd() + gg * 255);
75 rgb[0] = floor(rnd() + bb * 255);
76 if(fwrite(rgb, sizeof(rgb), 1, file) != 1)
77 err(1, "fwrite >%s", fn);
78 }
79
80 fclose(file);
81 }
82
83 typedef struct
84 {
85 double x, y, dist;
86 int weapon;
87 }
88 plotpoint_t;
89
90 plotpoint_t *plotpoints;
91 size_t nPlotpoints, allocatedPlotpoints;
92
readpoints(const char * fn)93 void readpoints(const char *fn)
94 {
95 char buf[1024];
96
97 FILE *infile = fopen(fn, "r");
98 if(!infile)
99 err(1, "fopen <%s", fn);
100
101 nPlotpoints = allocatedPlotpoints = 0;
102 plotpoints = NULL;
103
104 while(fgets(buf, sizeof(buf), infile))
105 {
106 if(*buf == '#')
107 {
108 fputs(buf + 1, stdout);
109 continue;
110 }
111 if(nPlotpoints >= allocatedPlotpoints)
112 {
113 if(allocatedPlotpoints == 0)
114 allocatedPlotpoints = 1024;
115 else
116 allocatedPlotpoints = nPlotpoints * 2;
117 plotpoints = (plotpoint_t *) realloc(plotpoints, allocatedPlotpoints * sizeof(*plotpoints));
118 }
119 if(sscanf(buf, "%lf %lf %lf %d", &plotpoints[nPlotpoints].x, &plotpoints[nPlotpoints].y, &plotpoints[nPlotpoints].dist, &plotpoints[nPlotpoints].weapon) != 4)
120 continue;
121 ++nPlotpoints;
122 }
123 }
124
calcplot1(double x,double y,double * out,double sigma2)125 void calcplot1(double x, double y, double *out, double sigma2)
126 {
127 size_t i;
128 double dist2;
129 double val, totalval = 0, weight, totalweight = 0;
130
131 for(i = 0; i < nPlotpoints; ++i)
132 {
133 dist2 = (x - plotpoints[i].x) * (x - plotpoints[i].x) + (y - plotpoints[i].y) * (y - plotpoints[i].y);
134 weight = 1; // / plotpoints[i].dist;
135 val = exp(-dist2 / sigma2);
136
137 totalweight += weight;
138 totalval += weight * val;
139 }
140
141 *out = softclip(totalval / (totalweight * sqrt(sigma2 * 2 * M_PI)), 0.8);
142 }
143
calcplotp(double x,double y,double dx,double dy,double * out)144 void calcplotp(double x, double y, double dx, double dy, double *out)
145 {
146 size_t i;
147 double distx, disty;
148
149 for(i = 0; i < nPlotpoints; ++i)
150 {
151 distx = x - plotpoints[i].x;
152 disty = y - plotpoints[i].y;
153
154 if(distx < dx)
155 if(distx > -dx)
156 if(disty < dy)
157 if(disty > -dy)
158 {
159 *out = 1;
160 break;
161 }
162 }
163 }
164
calcplot(double x,double y,double dx,double dy,double * r,double * g,double * b)165 void calcplot(double x, double y, double dx, double dy, double *r, double *g, double *b)
166 {
167 calcplot1(x, y, r, 1/64.0);
168 calcplot1(x, y, g, 1/512.0);
169 calcplot1(x, y, b, 1/4096.0);
170 calcplotp(x, y, dx, dy, b);
171 }
172
main(int argc,char ** argv)173 int main(int argc, char **argv)
174 {
175 if(argc != 3)
176 errx(1, "Usage: %s infile.plot outfile.tga", *argv);
177
178 readpoints(argv[1]);
179 writepic(calcplot, argv[2], 512, 512);
180
181 return 0;
182 }
183