-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Release 2.12
- Loading branch information
Showing
141 changed files
with
3,895 additions
and
76 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
const getBasis = require('./getBasis') | ||
const getBasisInverse = require('./getBasisInverse') | ||
const getCircle = require('./getCircle') | ||
const getSegments = require('./getSegments') | ||
const planeCompose = require('../plane2/compose') | ||
const pointTransitFrom = require('../point2/transitFrom') | ||
const collideCircles = require('../sphere2/collide') | ||
const collideSegments = require('../segment2/collide') | ||
|
||
const inside = (box, point) => { | ||
// Test if a point in the box basis is inside the box. | ||
const px = point.x | ||
const py = point.y | ||
return px >= 0 && px <= box.w && py >= 0 && py <= box.h | ||
} | ||
|
||
module.exports = function (b, bb) { | ||
// @affineplane.box2.collide(b, bb) | ||
// | ||
// Do two boxes collide? | ||
// | ||
// Parameters: | ||
// b | ||
// a box2, in the reference basis | ||
// bb | ||
// a box2, in the reference basis | ||
// | ||
// Return: | ||
// a boolean, true if boxes collide. | ||
// | ||
|
||
// We can first quickly determine if boxes cannot collide by | ||
// comparing their bounding spheres. If the spheres do not collide, | ||
// the boxes cannot collide. If the spheres do collide, we need to | ||
// test further do the boxes truly collide. | ||
|
||
// Boxes can collide without edges crossing. | ||
// Think of nested boxes. | ||
// Also, boxes can collide without any of the corners inside another. | ||
// Think of two long boards crossed. | ||
|
||
// Therefore we need to check if at least one of the corners is inside | ||
// the other box, and if not, check if any of the edge segments collide. | ||
// We need 4x4 segment collision tests. | ||
|
||
// For nested boxes, we need to test if a corner point is inside. | ||
// We do not know the nesting order, thus test both directions. | ||
// We need to test only one corner per direction. Alternatively we could | ||
// test each corner, which would imply 4 transits and 4 tests. | ||
|
||
// Test bounding circle collision | ||
const bCircle = getCircle(b) | ||
const bbCircle = getCircle(bb) | ||
const circleHit = collideCircles(bCircle, bbCircle) | ||
if (!circleHit) { | ||
// Bounding circles do not touch, thus we can exit quickly. | ||
return false | ||
} | ||
// Else the circles collide and we need to inspect further. | ||
|
||
// Test if boxes are nested. | ||
// Form transitions between boxes | ||
const bToRef = getBasis(b) | ||
const refToB = getBasisInverse(b) | ||
const bbToRef = getBasis(bb) | ||
const refToBb = getBasisInverse(bb) | ||
// bToBb is a box plane b, represented on the box plane bb. | ||
const bToBb = planeCompose(refToBb, bToRef) | ||
// bbToB is a box plane bb, represented on the box plane b. | ||
const bbToB = planeCompose(refToB, bbToRef) | ||
|
||
// Test if top left corner of box b is inside box bb. | ||
const corner = { x: 0, y: 0 } | ||
const cornerInBb = pointTransitFrom(corner, bToBb) | ||
const cornerInB = pointTransitFrom(corner, bbToB) | ||
|
||
const isInsideBb = inside(bb, cornerInBb) | ||
const isInsideB = inside(b, cornerInB) | ||
|
||
if (isInsideB || isInsideBb) { | ||
// Boxes are nested and therefore collide. | ||
return true | ||
} | ||
// Else, boxes are not nested, but still can collide. | ||
|
||
// Test if box segments cross. Any crossing implies collision. | ||
const segsB = getSegments(b) | ||
const segsBb = getSegments(bb) | ||
const len = 4 | ||
|
||
let i, j, segb, segbb | ||
// For each b segment | ||
for (i = 0; i < len; i += 1) { | ||
segb = segsB[i] | ||
// For each bb segment | ||
for (j = 0; j < len; j += 1) { | ||
segbb = segsBb[j] | ||
if (collideSegments(segb, segbb)) { | ||
return true | ||
} | ||
} | ||
} | ||
// Segments did not cross. | ||
|
||
return false | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
const at = require('./at') | ||
|
||
module.exports = (box) => { | ||
// @affineplane.box2.getCircle(box) | ||
// @affineplane.box2.getSphere | ||
// | ||
// Get the circumscribed circle of the box. In other words, get the circle | ||
// that contains the box so that the box corners are on it. | ||
// The resulting circle is also the minimum bounding circle of the box. | ||
// | ||
// Parameters | ||
// box | ||
// a box2, in the reference basis. | ||
// | ||
// Return | ||
// a sphere2 | ||
// | ||
|
||
// Circle center | ||
const hw = box.w / 2 | ||
const hh = box.h / 2 | ||
const p = at(box, hw, hh) | ||
// Patch radius | ||
p.r = Math.sqrt(hw * hw + hh * hh) | ||
|
||
return p | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
const at = require('./at') | ||
|
||
module.exports = (box) => { | ||
// @affineplane.box2.getSegments(box) | ||
// | ||
// Get the four line segments of the box. | ||
// | ||
// Parameters: | ||
// box | ||
// a box2, in the reference basis. | ||
// | ||
// Return | ||
// array of segment2, each segment in the reference basis. | ||
// | ||
const c00 = at(box, 0, 0) | ||
const cW0 = at(box, box.w, 0) | ||
const cWH = at(box, box.w, box.h) | ||
const c0H = at(box, 0, box.h) | ||
|
||
return [ | ||
[c00, cW0], | ||
[cW0, cWH], | ||
[cWH, c0H], | ||
[c0H, c00] | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
const getBasisInverse = require('./getBasisInverse') | ||
const pointTransitFrom = require('../point2/transitFrom') | ||
|
||
module.exports = function (box, point) { | ||
// @affineplane.box2.hasPoint(box, point) | ||
// | ||
// Test if a point is inside the box. If the point is at the box edge, | ||
// it is counted as being inside. | ||
// | ||
// Parameters: | ||
// box | ||
// a box2, in the reference basis. | ||
// point | ||
// a point2, in the reference basis. | ||
// | ||
// Return: | ||
// a boolean | ||
// | ||
|
||
// Note: we thought it would be practical to count inner box (0,0) inside | ||
// and inner box (w,h) outside. However, due to rotation that makes things | ||
// confusing. Therefore all edge points are counted as inside. | ||
|
||
// Transit the point to the inner box basis for easier checking. | ||
const innerBasis = getBasisInverse(box) | ||
const innerPoint = pointTransitFrom(point, innerBasis) | ||
|
||
// Test the point | ||
const px = innerPoint.x | ||
const py = innerPoint.y | ||
|
||
return px >= 0 && px <= box.w && py >= 0 && py <= box.h | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
module.exports = (box, vec) => { | ||
// @affineplane.box2.translate(box, vec) | ||
// | ||
// Move the box horizontally and vertically by a vector. | ||
// See affineplane.box2.offset to move by scalars. | ||
// | ||
// Parameters: | ||
// box | ||
// a box2 | ||
// vec | ||
// a vec2 | ||
// | ||
// Return | ||
// a box2 | ||
// | ||
return { | ||
a: box.a, | ||
b: box.b, | ||
x: box.x + vec.x, | ||
y: box.y + vec.y, | ||
w: box.w, | ||
h: box.h | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
module.exports = (box) => { | ||
// @affineplane.box3.getBasisInverse(box) | ||
// | ||
// Get the outer basis of the box represented in the box basis. | ||
// The scale of the resulting basis is always 1. | ||
// See also affineplane.box3.getBasis. | ||
// | ||
// Parameters: | ||
// box | ||
// a box3 in the reference basis. | ||
// | ||
// Return | ||
// a plane3 in the box basis. The outer basis. | ||
// | ||
|
||
return { | ||
a: box.a, | ||
b: -box.b, | ||
x: -box.a * box.x - box.b * box.y, | ||
y: box.b * box.x - box.a * box.y, | ||
z: -box.z | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
const at = require('./at') | ||
|
||
module.exports = (box) => { | ||
// @affineplane.box3.getSphere(box) | ||
// | ||
// Get the circumscribed sphere of the box. In other words, get the sphere | ||
// that contains the box so that the box corners are on the sphere. | ||
// The resulting sphere is also the minimum bounding sphere of the box. | ||
// | ||
// Parameters | ||
// box | ||
// a box3, in the reference basis. | ||
// | ||
// Return | ||
// a sphere3 | ||
// | ||
|
||
// Sphere center | ||
const hw = box.w / 2 | ||
const hh = box.h / 2 | ||
const hd = box.d / 2 | ||
const p = at(box, hw, hh, hd) | ||
// Patch radius | ||
p.r = Math.sqrt(hw * hw + hh * hh + hd * hd) | ||
|
||
return p | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
const getBasisInverse = require('./getBasisInverse') | ||
const pointTransitFrom = require('../point3/transitFrom') | ||
|
||
module.exports = function (box, point) { | ||
// @affineplane.box3.hasPoint(box, point) | ||
// | ||
// Test if a point is inside the box. If the point is at the box edge, | ||
// it is counted as being inside. | ||
// | ||
// Parameters: | ||
// box | ||
// a box3, in the reference basis. | ||
// point | ||
// a point3, in the reference basis. | ||
// | ||
// Return: | ||
// a boolean | ||
// | ||
|
||
// Transit the point to the inner box basis for easier checking. | ||
const innerBasis = getBasisInverse(box) | ||
const innerPoint = pointTransitFrom(point, innerBasis) | ||
|
||
// Test the point | ||
const px = innerPoint.x | ||
const py = innerPoint.y | ||
const pz = innerPoint.z | ||
|
||
return (px >= 0 && px <= box.w && | ||
py >= 0 && py <= box.h && | ||
pz >= 0 && pz <= box.d) | ||
} |
Oops, something went wrong.