Add and pervasively use grid type (Bitmap)
This commit is contained in:
47
lib/algorithms/geometry.dart
Normal file
47
lib/algorithms/geometry.dart
Normal 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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
Reference in New Issue
Block a user