├── .gitignore ├── .npmignore ├── LICENSE.md ├── README.md ├── index.js ├── package.json └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | bower_components 2 | node_modules 3 | *.log 4 | .DS_Store 5 | bundle.js 6 | from-points.js 7 | 8 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | bower_components 2 | node_modules 3 | *.log 4 | .DS_Store 5 | bundle.js 6 | test 7 | test.js 8 | demo/ 9 | .npmignore 10 | LICENSE.md -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2015 Matt DesLauriers 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 20 | OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ray-plane-intersection 2 | 3 | [![stable](http://badges.github.io/stability-badges/dist/stable.svg)](http://github.com/badges/stability-badges) 4 | 5 | Whether a 3D picking ray intersects with a plane. The plane is defined as having a `normal` [x, y, z] and `distance`. 6 | 7 | ```js 8 | var intersect = require('ray-plane-intersection') 9 | var origin = [1, 0, 4] 10 | var dir = [0, 0, -1] 11 | var normal = [0, 0, 1] 12 | var distance = 0 13 | 14 | var hit = intersect(out, origin, dir, normal, distance) 15 | 16 | if (hit) { //collision occurred 17 | console.log(hit) // [1, 0, 0] 18 | } 19 | ``` 20 | 21 | The distance can be determined with a second point on the plane, like so: 22 | 23 | ```js 24 | var d = -dot(normal, point) 25 | ``` 26 | 27 | PRs welcome. 28 | 29 | ## Usage 30 | 31 | [![NPM](https://nodei.co/npm/ray-plane-intersection.png)](https://www.npmjs.com/package/ray-plane-intersection) 32 | 33 | #### `hit = intersect(out, origin, direction, normal, distance)` 34 | 35 | Test whether the ray `(origin, direction)` intersects with the plane `(normal, distance)`. 36 | 37 | If an intersection occurs, it is stored in `out` [x, y, z] and returned. Otherwise `null` is returned. 38 | 39 | ## See Also 40 | 41 | - [get-plane-normal](https://www.npmjs.com/package/get-plane-normal) 42 | - [find-basis-3d](https://www.npmjs.com/package/find-basis-3d) 43 | - [ray-triangle-intersection](https://www.npmjs.com/package/ray-triangle-intersection) 44 | 45 | ## License 46 | 47 | MIT, see [LICENSE.md](http://github.com/mattdesl/ray-plane-intersection/blob/master/LICENSE.md) for details. 48 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var dot = require('gl-vec3/dot') 2 | var add = require('gl-vec3/add') 3 | var scale = require('gl-vec3/scale') 4 | var copy = require('gl-vec3/copy') 5 | 6 | module.exports = intersectRayPlane 7 | 8 | var v0 = [0, 0, 0] 9 | 10 | function intersectRayPlane(out, origin, direction, normal, dist) { 11 | var denom = dot(direction, normal) 12 | if (denom !== 0) { 13 | var t = -(dot(origin, normal) + dist) / denom 14 | if (t < 0) { 15 | return null 16 | } 17 | scale(v0, direction, t) 18 | return add(out, origin, v0) 19 | } else if (dot(normal, origin) + dist === 0) { 20 | return copy(out, origin) 21 | } else { 22 | return null 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ray-plane-intersection", 3 | "version": "1.0.0", 4 | "description": "whether a picking ray intersects with a plane", 5 | "main": "index.js", 6 | "license": "MIT", 7 | "author": { 8 | "name": "Matt DesLauriers", 9 | "email": "dave.des@gmail.com", 10 | "url": "https://github.com/mattdesl" 11 | }, 12 | "dependencies": { 13 | "gl-vec3": "^1.0.3" 14 | }, 15 | "devDependencies": { 16 | "tape": "^4.0.0" 17 | }, 18 | "scripts": { 19 | "test": "node test.js" 20 | }, 21 | "keywords": [ 22 | "plane", 23 | "ray", 24 | "camera", 25 | "pick", 26 | "ray", 27 | "picking", 28 | "raycast", 29 | "cast", 30 | "intersect", 31 | "intersection", 32 | "hit", 33 | "test", 34 | "hittest", 35 | "3d", 36 | "2d", 37 | "planes", 38 | "plane" 39 | ], 40 | "repository": { 41 | "type": "git", 42 | "url": "git://github.com/mattdesl/ray-plane-intersection.git" 43 | }, 44 | "homepage": "https://github.com/mattdesl/ray-plane-intersection", 45 | "bugs": { 46 | "url": "https://github.com/mattdesl/ray-plane-intersection/issues" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | var intersect = require('./') 2 | var test = require('tape') 3 | 4 | test('whether a picking ray intersects with a plane', function(t) { 5 | var out = [] 6 | var hit = intersect(out, [1, 0, 4], [0, 0, -1], [0, 0, 1], 0) 7 | t.deepEqual(hit, [1, 0, 0]) 8 | 9 | hit = intersect(out, [1, 2, 4], [0, 0, -1], [0, 0, 1], -1) 10 | t.deepEqual(hit, [1, 2, 1]) 11 | 12 | hit = intersect(out, [0, 0, 4], [-1, 0, 0], [-1, 0, 0], 1) 13 | t.deepEqual(hit, null) 14 | 15 | //dot product == 0 16 | hit = intersect(out, [0, 0, 4], [0, 0, -1], [1, 0, 0], 1) 17 | t.equal(hit, null) 18 | 19 | hit = intersect(out, [0, 0, 4], [0, 0, -1], [1, 0, 0], 0) 20 | t.deepEqual(hit, [0, 0, 4]) 21 | 22 | t.end() 23 | }) 24 | 25 | 26 | --------------------------------------------------------------------------------