Dane Sabo 0968572184 M0.5 part 1: geo dep + polygon-difference cleanup, Y overlap fixed
The Y intersection had a real I3 violation that the M0.3 centroid-
only check missed (parcels 0 and 7 overlapped by ~64.5 m²). This
commit:

- adds geo 0.28 as a dependency
- replaces y_intersection_no_overlaps's centroid-in-polygon check
  with a rigorous polygon-polygon intersection test using
  geo::BooleanOps; adds rectangle_no_overlaps_rigorous as a
  positive-control test for the rectangle case
- adds cleanup_block_parcel_overlaps pass at the end of
  subdivide_block: iterate parcels in placement order (corners
  first, regulars after), subtract previously-claimed territory
  from each via geo's polygon difference, drop empties, recover
  frontage edge index and edge_kinds for survivors
- snaps polygon coords to a 1mm grid before handing to geo (helps
  geo's sweep-line invariants); strips collinear-triple and
  near-zero-length-edge artifacts from boolean output before
  feeding back into Polygon::new strict
- wraps difference/union calls in catch_unwind so geo's
  occasional sweep-line panic on degenerate inputs falls back to
  a no-op instead of crashing subdivision

Test status: 24 unit + 24 integration + 1 doc passing. Y figure
visually cleaner — every parcel sits inside its own sub-block, no
visible overlap between sub-blocks.

Self-decisions checklist progress: rigorous I3 testing landed
(checklist item ✓).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 13:26:43 -04:00

55 lines
1.5 KiB
TOML

[package]
name = "road_parceling"
version = "0.1.0"
edition = "2021"
authors = ["Dane Sabo"]
description = "Road-frontage-based parcel subdivision for a city simulation. Pure logic, no rendering or game loop."
license = "MIT OR Apache-2.0"
repository = "https://github.com/danesabo/Historia_Urbis"
readme = "README.md"
keywords = ["geometry", "city", "simulation", "parcel", "gis"]
categories = ["algorithms", "game-development", "science::geo"]
[features]
default = []
viz = ["dep:svg"]
serde = ["dep:serde", "glam/serde", "slotmap/serde"]
[dependencies]
glam = { version = "0.29", features = ["mint"] }
geo = "0.28"
slotmap = "1"
thiserror = "2"
rand = "0.8"
rand_chacha = "0.3"
# optional
svg = { version = "0.18", optional = true }
serde = { version = "1", features = ["derive"], optional = true }
[dev-dependencies]
proptest = "1"
insta = { version = "1", features = ["yaml"] }
criterion = { version = "0.5", default-features = false, features = ["cargo_bench_support"] }
[[bench]]
name = "subdivision"
harness = false
[[example]]
name = "generate_figures"
required-features = ["viz"]
[lints.rust]
missing_docs = "deny"
unsafe_code = "forbid"
[lints.clippy]
all = { level = "warn", priority = -1 }
# Pragmatic exceptions for a numerical/geometry crate. We deliberately
# do *not* enable `pedantic` here — its naming and idiom checks fight
# the conventions of geometry code (single-letter coordinate names,
# small struct field reassignments) without buying real safety.
if_same_then_else = "allow"
field_reassign_with_default = "allow"