Add and pervasively use grid type (Bitmap)

This commit is contained in:
2023-09-21 15:37:12 -07:00
parent 5de409515e
commit ae0c62b010
7 changed files with 220 additions and 102 deletions

View File

@ -0,0 +1,47 @@
// Dart has a habit of using double-inclusive bounds,
// and I strongly prefer half-open bounds
//
// So: Here's a reimplementation of the geometry I need
class Size {
final int dx;
final int dy;
Size(this.dx, this.dy) {
assert(dx >= 0);
assert(dy >= 0);
}
}
class Offset {
final int x;
final int y;
const Offset(this.x, this.y);
}
class Rect {
final int x0;
final int y0;
final int dx;
final int dy;
int get x1 => x0 + dx;
int get y1 => y0 + dy;
Rect(this.x0, this.y0, this.dx, this.dy) {
assert(dx >= 0);
assert(dy >= 0);
}
bool contains(int x, int y) {
return x0 <= x && x < x1 && y0 <= y && y < y1;
}
bool containsPoint(Offset xy) {
return contains(xy.x, xy.y);
}
bool containsRect(Rect rect) {
return x0 <= rect.x0 && y0 <= rect.y0 && rect.x1 <= x1 && rect.y1 <= y1;
}
}

View File

@ -1,5 +1,7 @@
import 'dart:math' as math;
import 'package:dartterm/algorithms/geometry.dart' as geo;
class Region {
final math.Rectangle<int> rect;
final Set<(int, int)> points;
@ -25,14 +27,13 @@ class Region {
}
}
List<Region> regionalize(
math.Rectangle<int> rect, bool Function(int, int) isAccessible) {
List<Region> regionalize(geo.Rect rect, bool Function(int, int) isAccessible) {
int nextRegion = 0;
Map<(int, int), int> regions = {};
int floodfill(int x, int y) {
int workDone = 0;
if (!rect.containsPoint(math.Point(x, y))) {
if (!rect.containsPoint(geo.Offset(x, y))) {
return workDone;
}
if (regions[(x, y)] != null) {
@ -53,8 +54,8 @@ List<Region> regionalize(
// TODO: This can be done more efficiently with a union/find data structure
// But this is an easy implementation to understand
for (var y = rect.top; y < rect.bottom; y++) {
for (var x = rect.left; x < rect.right; x++) {
for (var y = rect.y0; y < rect.y1; y++) {
for (var x = rect.x0; x < rect.x1; x++) {
if (regions[(x, y)] == null) {
if (floodfill(x, y) > 0) {
nextRegion += 1;