2022-01-13 05:24:03 +01:00
|
|
|
enum AREA_DISTRIBUTION {
|
|
|
|
area,
|
|
|
|
border
|
|
|
|
}
|
|
|
|
|
|
|
|
enum AREA_SCATTER {
|
|
|
|
uniform,
|
|
|
|
random
|
|
|
|
}
|
|
|
|
|
2023-02-21 04:48:50 +01:00
|
|
|
function area_get_bbox(area) {
|
|
|
|
return [ area[0] - area[2], area[1] - area[3], area[0] + area[2], area[1] + area[3] ];
|
|
|
|
}
|
|
|
|
|
2024-01-24 06:19:34 +01:00
|
|
|
function area_get_random_point(area, distrib = AREA_DISTRIBUTION.area, scatter = AREA_SCATTER.random, index = 0, total = 1) {
|
2022-01-13 05:24:03 +01:00
|
|
|
if(total == 0) return [0, 0];
|
|
|
|
|
2024-03-31 05:36:11 +02:00
|
|
|
var _area_x = array_safe_get_fast(area, 0);
|
|
|
|
var _area_y = array_safe_get_fast(area, 1);
|
|
|
|
var _area_w = array_safe_get_fast(area, 2);
|
|
|
|
var _area_h = array_safe_get_fast(area, 3);
|
|
|
|
var _area_t = array_safe_get_fast(area, 4);
|
2022-01-13 05:24:03 +01:00
|
|
|
var xx = 0, yy = 0;
|
|
|
|
|
2024-08-30 11:08:30 +02:00
|
|
|
index = safe_mod(index, total);
|
|
|
|
|
2022-01-13 05:24:03 +01:00
|
|
|
switch(distrib) {
|
|
|
|
case AREA_DISTRIBUTION.area :
|
|
|
|
if(scatter == AREA_SCATTER.uniform) {
|
2024-01-17 14:57:32 +01:00
|
|
|
if(_area_t == AREA_SHAPE.rectangle) {
|
2024-08-30 11:08:30 +02:00
|
|
|
|
2024-01-17 14:57:32 +01:00
|
|
|
var _col = ceil(sqrt(total));
|
|
|
|
var _row = ceil(total / _col);
|
2024-08-30 11:08:30 +02:00
|
|
|
|
2024-01-17 14:57:32 +01:00
|
|
|
var _iwid = _area_w * 2 / _col;
|
|
|
|
var _ihig = _area_h * 2 / _row;
|
2024-08-30 11:08:30 +02:00
|
|
|
|
2024-01-17 14:57:32 +01:00
|
|
|
var _irow = floor(index / _col);
|
|
|
|
var _icol = safe_mod(index, _col);
|
2024-08-30 11:08:30 +02:00
|
|
|
|
2024-01-17 14:57:32 +01:00
|
|
|
xx = _area_x - _area_w + (_icol + 0.5) * _iwid;
|
|
|
|
yy = _area_y - _area_h + (_irow + 0.5) * _ihig;
|
2024-08-30 11:08:30 +02:00
|
|
|
|
|
|
|
//print($"{yy} = {_area_y} - {_area_h} + ({_irow} + 0.5) * {_ihig}")
|
|
|
|
|
2024-01-17 14:57:32 +01:00
|
|
|
} else {
|
|
|
|
if(index == 0) {
|
|
|
|
xx = _area_x;
|
|
|
|
yy = _area_y;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
var _r = _area_w;
|
|
|
|
var _a = _area_w / _area_h;
|
|
|
|
|
|
|
|
var _tm = floor(total / (2 * pi));
|
|
|
|
var _tn = ceil(sqrt(2 * _tm + 1 / 2) - 1 / 2);
|
|
|
|
var _s = _r / _tn;
|
|
|
|
|
|
|
|
var _m = floor(index / (2 * pi));
|
|
|
|
var _n = floor(sqrt(2 * _m + 1 / 2) - 1 / 2);
|
|
|
|
|
|
|
|
var _sr = (_n + 1) * _s;
|
|
|
|
var _tt = floor((_n * (_n + 1)) / 2 * pi * 2);
|
|
|
|
var _sa = (index - _tt) / (min(total - _tt, floor((_n + 1) * 2 * pi)) - 1) * 360;
|
|
|
|
|
|
|
|
xx = _area_x + lengthdir_x(_sr, _sa);
|
|
|
|
yy = _area_y + lengthdir_y(_sr, _sa) / _a;
|
|
|
|
}
|
2024-08-30 11:08:30 +02:00
|
|
|
|
2022-01-13 05:24:03 +01:00
|
|
|
} else if(scatter == AREA_SCATTER.random) {
|
|
|
|
if(_area_t == AREA_SHAPE.rectangle) {
|
2024-01-24 06:19:34 +01:00
|
|
|
xx = _area_x + random_range(-_area_w, _area_w);
|
|
|
|
yy = _area_y + random_range(-_area_h, _area_h);
|
2024-08-30 11:08:30 +02:00
|
|
|
|
2024-01-17 14:57:32 +01:00
|
|
|
} else if(_area_t == AREA_SHAPE.elipse) {
|
2024-01-24 06:19:34 +01:00
|
|
|
var rr = random(360);
|
|
|
|
xx = _area_x + lengthdir_x(1, rr) * random(_area_w);
|
|
|
|
yy = _area_y + lengthdir_y(1, rr) * random(_area_h);
|
2022-01-13 05:24:03 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case AREA_DISTRIBUTION.border :
|
|
|
|
if(scatter == AREA_SCATTER.uniform) {
|
|
|
|
if(_area_t == AREA_SHAPE.rectangle) {
|
2024-01-17 14:57:32 +01:00
|
|
|
var perimeter = _area_w * 4 + _area_h * 4;
|
|
|
|
var d = perimeter / total;
|
|
|
|
var l = perimeter * index / total;
|
|
|
|
|
|
|
|
if(l <= _area_w * 2) {
|
|
|
|
xx = _area_x - _area_w + l;
|
2022-01-13 05:24:03 +01:00
|
|
|
yy = _area_y - _area_h;
|
2024-01-17 14:57:32 +01:00
|
|
|
break;
|
|
|
|
} l -= _area_w * 2;
|
|
|
|
|
|
|
|
if(l <= _area_h * 2) {
|
2022-01-13 05:24:03 +01:00
|
|
|
xx = _area_x + _area_w;
|
2024-01-17 14:57:32 +01:00
|
|
|
yy = _area_y - _area_h + l;
|
|
|
|
break;
|
|
|
|
} l -= _area_h * 2;
|
|
|
|
|
|
|
|
if(l <= _area_w * 2) {
|
|
|
|
xx = _area_x + _area_w - l;
|
|
|
|
yy = _area_y + _area_h;
|
|
|
|
break;
|
|
|
|
} l -= _area_w * 2;
|
|
|
|
|
|
|
|
if(l <= _area_h * 2) {
|
|
|
|
xx = _area_x - _area_w;
|
|
|
|
yy = _area_y + _area_h - l;
|
|
|
|
break;
|
|
|
|
} l -= _area_h * 2;
|
|
|
|
|
|
|
|
} else if(_area_t == AREA_SHAPE.elipse) {
|
2022-01-13 05:24:03 +01:00
|
|
|
var rr = 360 * index / total;
|
|
|
|
xx = _area_x + lengthdir_x(_area_w, rr);
|
|
|
|
yy = _area_y + lengthdir_y(_area_h, rr);
|
|
|
|
}
|
2024-08-30 11:08:30 +02:00
|
|
|
|
2022-01-13 05:24:03 +01:00
|
|
|
} else if(scatter == AREA_SCATTER.random) {
|
|
|
|
if(_area_t == AREA_SHAPE.rectangle) {
|
|
|
|
var perimeter = _area_w * 2 + _area_h * 2;
|
2024-01-24 06:19:34 +01:00
|
|
|
var i = random(perimeter);
|
2022-01-13 05:24:03 +01:00
|
|
|
if(i < _area_w) {
|
2024-01-24 06:19:34 +01:00
|
|
|
xx = _area_x + random_range(-_area_w, _area_w);
|
2022-01-13 05:24:03 +01:00
|
|
|
yy = _area_y - _area_h;
|
|
|
|
} else if(i < _area_w + _area_h) {
|
|
|
|
xx = _area_x - _area_w;
|
2024-01-24 06:19:34 +01:00
|
|
|
yy = _area_y + random_range(-_area_h, _area_h);
|
2022-01-13 05:24:03 +01:00
|
|
|
} else if(i < _area_w * 2 + _area_h) {
|
2024-01-24 06:19:34 +01:00
|
|
|
xx = _area_x + random_range(-_area_w, _area_w);
|
2022-01-13 05:24:03 +01:00
|
|
|
yy = _area_y + _area_h;
|
|
|
|
} else {
|
|
|
|
xx = _area_x + _area_w;
|
2024-01-24 06:19:34 +01:00
|
|
|
yy = _area_y + random_range(-_area_h, _area_h);
|
2022-01-13 05:24:03 +01:00
|
|
|
}
|
2024-08-30 11:08:30 +02:00
|
|
|
|
2024-01-17 14:57:32 +01:00
|
|
|
} else if(_area_t == AREA_SHAPE.elipse) {
|
2024-01-24 06:19:34 +01:00
|
|
|
var rr = random(360);
|
2022-01-13 05:24:03 +01:00
|
|
|
xx = _area_x + lengthdir_x(_area_w, rr);
|
|
|
|
yy = _area_y + lengthdir_y(_area_h, rr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return [xx, yy];
|
|
|
|
}
|