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
|
#include <map>
#include <algorithm>
using namespace std;
#ifdef _WIN32
#define DLLEXPORT extern "C" __declspec(dllexport)
#else
#define DLLEXPORT extern "C"
#endif // _WIN32
int color_encode(int *rgb) {
return rgb[0]*256*256+rgb[1]*256+rgb[2];
}
void color_decode(int c, int *rgb) {
rgb[2]=c%256; c/=256; // b
rgb[1]=c%256; c/=256; // g
rgb[0]=c; // r
}
DLLEXPORT
void compute_density(int r, double *gx, double *gy, int n, double *dx, double *dy, int *drgb, int *rgba) {
int colors = 0;
map<int,int> color2ind, ind2color;
int *color = new int[n];
for (int i=0;i<n;i++) {
int c = color_encode(drgb+i*3);
if (color2ind.count(c)==0) {
int ind = colors++;
color2ind[c] = ind;
ind2color[ind] = c;
}
color[i] = color2ind[c];
}
double min_x = *min_element(dx,dx+n), max_x = *max_element(dx,dx+n);
double min_y = *min_element(dy,dy+n), max_y = *max_element(dy,dy+n);
double diag = (max_x-min_x)*(max_x-min_x) + (max_y-min_y)*(max_y-min_y);
double lo=1.0/colors, hi=1.0;
double *f = new double[colors];
for (int i=0;i<r;i++) {
for (int j=0;j<r;j++) {
double total=0;
for (int c=0;c<colors;c++) f[c]=0;
for (int k=0;k<n;k++) {
int c = color[k];
double d = 1.0/(0.001*diag + (gx[j]-dx[k])*(gx[j]-dx[k]) + (gy[i]-dy[k])*(gy[i]-dy[k]));
total += d;
f[c] += d;
}
double main_f=-1;
int main_color=-1;
for (int c=0;c<colors;c++) {
if (f[c]>main_f) {
main_f=f[c];
main_color=c;
}
}
double main_ratio=main_f/total;
int offset=i*r*4+j*4;
rgba[offset+3]=(lo<hi)?(int)(128*(main_ratio-lo)/(hi-lo)):128;
color_decode(ind2color[main_color], rgba+offset);
}
}
delete[] color;
delete[] f;
}
// Empty python module definition
#include "Python.h"
static PyModuleDef _grid_density_module = {
PyModuleDef_HEAD_INIT,
"_grid_density",
NULL,
-1,
};
PyMODINIT_FUNC
PyInit__grid_density(void) {
PyObject * mod;
mod = PyModule_Create(&_grid_density_module);
if (mod == NULL)
return NULL;
return mod;
}
|