# Contour Service ## Description Service for detecting and scoring wire/line contours from Vision results. ## Acceptance Criteria - [ ] `ContourService` class with methods: - `func findBestWireContour(at point: CGPoint, from contours: [VNContour]) -> VNContour?` - `func scoreContour(_ contour: VNContour, relativeTo point: CGPoint) -> Float` - `func contourToMask(_ contour: VNContour, width: Int, imageSize: CGSize) -> CGImage` - [ ] Contour scoring considers: - Proximity to tap point (closer = higher score) - Aspect ratio (thin and elongated = higher score) - Straightness / low curvature (straighter = higher score) - Length (longer = higher score) - [ ] Configurable mask width: default 6px, range 2-20px - [ ] Returns `nil` when no wire-like contour found near tap - [ ] Unit tests for contour scoring logic ## Technical Notes - VNContour provides normalized path points - Calculate curvature by analyzing angle changes along path - Aspect ratio = length / average width - Weight scoring factors: proximity (0.3), aspect (0.3), straightness (0.2), length (0.2) ## Edge Cases - No contours detected: return nil - All contours score below threshold: return nil - Curved wires: allow moderate curvature, don't require perfectly straight - Contour very close to tap but not wire-like: score should be low