{"id":13624344,"url":"https://github.com/Prozi/detect-collisions","last_synced_at":"2025-04-15T21:30:43.727Z","repository":{"id":41358877,"uuid":"123184521","full_name":"Prozi/detect-collisions","owner":"Prozi","description":"detecting collisions between bodies: Points, Lines, Boxes, Polygons (Concave too), Ellipses and Circles. Also RayCasting. All bodies can have offset, rotation, scale, bounding box padding, can be static (non moving) or be trigger bodies (non colliding).","archived":false,"fork":false,"pushed_at":"2024-04-12T21:18:19.000Z","size":9110,"stargazers_count":173,"open_issues_count":2,"forks_count":18,"subscribers_count":7,"default_branch":"master","last_synced_at":"2024-04-13T05:06:50.344Z","etag":null,"topics":["alghorithm","collision-checking","collisions","computational-geometry","computational-geometry-algorithms","javascript","library","typescript"],"latest_commit_sha":null,"homepage":"https://prozi.github.io/detect-collisions/","language":"TypeScript","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/Prozi.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-02-27T20:29:28.000Z","updated_at":"2024-07-15T18:40:55.180Z","dependencies_parsed_at":"2024-03-01T16:24:41.771Z","dependency_job_id":"c76fe05c-0908-479a-937a-0ffe1683b6af","html_url":"https://github.com/Prozi/detect-collisions","commit_stats":{"total_commits":423,"total_committers":13,"mean_commits":32.53846153846154,"dds":0.508274231678487,"last_synced_commit":"1f3b58dc4fb3efba97317e8fca211eabe04551c2"},"previous_names":[],"tags_count":59,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Prozi%2Fdetect-collisions","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Prozi%2Fdetect-collisions/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Prozi%2Fdetect-collisions/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Prozi%2Fdetect-collisions/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Prozi","download_url":"https://codeload.github.com/Prozi/detect-collisions/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223685195,"owners_count":17185798,"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":["alghorithm","collision-checking","collisions","computational-geometry","computational-geometry-algorithms","javascript","library","typescript"],"created_at":"2024-08-01T21:01:41.518Z","updated_at":"2025-04-15T21:30:43.716Z","avatar_url":"https://github.com/Prozi.png","language":"TypeScript","readme":"# Detect-Collisions\n\n[\u003cimg src=\"https://img.shields.io/npm/v/detect-collisions?style=for-the-badge\u0026color=success\" alt=\"npm version\" /\u003e](https://www.npmjs.com/package/detect-collisions?activeTab=versions)\n[\u003cimg src=\"https://img.shields.io/npm/dw/detect-collisions.svg?style=for-the-badge\u0026color=success\" alt=\"npm downloads per week\" /\u003e](https://www.npmjs.com/package/detect-collisions)\n[\u003cimg src=\"https://img.shields.io/circleci/build/github/Prozi/detect-collisions/master?style=for-the-badge\" alt=\"build status\" /\u003e](https://app.circleci.com/pipelines/github/Prozi/detect-collisions)\n\n## Introduction\n\nDetect-Collisions 💫 is a lightning-fast ⚡️ TypeScript library built to detect collisions between diverse shapes like Points, Lines, Boxes, Polygons (including concave), Ellipses, and Circles. Utilizing Bounding Volume Hierarchy (BVH) and the Separating Axis Theorem (SAT), it offers rapid and accurate collision detection. The library supports RayCasting, offsets, rotation, scaling, and optimizations for: bounding box, flags for non-moving and ghost/trigger bodies and collision groups filtering - making it an ideal choice for high-speed applications in gaming and simulations.\n\n## Demos\n\n- [Tank](https://prozi.github.io/detect-collisions/demo/)\n- [Stress Test](https://prozi.github.io/detect-collisions/demo/?stress)\n- [Stackblitz](https://stackblitz.com/edit/detect-collisions)\n- [CodePan](https://code.pietal.dev/#/boilerplate/detect-collisions?pans=html,console)\n\n## Installation\n\n```bash\nnpm i detect-collisions --save\n```\n\n## API Documentation\n\nFor detailed documentation on the library's API, refer to the following link:\n\n[Detect-Collisions API Documentation](https://prozi.github.io/detect-collisions/)\n\n## Usage\n\n### Step 1: Initialize Collision System\n\nInitialize a unique collision system using Detect-Collisions:\n\n```ts\nconst { System } = require(\"detect-collisions\");\nconst system = new System();\n```\n\n### Step 2: Understand Body Attributes\n\nBodies possess various properties:\n\n- **Position**: Use `setPosition(x: number, y: number)` for teleport and `move(speed: number)` for moving forward in direction of its angle.\n- **Scale**: Use `setScale(x: number, y: number)` for setting and `scale: Vector` for getting scale\n- **Rotation**: Use `setAngle(radians: number)` for setting and `angle: number` for getting and `deg2rad(degrees: number)` to convert to radians.\n- **Offset**: Use `setOffset(offset: Vector)` for setting and `offset: Vector` for getting offset from the body center.\n- **AABB Bounding Box**: Use `aabb: BBox` for inserted or `getAABBAsBBox(): BBox` for non inserted bodies to get the bounding box.\n- **Padding**: Use `padding: number` and set to nonzero value to reduce costly reinserts on attributes' change.\n- **Collision Filtering**: Use `group: number` for collision filtering, with a range within 0x0 ~ 0x7fffffff.\n- **Body Options**: [Read more in BodyOptions documentation](https://prozi.github.io/detect-collisions/interfaces/BodyOptions.html)\n\n### Step 3: Create and Manage Bodies\n\nCreate bodies of various types and manage them:\n\n```ts\nconst {\n  Box,\n  Circle,\n  Ellipse,\n  Line,\n  Point,\n  Polygon,\n} = require(\"detect-collisions\");\n\n// Example: Create and insert box1 body\nconst box1 = system.createBox(position, width, height, options);\n// Example: Create box2 body\nconst box2 = new Box(position, width, height, options);\n// Example: Insert box2 body\nsystem.insert(box2);\n```\n\n### Step 4: Manipulate Bodies\n\nManipulate body attributes and update the collision system:\n\n```ts\n// if omitted updateNow is true\nconst updateNow = false;\n// this should be time scaled, 1 for example\nconst speed = 1;\n\n// teleport\nbox.setPosition(x, y, updateNow);\nbox.setScale(scaleX, scaleY, updateNow);\nbox.setAngle(angle, updateNow);\nbox.move(speed, updateNow);\nbox.setOffset({ x, y }, updateNow);\nconsole.log(box.dirty); // true\n\nbox.updateBody(); // Update the body once, when all manipulations are done\nconsole.log(box.dirty); // false\n\nbox.group = group; // Immediate effect, no body/system update needed\nconsole.log(box.dirty); // false\n```\n\n### Step 5: Collision Detection and Resolution\n\nDetect collisions and respond accordingly:\n\n```ts\nconst callback = (result) =\u003e {\n  console.info(result);\n}\n\nif (system.checkAll(callback)) {\n  // Do something yourself\n}\n\nif (system.checkOne(body, callback)) {\n  // Do something yourself\n}\n\n// Or separate bodies based on isStatic/isTrigger\nsystem.separate();\n```\n\nGet exact collision points:\n\n```ts\nconst { a, b } = result;\nconst points = system.getCollisionPoints(a, b)\n```\n\n### Step 6: Cleaning Up\n\nRemove bodies when they're no longer needed:\n\n```ts\nsystem.remove(body);\n```\n\nAnd that's it! You're now ready to utilize the Detect-Collisions library in your project.\n\n## Visual Debugging with Rendering\n\nTo facilitate debugging, Detect-Collisions allows you to visually represent the collision bodies. By invoking the `draw()` method and supplying a 2D context of a `\u003ccanvas\u003e` element, you can draw all the bodies within a collision system. You can also opt to draw individual bodies.\n\n```ts\nconst canvas = document.createElement(\"canvas\");\nconst context = canvas.getContext(\"2d\");\n\ncontext.strokeStyle = \"#FFFFFF\";\ncontext.beginPath();\n// draw specific body\nbody.draw(context);\n// draw whole system\nsystem.draw(context);\ncontext.stroke();\n```\n\nTo assess the [Bounding Volume Hierarchy](https://en.wikipedia.org/wiki/Bounding_volume_hierarchy), you can draw the BVH.\n\n```ts\ncontext.strokeStyle = \"#FFFFFF\";\ncontext.beginPath();\n// draw specific body bounding box\nbody.drawBVH(context);\n// draw bounding volume hierarchy of the system\nsystem.drawBVH(context);\ncontext.stroke();\n```\n\n## Raycasting\n\nDetect-Collisions provides the functionality to gather raycast data. Here's how:\n\n```ts\nconst start = { x: 0, y: 0 };\nconst end = { x: 0, y: -10 };\nconst hit = system.raycast(start, end, (body, ray) =\u003e {\n  // if you don't want the body to be hit by raycast return false\n  return true;\n});\n\nif (hit) {\n  const { point, body } = hit;\n\n  console.log({ point, body });\n}\n```\n\nIn this example, `point` is a `Vector` with the coordinates of the nearest intersection, and `body` is a reference to the closest body.\n\n## Usage in Browsers\n\nJust do what I did here, import from proper cdn as module, and v'oila:\n\n\u003chttps://code.pietal.dev/#/boilerplate/detect-collisions?pans=html,console\u003e\n\n## Contributing to the Project\n\nWe welcome contributions! Feel free to open a merge request. When doing so, please adhere to the following code style guidelines:\n\n- Execute the `npm run precommit` script prior to submitting your merge request\n- Follow the [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/#summary) standard\n- Refrain from using the `any` type\n\n## Additional Considerations\n\n### Why not use a physics engine?\n\nWhile physics engines like [Matter-js](https://github.com/liabru/matter-js) or [Planck.js](https://github.com/shakiba/planck.js) are recommended for projects that need comprehensive physics simulation, not all projects require such complexity. In fact, using a physics engine solely for collision detection can lead to unnecessary overhead and complications due to built-in assumptions (gravity, velocity, friction, etc.). Detect-Collisions is purpose-built for efficient and robust collision detection, making it an excellent choice for projects that primarily require this functionality. It can also serve as the foundation for a custom physics engine.\n\n## Benchmark\n\nThis will provide you with the results of both the insertion test benchmark and a headless [Stress Demo](https://prozi.github.io/detect-collisions/demo/?stress) benchmark, featuring moving bodies, with increasing amounts in each step.\n\n```bash\ngit clone https://github.com/Prozi/detect-collisions.git\ncd detect-collisions\nnpm i \u0026\u0026 npm run build # will build \u0026 run tests \u0026 run benchmarks\n```\n\n## License\n\nMIT\n\n## You can buy me a coffee\n\n\u003chttps://paypal.me/jacekpietal\u003e\n","funding_links":["https://paypal.me/jacekpietal"],"categories":["typescript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FProzi%2Fdetect-collisions","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FProzi%2Fdetect-collisions","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FProzi%2Fdetect-collisions/lists"}