{"id":13821198,"url":"https://github.com/mikolalysenko/l1-path-finder","last_synced_at":"2025-04-04T13:12:57.893Z","repository":{"id":30632060,"uuid":"34187543","full_name":"mikolalysenko/l1-path-finder","owner":"mikolalysenko","description":"🗺 Fast path planning for 2D grids","archived":false,"fork":false,"pushed_at":"2016-05-18T18:44:17.000Z","size":1251,"stargazers_count":488,"open_issues_count":4,"forks_count":44,"subscribers_count":25,"default_branch":"master","last_synced_at":"2024-12-16T22:35:05.385Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://mikolalysenko.github.io/l1-path-finder/www","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mikolalysenko.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-04-19T00:04:19.000Z","updated_at":"2024-12-13T09:24:07.000Z","dependencies_parsed_at":"2022-09-05T02:00:52.250Z","dependency_job_id":null,"html_url":"https://github.com/mikolalysenko/l1-path-finder","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikolalysenko%2Fl1-path-finder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikolalysenko%2Fl1-path-finder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikolalysenko%2Fl1-path-finder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikolalysenko%2Fl1-path-finder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mikolalysenko","download_url":"https://codeload.github.com/mikolalysenko/l1-path-finder/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247182401,"owners_count":20897381,"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","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":[],"created_at":"2024-08-04T08:01:17.287Z","updated_at":"2025-04-04T13:12:57.874Z","avatar_url":"https://github.com/mikolalysenko.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"[\u003cimg src=\"https://github.com/mikolalysenko/l1-path-finder/raw/master/img/logo.png\"\u003e](https://mikolalysenko.github.io/l1-path-finder/www)\n\n[A fast path planner for grids.](https://mikolalysenko.github.io/l1-path-finder/www)\n\n# Example\n\n```javascript\nvar ndarray = require('ndarray')\nvar createPlanner = require('l1-path-finder')\n\n\n//Create a maze as an ndarray\nvar maze = ndarray([\n  0, 1, 0, 0, 0, 0, 0,\n  0, 1, 0, 1, 0, 0, 0,\n  0, 1, 0, 1, 1, 1, 0,\n  0, 1, 0, 1, 0, 0, 0,\n  0, 1, 0, 1, 0, 0, 0,\n  0, 1, 0, 1, 0, 0, 0,\n  0, 1, 0, 1, 0, 1, 1,\n  0, 0, 0, 1, 0, 0, 0,\n], [8, 7])\n\n//Create path planner\nvar planner = createPlanner(maze)\n\n//Find path\nvar path = []\nvar dist = planner.search(0,0,  7,6,  path)\n\n//Log output\nconsole.log('path length=', dist)\nconsole.log('path = ', path)\n```\n\nOutput:\n\n```\npath length= 31\npath =  [ 0, 0, 7, 0, 7, 2, 0, 2, 0, 4, 1, 4, 1, 6, 3, 6, 5, 6, 5, 4, 7, 4, 7, 6 ]\n```\n\n# Install\n\nThis module works in any node-flavored CommonJS environment, including [node.js](https://nodejs.org/), [iojs](https://iojs.org/en/index.html) and [browserify](http://browserify.org/).  You can install it using the [npm package manager](https://docs.npmjs.com/) with the following command:\n\n```\nnpm i l1-path-finder\n```\n\nThe input to the library is in the form of an [ndarray](https://github.com/scijs/ndarray).  For more information on this data type, check out the [SciJS](https://scijs.net) project.\n\n# API\n\n```javascript\nvar createPlanner = require('l1-path-finder')\n```\n\n#### `var planner = createPlanner(grid)`\n\nThe default method from the package is a constructor which creates a path planner.\n\n* `grid` is a 2D ndarray.  `0` or `false`-y values correspond to empty cells and non-zero or `true`-thy values correspond to impassable obstacles\n\n**Returns** A new planner object which you can use to answer queries about the path.\n\n**Time Complexity** `O(grid.shape[0]*grid.shape[1] + n log(n))` where `n` is the number of concave corners in the grid.\n\n**Space Complexity** `O(n sqrt(log(n)))`\n\n#### `var dist = planner.search(srcX, srcY, dstX, dstY[, path])`\n\nExecutes a path search on the grid.\n\n* `srcX, srcY` are the coordinates of the start of the path (source)\n* `dstX, dstY` are the coordiantes of the end of the path (target)\n* `path` is an optional array which receives the result of the path\n\n**Returns** The distance from the source to the target\n\n**Time Complexity** Worst case `O(n sqrt(log(n)³) )`, but in practice much less usually\n\n# Benchmarks\n\nl1-path-finder is probably the fastest JavaScript library for finding paths on\nuniform cost grids.  Here is a chart showing some typical comparisons (log-scale):\n\n[\u003cimg src=\"https://plot.ly/~MikolaLysenko/221.png\" width=\"512\"\u003e](https://plot.ly/~MikolaLysenko/221)\n\nYou can try out some of the benchmarks in [your browser here](http://mikolalysenko.github.io/l1-path-finder/benchmark.html), or you can run them locally by cloning this repo.  Data is taken from the [grid path planning challenge benchmark](http://www.movingai.com/benchmarks/).\n\nIt is also pretty competitive with C++ libraries for path searching.  The following chart shows the performance of l1-path-finder compared to [Warthog](https://code.google.com/p/ddh/), which is a state of the art\nimplementation of the popular \"[jump point search](https://harablog.wordpress.com/2011/09/07/jump-point-search/)\" algorithm:\n\n[\u003cimg src=\"https://plot.ly/~MikolaLysenko/230.png\" width=\"512\"\u003e](https://plot.ly/~MikolaLysenko/230)\n\n# Notes and references\n\n* The algorithm implemented in this module is based on the following result by Clarkson et al:\n    + K. Clarkson, S. Kapoor, P. Vaidya. (1987) \"[Rectilinear shortest paths through polygonal obstacles in O(n log(n)²) time](http://dl.acm.org/citation.cfm?id=41985)\" SoCG 87\n* This data structure is asymptotically faster than naive grid based algorithms like Jump Point Search or simple A*/Dijkstra based searches.\n* All memory is preallocated.  At run time, searches trigger no garbage collection or other memory allocations.\n* The heap data structure used in this implementation is a pairing heap based on the following paper:\n    + G. Navarro, R. Paredes. (2010) \"[On sorting, heaps, and minimum spanning trees](http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.218.3241)\" Algorithmica\n* Box stabbing queries are implemented using rank queries.\n* The graph search uses landmarks to speed up A*, based on the technique in the following paper:\n    + A. Goldberg, C. Harrelson. (2004) \"[Computing the shortest path: A* search meets graph theory](http://research.microsoft.com/pubs/64511/tr-2004-24.pdf)\" Microsoft Research Tech Report\n* For more information on A* searching, check out [Amit Patel's pages](http://theory.stanford.edu/~amitp/GameProgramming/)\n\n# License\n\n(c) 2015 Mikola Lysenko. MIT License\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmikolalysenko%2Fl1-path-finder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmikolalysenko%2Fl1-path-finder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmikolalysenko%2Fl1-path-finder/lists"}