Skip to content

Commit

Permalink
Merge release-2.13
Browse files Browse the repository at this point in the history
Release 2.13
  • Loading branch information
axelpale authored Mar 13, 2023
2 parents ba4d830 + 7bb46d7 commit 6882626
Show file tree
Hide file tree
Showing 57 changed files with 1,441 additions and 122 deletions.
621 changes: 509 additions & 112 deletions docs/API.md

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions docs/generate.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,14 @@ yamdog.generate({
poly2: '#affineplanepoly2',
quat4: '#affineplanequat4',
rot2: '#affineplanerot2',
scalar1: '#affineplanescalar1',
scalar2: '#affineplanescalar2',
scalar3: '#affineplanescalar3',
segment2: '#affineplanesegment2',
size2: '#affineplanesize2',
size3: '#affineplanesize3',
sphere2: '#affineplanesphere2',
sphere3: '#affineplanesphere3',
vec2: '#affineplanevec2',
vec3: '#affineplanevec3',
vec4: '#affineplanevec4',
Expand Down
39 changes: 39 additions & 0 deletions lib/box3/collide.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
const collide2 = require('../box2/collide')

module.exports = function (b, bb) {
// @affineplane.box3.collide(b, bb)
//
// Test if the two boxes collide.
// The boxes collide when the intersection of their solid cuboids
// is not empty.
//
// Parameters:
// b
// a box3, in the reference basis
// bb
// a box3, in the reference basis
//
// Return:
// a boolean, true if boxes collide.
//

// The box3 can rotate only around z. Therefore we check z-collision first
// and then proceed to more throughout 2D collision check.

// Build ranges
const bmin = b.z
const bmax = b.z + b.d
const bbmin = bb.z
const bbmax = bb.z + bb.d

// Range collision check.
if ((bmin >= bbmin && bmin <= bbmax) ||
(bmax >= bbmin && bmax <= bbmax) ||
(bmin <= bbmin && bmax >= bbmin) ||
(bmin <= bbmax && bmax >= bbmax)) {
// assert: one of the range ends is in the other
return collide2(b, bb)
}
// Else the boxes cannot hit regardless the position and orientation.
return false
}
1 change: 1 addition & 0 deletions lib/box3/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ exports.almostEqual = require('./almostEqual')
exports.at = require('./at')
exports.atBox = require('./atBox')
exports.atNorm = require('./atNorm')
exports.collide = require('./collide')
exports.create = require('./create')
exports.fromPoints = require('./fromPoints')
exports.getAngle = require('./getAngle')
Expand Down
4 changes: 2 additions & 2 deletions lib/box3/translate.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ module.exports = (box, vec) => {
// box
// a box3
// vec
// a vec3
// a vec3 or vec2
//
// Return
// a box3
Expand All @@ -18,7 +18,7 @@ module.exports = (box, vec) => {
b: box.b,
x: box.x + vec.x,
y: box.y + vec.y,
z: box.z + vec.z,
z: box.z + (vec.z || 0),
w: box.w,
h: box.h,
d: box.d
Expand Down
2 changes: 2 additions & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ exports.plane3 = exports.basis3
exports.point2 = require('./point2')
exports.point3 = require('./point3')

// TODO exports.range1 = require('./range1')

// TODO Ray. A line but into one direction only.
// exports.ray3 = require('./ray3')

Expand Down
21 changes: 21 additions & 0 deletions lib/plane2/at.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module.exports = (plane, x, y) => {
// @affineplane.plane2.at(plane, x, y)
//
// Take a point on the plane and transit it to the reference basis.
//
// Parameters
// plane
// a plane2, in the reference basis.
// x
// a number, the horizontal coordinate on the plane
// y
// a number, the vertical coordinate on the plane
//
// Return
// a point2 in the reference basis.
//
return {
x: plane.a * x - plane.b * y + plane.x,
y: plane.b * x + plane.a * y + plane.y
}
}
1 change: 1 addition & 0 deletions lib/plane2/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ exports.I = { a: 1, b: 0, x: 0, y: 0 }
exports.IDENTITY = exports.I

exports.almostEqual = require('./almostEqual')
exports.at = require('./at')
exports.between = require('./difference')
exports.clone = require('./copy')
exports.combine = require('./compose')
Expand Down
27 changes: 27 additions & 0 deletions lib/plane3/at.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
module.exports = (plane, x, y, z) => {
// @affineplane.plane3.at(plane, x, y, z)
//
// Take a point relative to the plane and transit it to the reference basis.
//
// Parameters
// plane
// a plane3, in the reference basis.
// x
// a number, the horizontal coordinate on the plane
// y
// a number, the vertical coordinate on the plane
// z
// a number, the depth offset relative to the plane
//
// Return
// a point3 in the reference basis.
//
const a = plane.a
const b = plane.b
const m = Math.sqrt(a * a + b * b)
return {
x: a * x - b * y + plane.x,
y: b * x + a * y + plane.y,
z: m * z + plane.z
}
}
1 change: 1 addition & 0 deletions lib/plane3/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ exports.I = { a: 1, b: 0, x: 0, y: 0, z: 0 }
exports.IDENTITY = exports.I

exports.almostEqual = require('./almostEqual')
exports.at = require('./at')
exports.between = require('./difference')
exports.clone = require('./copy')
exports.compose = require('./compose')
Expand Down
1 change: 1 addition & 0 deletions lib/point3/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ exports.offset = require('./offset')
exports.polarOffset = require('./polarOffset')
exports.projectToPlane = require('./projectToPlane')
exports.projectTo = exports.projectToPlane
exports.rotateAroundLine = require('./rotateAroundLine')
exports.rotateBy = require('./rotateBy')
exports.round = require('./round')
exports.toArray = require('./toArray')
Expand Down
32 changes: 32 additions & 0 deletions lib/point3/rotateAroundLine.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
const fromAxisAngle = require('../quat4/fromAxisAngle')
const rotateVector = require('../quat4/rotateVector')
const pointDiff = require('./difference')
const pointTranslate = require('./translate')

module.exports = function (p, line, rads) {
// @affineplane.point3.rotateAroundLine(p, line, rads)
//
// Rotate a point around the axis line by the given radians.
//
// Parameters
// p
// a point3
// line
// a line3, the rotation axis
// rads
// a number, angle in radians
//
// Return
// a point3, the rotated point
//

// Convert to quaternion, note halved angle cuz will double.
const q = fromAxisAngle(line.span, rads / 2)
// Construct a vector to rotate.
const v = pointDiff(line.origin, p)
const vv = rotateVector(q, v)
// Apply the rotated vector to origin
const pp = pointTranslate(line.origin, vv)

return pp
}
2 changes: 1 addition & 1 deletion lib/point3/rotateBy.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module.exports = function (p, origin, roll, pitch) {
// @affineplane.point3.rotateBy(p, origin, roll, pitch)
// @affineplane.point3.rotateBy(p, origin, roll[, pitch])
//
// Rotate point around the given center point.
// Roll is applied before pitch.
Expand Down
1 change: 1 addition & 0 deletions lib/quat4/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ exports.fromVector = require('./fromVector')
exports.hamilton = require('./hamilton')
exports.multiply = exports.hamilton
exports.norm = require('./norm')
exports.rotateVector = require('./rotateVector')
49 changes: 49 additions & 0 deletions lib/quat4/rotateVector.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
module.exports = (quat, vec) => {
// @affineplane.quat4.rotateVector(quat, vec)
//
// Apply quaternion to rotate a vector.
// Note that the quaternion must rotate the vector twice to return it
// back to the 3D space. Therefore, if the quaternion was created using
// an angle like π/2, the vector will be rotated twice that amount, π.
//
// Parameters:
// quat
// a quat4, a quaternion.
// vec
// a vec3, the vector to rotate
//
// Return
// a vec3, the rotated vector.
//

const a = quat.a
const b = quat.b
const c = quat.c
const d = quat.d

// Rotation matrix construction.
// Algorithm from A.Watt and M.Watt 1992 via Wikipedia.
const s = 2 / (a * a + b * b + c * c + d * d)
const bs = b * s
const cs = c * s
const ds = d * s
const ab = a * bs
const ac = a * cs
const ad = a * ds
const bb = b * bs
const bc = b * cs
const bd = b * ds
const cc = c * cs
const cd = c * ds
const dd = d * ds

const x = vec.x
const y = vec.y
const z = vec.z

return {
x: x * (1 - cc - dd) + y * (bc - ad) + z * (bd + ac),
y: x * (bc + ad) + y * (1 - bb - dd) + z * (cd - ab),
z: x * (bd - ac) + y * (cd + ab) + z * (1 - bb - cc)
}
}
17 changes: 17 additions & 0 deletions lib/sphere2/atCenter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module.exports = (sp) => {
// @affineplane.sphere2.atCenter(sp)
//
// Get the center point of the sphere.
// Note that the sphere2 object itself can act as a point2 in many cases.
//
// Parameters:
// a sphere2
//
// Return
// a point2
//
return {
x: sp.x,
y: sp.y
}
}
21 changes: 21 additions & 0 deletions lib/sphere2/boundingBox.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module.exports = (sphere) => {
// @affineplane.sphere2.boundingBox(sphere)
//
// Get outer rectangular boundary of the given sphere.
//
// Parameters
// sphere
// a sphere2, in the reference basis.
//
// Return
// a box2, in the reference basis.
//

const r = sphere.r
const bx = sphere.x - r
const by = sphere.y - r
const dia = r + r

// Construct the bounding rect.
return { a: 1, b: 0, x: bx, y: by, w: dia, h: dia }
}
6 changes: 6 additions & 0 deletions lib/sphere2/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,20 @@
//
exports.almostEqual = require('./almostEqual')
exports.area = require('./area')
exports.atCenter = require('./atCenter')
exports.boundingBox = require('./boundingBox')
exports.collide = require('./collide')
exports.copy = require('./copy')
exports.create = require('./create')
exports.gap = require('./gap')
exports.hasPoint = require('./hasPoint')
exports.homothety = require('./homothety')
exports.offset = require('./offset')
exports.polarOffset = require('./polarOffset')
exports.rotateBy = require('./rotateBy')
exports.scaleBy = exports.homothety
exports.size = require('./size')
exports.transitFrom = require('./transitFrom')
exports.transitTo = require('./transitTo')
exports.translate = require('./translate')
exports.validate = require('./validate')
27 changes: 27 additions & 0 deletions lib/sphere2/polarOffset.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const sin = Math.sin
const cos = Math.cos

module.exports = (sp, dist, theta) => {
// @affineplane.sphere2.polarOffset(sphere, distance, theta)
//
// Offset a sphere by the given distance towards the direction given by
// the theta angles.
//
// Parameters:
// sphere
// a sphere2
// distance
// a number, the distance from p.
// theta
// a number, the angle around z-axis, the azimuthal angle.
// .. Clockwise rotation, following the right-hand rule.
//
// Return
// a sphere2
//
return {
x: sp.x + dist * cos(theta),
y: sp.y + dist * sin(theta),
r: sp.r
}
}
26 changes: 26 additions & 0 deletions lib/sphere2/rotateBy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const rotate = require('../point2/rotateBy')

module.exports = function (sp, origin, radians) {
// @affineplane.sphere2.rotateBy(sp, origin, radians)
//
// Rotate a sphere about an origin point.
//
// Parameters
// sp
// a sphere2
// origin
// a point2, the point around to rotate
// radians
// a number, angle in radians
//
// Return
// a sphere2, the rotated sphere
//

// Reuse point rotation
const pole = rotate(sp, origin, radians)
// Patch radius
pole.r = sp.r

return pole
}
18 changes: 18 additions & 0 deletions lib/sphere2/size.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module.exports = (sphere) => {
// @affineplane.sphere2.size(sphere)
//
// Get the rectangular size of the circle.
//
// Parameters:
// sphere
// a sphere2 in the reference basis.
//
// Return
// a size2 in the reference basis.
//
const diam = sphere.r + sphere.r
return {
w: diam,
h: diam
}
}
Loading

0 comments on commit 6882626

Please sign in to comment.