{"id":33338210,"url":"https://github.com/oldrev/mini-router","last_synced_at":"2026-05-15T10:35:15.450Z","repository":{"id":325268801,"uuid":"1100512605","full_name":"oldrev/mini-router","owner":"oldrev","description":"A minimal demo for exploring key algorithms used in PCB routing and layout tools.","archived":false,"fork":false,"pushed_at":"2025-11-20T11:47:23.000Z","size":104,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-11-20T13:17:45.705Z","etag":null,"topics":["algorithms","avalonia","dotnet","eda","gui","layout","open-source","pcb"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/oldrev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-20T11:32:44.000Z","updated_at":"2025-11-20T11:47:27.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/oldrev/mini-router","commit_stats":null,"previous_names":["oldrev/mini-router"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/oldrev/mini-router","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oldrev%2Fmini-router","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oldrev%2Fmini-router/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oldrev%2Fmini-router/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oldrev%2Fmini-router/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/oldrev","download_url":"https://codeload.github.com/oldrev/mini-router/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oldrev%2Fmini-router/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":285587839,"owners_count":27197176,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-11-21T02:00:06.175Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["algorithms","avalonia","dotnet","eda","gui","layout","open-source","pcb"],"created_at":"2025-11-21T09:00:27.777Z","updated_at":"2026-05-15T10:35:15.424Z","avatar_url":"https://github.com/oldrev.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MinimalRouter\n\n[中文](README.zh.md)\n\nA minimal demo for exploring key algorithms used in PCB routing and layout tools.\n\n![Screen shot](Assets/screenshot.png)\n\nProject goals: study and demonstrate common techniques for PCB routing/layout, including path search (A*), collision detection, handling trace width/clearance, 90° chamfering of corners, and copper pour (difference/clip operations) around obstacles and traces.\n\nThis project is a learning and experimentation demo; it intentionally does not separate world coordinates from drawing coordinates to keep the implementation compact.\n\n\n\n## Highlights\n\n- Interactive UI (built with .NET Avalonia): place random polygonal obstacles, drag to create traces, and confirm multi-segment traces.\n- A* grid search with 8-direction neighbours (includes diagonals) and optional turn penalty to reduce unnecessary corners.\n- Collision detection: robust tests for arbitrary polygon obstacles and traces using bounding boxes + edge-to-edge distance checks.\n- Trace width \u0026 clearance management: expands boundaries by half the trace width plus a global clearance when checking for collisions.\n- Chamfering at 90° corners: attempts to replace right-angle corners with 45° chamfers to reduce sharp points and improve manufacturability.\n- Copper pour (difference): uses Clipper2 to subtract obstacles and traces (with expansion) from the board polygon, showing allowable copper regions.\n- Vectorized distance operations and other optimizations are used where appropriate to reduce cost for large arrays.\n\n---\n\n## Project structure (key files)\n\n- `Program.cs`: Avalonia application entry point.\n- `MainWindow.axaml` / `MainWindow.axaml.cs`: UI and interaction logic. Handles random obstacle generation, mouse events (draw/confirm), and copper pour demo.\n- `Controls/DrawingCanvas.cs`: Canvas drawing support.\n- `Routing/Router.cs`: Core router that implements A*, neighbor selection, simplification, and chamfer logic.\n- `Routing/CollisionDetector.cs`: Collision detection for polygons, rectangles and distance-based checks between segments.\n- `Routing/Obstacle.cs`: Obstacle polygon data structure.\n- `Routing/Trace.cs`, `Routing/Segment.cs`: Trace/segment models.\n- `Models/Point.cs`: A small simplified `Point` structure used in the demo.\n\n---\n\n## Design \u0026 algorithm details\n\n1. Path search (Router)\n   - A* search on a discretized grid (step = 10 pixels) using Euclidean distance as the heuristic. Each cell has 8 neighbors (4 orthogonal, 4 diagonal).\n   - Turn penalty encourages straighter routes by increasing g-score when a path changes direction, which reduces unnecessary turns.\n   - The search is bounded by a `MaxSearchRange` radius from the start/end points to avoid global blow-ups.\n   - Post-processing: remove colinear points (Simplify) and attempt to replace 90° corners with chamfers (ApplyChamfers). A chamfer is only applied after it is confirmed to be collision-free.\n\n2. Collision detection (CollisionDetector)\n   - Each obstacle is first quickly cropped using an inflated bounding rectangle (inflated by clearance + width/2). If bounding rectangles overlap, a more expensive polygon-edge/edge distance test is performed.\n   - For static traces, the effective minimum allowed distance is trace half-width + clearance — if the segment-to-segment distance is smaller than this threshold, it is considered a collision. Shared endpoints are allowed to connect.\n   - Interior point testing uses ray casting; segment-segment shortest distance uses robust geometric algorithms adapted from GeomAlgorithms.\n\n3. Copper pour\n   - Uses the Clipper2 library. The board boundary acts as the Subject polygon. Obstacles and traces (after inflating by half trace width + clearance) are the Clip polygons. Performing a Difference yields the regions that can be filled with copper.\n\n4. Performance-friendly measures\n   - Where possible, batch distance computations use `System.Numerics.Vector` for SIMD acceleration.\n   - Search space clipping and `maxSteps` help prevent very long or infinite searches.\n\n---\n\n## Quick start (Windows / PowerShell)\n\nPrerequisites: .NET SDK installed (.NET 10) and Internet to restore NuGet packages.\n\nBuild and run:\n\n```powershell\ndotnet restore\ndotnet build -c Debug\ndotnet run --project MinimalRouter.csproj\n```\n\nThe app will open a window. Typical actions:\n- Left-click to start routing; move the mouse to preview candidate routes; click to confirm a segment. Double-click to finish the trace.\n- Right-click to cancel the current trace.\n- Use the `Width` slider to change trace width; use the `Clearance` slider to adjust the global clearance. Press the `Pour` button to perform a copper pour (board boundary minus obstacles and traces).\n\n## Interaction notes\n\n- The first click on the canvas sets the start point (green). Subsequent clicks add points to the route; double-click finishes and commits the trace. Right-click cancels or reverts.\n- Confirmed traces are added to a static list used by the router for collision detection. The router allows connecting to trace endpoints.\n- Obstacles are randomly generated polygons for demo purposes and to demonstrate collision avoidance and copper pour.\n\n---\n\n## License \u0026 contribution\n\nThis code is provided as a demo for educational/video purposes.\n\nPublic Domain (no restrictions).\n\nAuthor: Li Wei (email: oldrev@gmail.com) (The code was primarily written by GitHub Copilot.)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foldrev%2Fmini-router","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foldrev%2Fmini-router","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foldrev%2Fmini-router/lists"}