Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@js-draw/math

Package Overview
Dependencies
Maintainers
1
Versions
23
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@js-draw/math - npm Package Compare versions

Comparing version 1.3.0 to 1.3.1

dist/cjs/Mat33.fromCSSMatrix.test.d.ts

32

dist/cjs/Mat33.d.ts

@@ -110,5 +110,18 @@ import { Point2, Vec2 } from './Vec2';

getScaleFactor(): number;
/** Returns the `idx`-th column (`idx` is 0-indexed). */
getColumn(idx: number): Vec3;
/** Returns the magnitude of the entry with the largest entry */
maximumEntryMagnitude(): number;
/**
* Constructs a 3x3 translation matrix (for translating `Vec2`s) using
* **transformVec2**.
*
* Creates a matrix in the form
* $$
* \begin{pmatrix}
* 1 & 0 & {\tt amount.x}\\
* 0 & 1 & {\tt amount.y}\\
* 0 & 0 & 1
* \end{pmatrix}
* $$
*/

@@ -118,5 +131,22 @@ static translation(amount: Vec2): Mat33;

static scaling2D(amount: number | Vec2, center?: Point2): Mat33;
/** @see {@link fromCSSMatrix} */
/**
* **Note**: Assumes `this.c1 = this.c2 = 0` and `this.c3 = 1`.
*
* @see {@link fromCSSMatrix} and {@link toSafeCSSTransformList}
*/
toCSSMatrix(): string;
/**
* @beta May change or even be removed between minor releases.
*
* Converts this matrix into a list of CSS transforms that attempt to preserve
* this matrix's translation.
*
* In Chrome/Firefox, translation attributes only support 6 digits (likely an artifact
* of using lower-precision floating point numbers). This works around
* that by expanding this matrix into the product of several CSS transforms.
*
* **Note**: Assumes `this.c1 = this.c2 = 0` and `this.c3 = 1`.
*/
toSafeCSSTransformList(): string;
/**
* Converts a CSS-form `matrix(a, b, c, d, e, f)` to a Mat33.

@@ -123,0 +153,0 @@ *

@@ -9,2 +9,3 @@ "use strict";

const Vec3_1 = __importDefault(require("./Vec3"));
const rounding_1 = require("./rounding");
/**

@@ -263,5 +264,26 @@ * Represents a three dimensional linear transformation or

}
/** Returns the `idx`-th column (`idx` is 0-indexed). */
getColumn(idx) {
return Vec3_1.default.of(this.rows[0].at(idx), this.rows[1].at(idx), this.rows[2].at(idx));
}
/** Returns the magnitude of the entry with the largest entry */
maximumEntryMagnitude() {
let greatestSoFar = Math.abs(this.a1);
for (const entry of this.toArray()) {
greatestSoFar = Math.max(greatestSoFar, Math.abs(entry));
}
return greatestSoFar;
}
/**
* Constructs a 3x3 translation matrix (for translating `Vec2`s) using
* **transformVec2**.
*
* Creates a matrix in the form
* $$
* \begin{pmatrix}
* 1 & 0 & {\tt amount.x}\\
* 0 & 1 & {\tt amount.y}\\
* 0 & 0 & 1
* \end{pmatrix}
* $$
*/

@@ -301,3 +323,7 @@ static translation(amount) {

}
/** @see {@link fromCSSMatrix} */
/**
* **Note**: Assumes `this.c1 = this.c2 = 0` and `this.c3 = 1`.
*
* @see {@link fromCSSMatrix} and {@link toSafeCSSTransformList}
*/
toCSSMatrix() {

@@ -307,2 +333,119 @@ return `matrix(${this.a1},${this.b1},${this.a2},${this.b2},${this.a3},${this.b3})`;

/**
* @beta May change or even be removed between minor releases.
*
* Converts this matrix into a list of CSS transforms that attempt to preserve
* this matrix's translation.
*
* In Chrome/Firefox, translation attributes only support 6 digits (likely an artifact
* of using lower-precision floating point numbers). This works around
* that by expanding this matrix into the product of several CSS transforms.
*
* **Note**: Assumes `this.c1 = this.c2 = 0` and `this.c3 = 1`.
*/
toSafeCSSTransformList() {
// Check whether it's safe to return just the CSS matrix
const translation = Vec2_1.Vec2.of(this.a3, this.b3);
const translationRoundedX = (0, rounding_1.toRoundedString)(translation.x);
const translationRoundedY = (0, rounding_1.toRoundedString)(translation.y);
const nonDigitsRegex = /[^0-9]+/g;
const translationXDigits = translationRoundedX.replace(nonDigitsRegex, '').length;
const translationYDigits = translationRoundedY.replace(nonDigitsRegex, '').length;
// Is it safe to just return the default CSS matrix?
if (translationXDigits <= 5 && translationYDigits <= 5) {
return this.toCSSMatrix();
}
// Remove the last column (the translation column)
let transform = new Mat33(this.a1, this.a2, 0, this.b1, this.b2, 0, 0, 0, 1);
const transforms = [];
let lastScale = null;
// Appends a translate() command to the list of `transforms`.
const addTranslate = (translation) => {
lastScale = null;
if (!translation.eq(Vec2_1.Vec2.zero)) {
transforms.push(`translate(${(0, rounding_1.toRoundedString)(translation.x)}px, ${(0, rounding_1.toRoundedString)(translation.y)}px)`);
}
};
// Appends a scale() command to the list of transforms, possibly merging with
// the last command, if a scale().
const addScale = (scale) => {
// Merge with the last scale
if (lastScale) {
const newScale = lastScale.scale(scale);
// Don't merge if the new scale has very large values
if (newScale.maximumEntryMagnitude() < 1e7) {
const previousCommand = transforms.pop();
console.assert(previousCommand.startsWith('scale'), 'Invalid state: Merging scale commands');
scale = newScale;
}
}
if (scale.x === scale.y) {
transforms.push(`scale(${(0, rounding_1.toRoundedString)(scale.x)})`);
}
else {
transforms.push(`scale(${(0, rounding_1.toRoundedString)(scale.x)}, ${(0, rounding_1.toRoundedString)(scale.y)})`);
}
lastScale = scale;
};
// Returns the number of digits before the `.` in the given number string.
const digitsPreDecimalCount = (numberString) => {
let decimalIndex = numberString.indexOf('.');
if (decimalIndex === -1) {
decimalIndex = numberString.length;
}
return numberString.substring(0, decimalIndex).replace(nonDigitsRegex, '').length;
};
// Returns the number of digits (positive for left shift, negative for right shift)
// required to shift the decimal to the middle of the number.
const getShift = (numberString) => {
const preDecimal = digitsPreDecimalCount(numberString);
const postDecimal = (numberString.match(/[.](\d*)/) ?? ['', ''])[1].length;
// The shift required to center the decimal point.
const toCenter = postDecimal - preDecimal;
// toCenter is positive for a left shift (adding more pre-decimals),
// so, after applying it,
const postShiftPreDecimal = preDecimal + toCenter;
// We want the digits before the decimal to have a length at most 4, however.
// Thus, right shift until this is the case.
const shiftForAtMost5DigitsPreDecimal = 4 - Math.max(postShiftPreDecimal, 4);
return toCenter + shiftForAtMost5DigitsPreDecimal;
};
const addShiftedTranslate = (translate, depth = 0) => {
const xString = (0, rounding_1.toRoundedString)(translate.x);
const yString = (0, rounding_1.toRoundedString)(translate.y);
const xShiftDigits = getShift(xString);
const yShiftDigits = getShift(yString);
const shift = Vec2_1.Vec2.of(Math.pow(10, xShiftDigits), Math.pow(10, yShiftDigits));
const invShift = Vec2_1.Vec2.of(Math.pow(10, -xShiftDigits), Math.pow(10, -yShiftDigits));
addScale(invShift);
const shiftedTranslate = translate.scale(shift);
const roundedShiftedTranslate = Vec2_1.Vec2.of(Math.floor(shiftedTranslate.x), Math.floor(shiftedTranslate.y));
addTranslate(roundedShiftedTranslate);
// Don't recurse more than 3 times -- the more times we recurse, the more
// the scaling is influenced by error.
if (!roundedShiftedTranslate.eq(shiftedTranslate) && depth < 3) {
addShiftedTranslate(shiftedTranslate.minus(roundedShiftedTranslate), depth + 1);
}
addScale(shift);
return translate;
};
const adjustTransformFromScale = () => {
if (lastScale) {
const scaledTransform = transform.rightMul(Mat33.scaling2D(lastScale));
// If adding the scale to the transform leads to large values, avoid
// doing this.
if (scaledTransform.maximumEntryMagnitude() < 1e12) {
transforms.pop();
transform = transform.rightMul(Mat33.scaling2D(lastScale));
lastScale = null;
}
}
};
addShiftedTranslate(translation);
adjustTransformFromScale();
if (!transform.eq(Mat33.identity)) {
transforms.push(transform.toCSSMatrix());
}
return transforms.join(' ');
}
/**
* Converts a CSS-form `matrix(a, b, c, d, e, f)` to a Mat33.

@@ -321,26 +464,91 @@ *

}
const numberExp = '([-]?\\d*(?:\\.\\d*)?(?:[eE][-]?\\d+)?)';
const numberSepExp = '[, \\t\\n]';
const regExpSource = `^\\s*matrix\\s*\\(${[
// According to MDN, matrix(a,b,c,d,e,f) has form:
// ⎡ a c e ⎤
// ⎢ b d f ⎥
// ⎣ 0 0 1 ⎦
numberExp, numberExp, numberExp,
numberExp, numberExp, numberExp, // b, d, f
].join(`${numberSepExp}+`)}${numberSepExp}*\\)\\s*$`;
const matrixExp = new RegExp(regExpSource, 'i');
const match = matrixExp.exec(cssString);
if (!match) {
throw new Error(`Unsupported transformation: ${cssString}`);
const parseArguments = (argumentString) => {
return argumentString.split(/[, \t\n]+/g).map(argString => {
let isPercentage = false;
if (argString.endsWith('%')) {
isPercentage = true;
argString = argString.substring(0, argString.length - 1);
}
// Remove trailing px units.
argString = argString.replace(/px$/ig, '');
const numberExp = /^[-]?\d*(?:\.\d*)?(?:[eE][-+]?\d+)?$/i;
if (!numberExp.exec(argString)) {
throw new Error(`All arguments to transform functions must be numeric (state: ${JSON.stringify({
currentArgument: argString,
allArguments: argumentString,
})})`);
}
let argNumber = parseFloat(argString);
if (isPercentage) {
argNumber /= 100;
}
return argNumber;
});
};
const keywordToAction = {
matrix: (matrixData) => {
if (matrixData.length !== 6) {
throw new Error(`Invalid matrix argument: ${matrixData}. Must have length 6`);
}
const a = matrixData[0];
const b = matrixData[1];
const c = matrixData[2];
const d = matrixData[3];
const e = matrixData[4];
const f = matrixData[5];
const transform = new Mat33(a, c, e, b, d, f, 0, 0, 1);
return transform;
},
scale: (scaleArgs) => {
let scaleX, scaleY;
if (scaleArgs.length === 1) {
scaleX = scaleArgs[0];
scaleY = scaleArgs[0];
}
else if (scaleArgs.length === 2) {
scaleX = scaleArgs[0];
scaleY = scaleArgs[1];
}
else {
throw new Error(`The scale() function only supports two arguments. Given: ${scaleArgs}`);
}
return Mat33.scaling2D(Vec2_1.Vec2.of(scaleX, scaleY));
},
translate: (translateArgs) => {
let translateX = 0;
let translateY = 0;
if (translateArgs.length === 1) {
// If no y translation is given, assume 0.
translateX = translateArgs[0];
}
else if (translateArgs.length === 2) {
translateX = translateArgs[0];
translateY = translateArgs[1];
}
else {
throw new Error(`The translate() function requires either 1 or 2 arguments. Given ${translateArgs}`);
}
return Mat33.translation(Vec2_1.Vec2.of(translateX, translateY));
},
};
// A command (\w+)
// followed by a set of arguments ([ \t\n0-9eE.,\-%]+)
const partRegex = /\s*(\w+)\s*\(([^)]*)\)/ig;
let match;
let matrix = null;
while ((match = partRegex.exec(cssString)) !== null) {
const action = match[1].toLowerCase();
if (!(action in keywordToAction)) {
throw new Error(`Unsupported CSS transform action: ${action}`);
}
const args = parseArguments(match[2]);
const currentMatrix = keywordToAction[action](args);
if (!matrix) {
matrix = currentMatrix;
}
else {
matrix = matrix.rightMul(currentMatrix);
}
}
const matrixData = match.slice(1).map(entry => parseFloat(entry));
const a = matrixData[0];
const b = matrixData[1];
const c = matrixData[2];
const d = matrixData[3];
const e = matrixData[4];
const f = matrixData[5];
const transform = new Mat33(a, c, e, b, d, f, 0, 0, 1);
return transform;
return matrix ?? Mat33.identity;
}

@@ -347,0 +555,0 @@ }

@@ -39,2 +39,9 @@ /**

/**
* Returns the entry of this with the greatest magnitude.
*
* In other words, returns $\max \{ |x| : x \in {\bf v} \}$, where ${\bf v}$ is the set of
* all entries of this vector.
*/
maximumEntryMagnitude(): number;
/**
* Return this' angle in the XY plane (treats this as a Vec2).

@@ -41,0 +48,0 @@ *

@@ -62,2 +62,11 @@ "use strict";

/**
* Returns the entry of this with the greatest magnitude.
*
* In other words, returns $\max \{ |x| : x \in {\bf v} \}$, where ${\bf v}$ is the set of
* all entries of this vector.
*/
maximumEntryMagnitude() {
return Math.max(Math.abs(this.x), Math.max(Math.abs(this.y), Math.abs(this.z)));
}
/**
* Return this' angle in the XY plane (treats this as a Vec2).

@@ -64,0 +73,0 @@ *

@@ -110,5 +110,18 @@ import { Point2, Vec2 } from './Vec2';

getScaleFactor(): number;
/** Returns the `idx`-th column (`idx` is 0-indexed). */
getColumn(idx: number): Vec3;
/** Returns the magnitude of the entry with the largest entry */
maximumEntryMagnitude(): number;
/**
* Constructs a 3x3 translation matrix (for translating `Vec2`s) using
* **transformVec2**.
*
* Creates a matrix in the form
* $$
* \begin{pmatrix}
* 1 & 0 & {\tt amount.x}\\
* 0 & 1 & {\tt amount.y}\\
* 0 & 0 & 1
* \end{pmatrix}
* $$
*/

@@ -118,5 +131,22 @@ static translation(amount: Vec2): Mat33;

static scaling2D(amount: number | Vec2, center?: Point2): Mat33;
/** @see {@link fromCSSMatrix} */
/**
* **Note**: Assumes `this.c1 = this.c2 = 0` and `this.c3 = 1`.
*
* @see {@link fromCSSMatrix} and {@link toSafeCSSTransformList}
*/
toCSSMatrix(): string;
/**
* @beta May change or even be removed between minor releases.
*
* Converts this matrix into a list of CSS transforms that attempt to preserve
* this matrix's translation.
*
* In Chrome/Firefox, translation attributes only support 6 digits (likely an artifact
* of using lower-precision floating point numbers). This works around
* that by expanding this matrix into the product of several CSS transforms.
*
* **Note**: Assumes `this.c1 = this.c2 = 0` and `this.c3 = 1`.
*/
toSafeCSSTransformList(): string;
/**
* Converts a CSS-form `matrix(a, b, c, d, e, f)` to a Mat33.

@@ -123,0 +153,0 @@ *

@@ -39,2 +39,9 @@ /**

/**
* Returns the entry of this with the greatest magnitude.
*
* In other words, returns $\max \{ |x| : x \in {\bf v} \}$, where ${\bf v}$ is the set of
* all entries of this vector.
*/
maximumEntryMagnitude(): number;
/**
* Return this' angle in the XY plane (treats this as a Vec2).

@@ -41,0 +48,0 @@ *

6

package.json
{
"name": "@js-draw/math",
"version": "1.3.0",
"version": "1.3.1",
"description": "A math library for js-draw. ",

@@ -25,3 +25,3 @@ "types": "./dist/mjs/lib.d.ts",

"build": "rm -rf ./dist && mkdir dist && build-tool build",
"watch": "rm -rf ./dist && mkdir dist && build-tool watch"
"watch": "rm -rf ./dist/* && mkdir -p dist && build-tool watch"
},

@@ -49,3 +49,3 @@ "dependencies": {

],
"gitHead": "46b3d8f819f8e083f6e3e1d01e027e4311355456"
"gitHead": "65af7ec944f70b69b2a4b07d98e5bb92eeeca029"
}

@@ -201,45 +201,9 @@ import Mat33 from './Mat33';

it('should convert CSS matrix(...) strings to matricies', () => {
// From MDN:
// ⎡ a c e ⎤
// ⎢ b d f ⎥ = matrix(a,b,c,d,e,f)
// ⎣ 0 0 1 ⎦
const identity = Mat33.fromCSSMatrix('matrix(1, 0, 0, 1, 0, 0)');
expect(identity).objEq(Mat33.identity);
expect(Mat33.fromCSSMatrix('matrix(1, 2, 3, 4, 5, 6)')).objEq(new Mat33(
1, 3, 5,
2, 4, 6,
0, 0, 1,
));
expect(Mat33.fromCSSMatrix('matrix(1e2, 2, 3, 4, 5, 6)')).objEq(new Mat33(
1e2, 3, 5,
2, 4, 6,
0, 0, 1,
));
expect(Mat33.fromCSSMatrix('matrix(1.6, 2, .3, 4, 5, 6)')).objEq(new Mat33(
1.6, .3, 5,
2, 4, 6,
0, 0, 1,
));
expect(Mat33.fromCSSMatrix('matrix(-1, 2, 3.E-2, 4, -5.123, -6.5)')).objEq(new Mat33(
-1, 0.03, -5.123,
2, 4, -6.5,
0, 0, 1,
));
expect(Mat33.fromCSSMatrix('matrix(1.6,\n\t2, .3, 4, 5, 6)')).objEq(new Mat33(
1.6, .3, 5,
2, 4, 6,
0, 0, 1,
));
expect(Mat33.fromCSSMatrix('matrix(1.6,2, .3E-2, 4, 5, 6)')).objEq(new Mat33(
1.6, 3e-3, 5,
2, 4, 6,
0, 0, 1,
));
expect(Mat33.fromCSSMatrix('matrix(-1, 2e6, 3E-2,-5.123, -6.5e-1, 0.01)')).objEq(new Mat33(
-1, 3E-2, -6.5e-1,
2e6, -5.123, 0.01,
0, 0, 1,
));
it('getColumn should return the given column index', () => {
expect(Mat33.identity.getColumn(0)).objEq(Vec3.unitX);
expect(Mat33.identity.getColumn(1)).objEq(Vec3.of(0, 1, 0));
// scaling2D only scales the x/y components of vectors it transforms
expect(Mat33.scaling2D(2).getColumn(2)).objEq(Vec3.of(0, 0, 1));
});
});

@@ -338,5 +338,33 @@ import { Point2, Vec2 } from './Vec2';

/** Returns the `idx`-th column (`idx` is 0-indexed). */
public getColumn(idx: number) {
return Vec3.of(
this.rows[0].at(idx),
this.rows[1].at(idx),
this.rows[2].at(idx),
);
}
/** Returns the magnitude of the entry with the largest entry */
public maximumEntryMagnitude() {
let greatestSoFar = Math.abs(this.a1);
for (const entry of this.toArray()) {
greatestSoFar = Math.max(greatestSoFar, Math.abs(entry));
}
return greatestSoFar;
}
/**
* Constructs a 3x3 translation matrix (for translating `Vec2`s) using
* **transformVec2**.
*
* Creates a matrix in the form
* $$
* \begin{pmatrix}
* 1 & 0 & {\tt amount.x}\\
* 0 & 1 & {\tt amount.y}\\
* 0 & 0 & 1
* \end{pmatrix}
* $$
*/

@@ -396,3 +424,7 @@ public static translation(amount: Vec2): Mat33 {

/** @see {@link fromCSSMatrix} */
/**
* **Note**: Assumes `this.c1 = this.c2 = 0` and `this.c3 = 1`.
*
* @see {@link fromCSSMatrix} and {@link toSafeCSSTransformList}
*/
public toCSSMatrix(): string {

@@ -417,37 +449,116 @@ return `matrix(${this.a1},${this.b1},${this.a2},${this.b2},${this.a3},${this.b3})`;

const numberExp = '([-]?\\d*(?:\\.\\d*)?(?:[eE][-]?\\d+)?)';
const numberSepExp = '[, \\t\\n]';
const regExpSource = `^\\s*matrix\\s*\\(${
[
// According to MDN, matrix(a,b,c,d,e,f) has form:
// ⎡ a c e ⎤
// ⎢ b d f ⎥
// ⎣ 0 0 1 ⎦
numberExp, numberExp, numberExp, // a, c, e
numberExp, numberExp, numberExp, // b, d, f
].join(`${numberSepExp}+`)
}${numberSepExp}*\\)\\s*$`;
const matrixExp = new RegExp(regExpSource, 'i');
const match = matrixExp.exec(cssString);
const parseArguments = (argumentString: string) => {
return argumentString.split(/[, \t\n]+/g).map(argString => {
let isPercentage = false;
if (argString.endsWith('%')) {
isPercentage = true;
argString = argString.substring(0, argString.length - 1);
}
if (!match) {
throw new Error(`Unsupported transformation: ${cssString}`);
// Remove trailing px units.
argString = argString.replace(/px$/ig, '');
const numberExp = /^[-]?\d*(?:\.\d*)?(?:[eE][-+]?\d+)?$/i;
if (!numberExp.exec(argString)) {
throw new Error(
`All arguments to transform functions must be numeric (state: ${
JSON.stringify({
currentArgument: argString,
allArguments: argumentString,
})
})`
);
}
let argNumber = parseFloat(argString);
if (isPercentage) {
argNumber /= 100;
}
return argNumber;
});
};
const keywordToAction = {
matrix: (matrixData: number[]) => {
if (matrixData.length !== 6) {
throw new Error(`Invalid matrix argument: ${matrixData}. Must have length 6`);
}
const a = matrixData[0];
const b = matrixData[1];
const c = matrixData[2];
const d = matrixData[3];
const e = matrixData[4];
const f = matrixData[5];
const transform = new Mat33(
a, c, e,
b, d, f,
0, 0, 1
);
return transform;
},
scale: (scaleArgs: number[]) => {
let scaleX, scaleY;
if (scaleArgs.length === 1) {
scaleX = scaleArgs[0];
scaleY = scaleArgs[0];
} else if (scaleArgs.length === 2) {
scaleX = scaleArgs[0];
scaleY = scaleArgs[1];
} else {
throw new Error(`The scale() function only supports two arguments. Given: ${scaleArgs}`);
}
return Mat33.scaling2D(Vec2.of(scaleX, scaleY));
},
translate: (translateArgs: number[]) => {
let translateX = 0;
let translateY = 0;
if (translateArgs.length === 1) {
// If no y translation is given, assume 0.
translateX = translateArgs[0];
} else if (translateArgs.length === 2) {
translateX = translateArgs[0];
translateY = translateArgs[1];
} else {
throw new Error(`The translate() function requires either 1 or 2 arguments. Given ${translateArgs}`);
}
return Mat33.translation(Vec2.of(translateX, translateY));
},
};
// A command (\w+)
// followed by a set of arguments ([ \t\n0-9eE.,\-%]+)
const partRegex = /\s*(\w+)\s*\(([^)]*)\)/ig;
let match;
let matrix: Mat33|null = null;
while ((match = partRegex.exec(cssString)) !== null) {
const action = match[1].toLowerCase();
if (!(action in keywordToAction)) {
throw new Error(`Unsupported CSS transform action: ${action}`);
}
const args = parseArguments(match[2]);
const currentMatrix = keywordToAction[action as keyof typeof keywordToAction](args);
if (!matrix) {
matrix = currentMatrix;
} else {
matrix = matrix.rightMul(currentMatrix);
}
}
const matrixData = match.slice(1).map(entry => parseFloat(entry));
const a = matrixData[0];
const b = matrixData[1];
const c = matrixData[2];
const d = matrixData[3];
const e = matrixData[4];
const f = matrixData[5];
const transform = new Mat33(
a, c, e,
b, d, f,
0, 0, 1
);
return transform;
return matrix ?? Mat33.identity;
}
}
export default Mat33;

@@ -168,1 +168,2 @@ // @packageDocumentation @internal

};

@@ -67,2 +67,12 @@

/**
* Returns the entry of this with the greatest magnitude.
*
* In other words, returns $\max \{ |x| : x \in {\bf v} \}$, where ${\bf v}$ is the set of
* all entries of this vector.
*/
public maximumEntryMagnitude(): number {
return Math.max(Math.abs(this.x), Math.max(Math.abs(this.y), Math.abs(this.z)));
}
/**
* Return this' angle in the XY plane (treats this as a Vec2).

@@ -69,0 +79,0 @@ *

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc