generate method
void
generate(
- double radius
)
Implementation
void generate(double radius) {
if (generators.isEmpty) {
return;
}
_diagram.clear();
_queue.clear();
final inverseRadius = 1 / radius;
final firstGenerator = generators.first;
_lower.setFrom(firstGenerator.center);
_upper.setFrom(firstGenerator.center);
for (final g in generators) {
Vector2.min(_lower, g.center, _lower);
Vector2.max(_upper, g.center, _upper);
}
_countX = 1 + (inverseRadius * (_upper.x - _lower.x)).toInt();
_countY = 1 + (inverseRadius * (_upper.y - _lower.y)).toInt();
for (final g in generators) {
g.center.setFrom((g.center - _lower)..scale(inverseRadius));
final x = max(0, min(g.center.x.toInt(), _countX - 1));
final y = max(0, min(g.center.y.toInt(), _countY - 1));
_queue.addFirst(VoronoiDiagramTask(x, y, x + y * _countX, g));
}
while (_queue.isNotEmpty) {
final front = _queue.removeFirst();
final x = front.x;
final y = front.y;
final i = front.i;
final g = front.generator;
if (_diagram.containsKey(i)) {
_diagram[i] = g;
if (x > 0) {
_queue.addFirst(VoronoiDiagramTask(x - 1, y, i - 1, g));
}
if (y > 0) {
_queue.addFirst(VoronoiDiagramTask(x, y - 1, i - _countX, g));
}
if (x < _countX - 1) {
_queue.addFirst(VoronoiDiagramTask(x + 1, y, i + 1, g));
}
if (y < _countY - 1) {
_queue.addFirst(VoronoiDiagramTask(x, y + 1, i + _countX, g));
}
}
}
final maxIteration = _countX + _countY;
for (var iteration = 0; iteration < maxIteration; iteration++) {
for (var y = 0; y < _countY; y++) {
for (var x = 0; x < _countX - 1; x++) {
final i = x + y * _countX;
final a = _diagram[i]!;
final b = _diagram[i + 1]!;
if (a != b) {
_queue.addFirst(VoronoiDiagramTask(x, y, i, b));
_queue.addFirst(VoronoiDiagramTask(x + 1, y, i + 1, a));
}
}
}
for (var y = 0; y < _countY - 1; y++) {
for (var x = 0; x < _countX; x++) {
final i = x + y * _countX;
final a = _diagram[i]!;
final b = _diagram[i + _countX]!;
if (a != b) {
_queue.addFirst(VoronoiDiagramTask(x, y, i, b));
_queue.addFirst(VoronoiDiagramTask(x, y + 1, i + _countX, a));
}
}
}
var updated = false;
while (_queue.isNotEmpty) {
final front = _queue.removeFirst();
final x = front.x;
final y = front.y;
final i = front.i;
final k = front.generator;
final a = _diagram[i]!;
final b = k;
if (a != b) {
final ax = a.center.x - x;
final ay = a.center.y - y;
final bx = b.center.x - x;
final by = b.center.y - y;
final a2 = ax * ax + ay * ay;
final b2 = bx * bx + by * by;
if (a2 > b2) {
_diagram[i] = b;
if (x > 0) {
_queue.addFirst(VoronoiDiagramTask(x - 1, y, i - 1, b));
}
if (y > 0) {
_queue.addFirst(VoronoiDiagramTask(x, y - 1, i - _countX, b));
}
if (x < _countX - 1) {
_queue.addFirst(VoronoiDiagramTask(x + 1, y, i + 1, b));
}
if (y < _countY - 1) {
_queue.addFirst(VoronoiDiagramTask(x, y + 1, i + _countX, b));
}
updated = true;
}
}
}
if (!updated) {
break;
}
}
}