You're Invited:Meet the Socket Team at RSAC and BSidesSF 2026, March 23–26.RSVP
Socket
Book a DemoSign in
Socket

@leafer/math

Package Overview
Dependencies
Maintainers
1
Versions
117
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@leafer/math - npm Package Compare versions

Comparing version
1.0.0-rc.6
to
1.0.0-rc.7
+28
src/AroundHelper.ts
import { IAround, IPointData, IBoundsData } from '@leafer/interface'
const center: IPointData = { x: 0.5, y: 0.5 }
export const AroundHelper = {
center,
tempPoint: {} as IPointData,
toPoint(around: IAround, bounds: IBoundsData, to?: IPointData, onlySize?: boolean) {
to || (to = {} as IPointData)
switch (around) {
case 'center':
around = center
break
}
to.x = around.x * bounds.width
to.y = around.y * bounds.height
if (!onlySize) {
to.x += bounds.x
to.y += bounds.y
}
}
}
+2
-2
{
"name": "@leafer/math",
"version": "1.0.0-rc.6",
"version": "1.0.0-rc.7",
"description": "@leafer/math",

@@ -25,4 +25,4 @@ "author": "Chao (Leafer) Wan",

"devDependencies": {
"@leafer/interface": "1.0.0-rc.6"
"@leafer/interface": "1.0.0-rc.7"
}
}

@@ -1,2 +0,2 @@

import { IBounds, IBoundsData, IMatrixData, IPointData, IBoundsDataHandle, IObject, IMatrix, IRadiusPointData, IMatrixWithLayoutData } from '@leafer/interface'
import { IBounds, IBoundsData, IMatrixData, IPointData, IBoundsDataFn, IObject, IMatrix, IRadiusPointData, IMatrixWithLayoutData } from '@leafer/interface'
import { BoundsHelper as B } from './BoundsHelper'

@@ -12,13 +12,19 @@

public get minX(): number { return B.minX(this) }
public get minY(): number { return B.minY(this) }
public get maxX(): number { return B.maxX(this) }
public get maxY(): number { return B.maxY(this) }
constructor(x?: number | IBoundsData, y?: number, width?: number, height?: number) {
typeof x === 'object' ? B.copy(this, x) : B.set(this, x, y, width, height)
this.set(x, y, width, height)
}
public set(x?: number, y?: number, width?: number, height?: number): void {
B.set(this, x, y, width, height)
public set(x?: number | IBoundsData, y?: number, width?: number, height?: number): IBounds {
typeof x === 'object' ? B.copy(this, x) : B.set(this, x, y, width, height)
return this
}
public copy(bounds: IBoundsData): IBounds {
B.copy(this, bounds)
return this
public get(): IBoundsData {
const { x, y, width, height } = this
return { x, y, width, height }
}

@@ -72,29 +78,34 @@

public addList(boundsList: IBounds[]): IBounds {
B.setByList(this, boundsList, true)
public addList(boundsList: IBoundsData[]): IBounds {
B.setList(this, boundsList, true)
return this
}
public setByList(boundsList: IBounds[], addMode?: boolean): IBounds {
B.setByList(this, boundsList, addMode)
public setList(boundsList: IBoundsData[]): IBounds {
B.setList(this, boundsList)
return this
}
public addListWithHandle(list: IObject[], boundsDataHandle: IBoundsDataHandle): IBounds {
B.setByListWithHandle(this, list, boundsDataHandle, true)
public addListWithFn(list: IObject[], boundsDataFn: IBoundsDataFn): IBounds {
B.setListWithFn(this, list, boundsDataFn, true)
return this
}
public setByListWithHandle(list: IObject[], boundsDataHandle: IBoundsDataHandle, addMode?: boolean): IBounds {
B.setByListWithHandle(this, list, boundsDataHandle, addMode)
public setListWithFn(list: IObject[], boundsDataFn: IBoundsDataFn): IBounds {
B.setListWithFn(this, list, boundsDataFn)
return this
}
public setByPoints(points: IPointData[]): IBounds {
B.setByPoints(this, points)
public setPoints(points: IPointData[]): IBounds {
B.setPoints(this, points)
return this
}
public getPoints(): IPointData[] {
return B.getPoints(this)
}
public hitPoint(point: IPointData, pointMatrix?: IMatrixData): boolean {

@@ -101,0 +112,0 @@ return B.hitPoint(this, point, pointMatrix)

@@ -1,2 +0,2 @@

import { IPointData, IBoundsData, IMatrixData, IBoundsDataHandle, IObject, IMatrix, IOffsetBoundsData, IRadiusPointData, IMatrixWithLayoutData } from '@leafer/interface'
import { IPointData, IBoundsData, IMatrixData, IBoundsDataFn, IObject, IMatrix, IOffsetBoundsData, IRadiusPointData, IMatrixWithScaleData } from '@leafer/interface'
import { Matrix } from './Matrix'

@@ -38,10 +38,12 @@ import { MatrixHelper as M } from './MatrixHelper'

right(t: IBoundsData): number {
return t.x + t.width
},
bottom(t: IBoundsData): number {
return t.y + t.height
},
minX(t: IBoundsData): number { return t.width > 0 ? t.x : t.x + t.width },
minY(t: IBoundsData): number { return t.height > 0 ? t.y : t.y + t.height },
maxX(t: IBoundsData): number { return t.width > 0 ? t.x + t.width : t.x },
maxY(t: IBoundsData): number { return t.height > 0 ? t.y + t.height : t.y },
move(t: IBoundsData, x: number, y: number): void {

@@ -65,4 +67,4 @@ t.x += x

if (parent) {
to.offsetX = -(B.right(parent) - t.x)
to.offsetY = -(B.bottom(parent) - t.y)
to.offsetX = -(B.maxX(parent) - t.x)
to.offsetY = -(B.maxY(parent) - t.y)
} else {

@@ -75,2 +77,3 @@ to.offsetX = t.x + t.width

scale(t: IBoundsData, scaleX: number, scaleY: number = scaleX): void {

@@ -157,2 +160,3 @@ if (t.x) t.x *= scaleX

getSpread(t: IBoundsData, spreadX: number, spreadY?: number): IBoundsData {

@@ -186,2 +190,3 @@ const n = {} as IBoundsData

add(t: IBoundsData, bounds: IBoundsData): void {

@@ -203,17 +208,17 @@ right = t.x + t.width

addList(t: IBoundsData, list: IBoundsData[]): void {
B.setByListWithHandle(t, list, undefined, true)
B.setListWithFn(t, list, undefined, true)
},
setByList(t: IBoundsData, list: IBoundsData[], addMode = false): void {
B.setByListWithHandle(t, list, undefined, addMode)
setList(t: IBoundsData, list: IBoundsData[], addMode = false): void {
B.setListWithFn(t, list, undefined, addMode)
},
addListWithHandle(t: IBoundsData, list: IObject[], boundsDataHandle: IBoundsDataHandle): void {
B.setByListWithHandle(t, list, boundsDataHandle, true)
addListWithFn(t: IBoundsData, list: IObject[], boundsDataFn: IBoundsDataFn): void {
B.setListWithFn(t, list, boundsDataFn, true)
},
setByListWithHandle(t: IBoundsData, list: IObject[], boundsDataHandle: IBoundsDataHandle, addMode = false): void {
setListWithFn(t: IBoundsData, list: IObject[], boundsDataFn: IBoundsDataFn, addMode = false): void {
let bounds: IBoundsData, first = true
for (let i = 0, len = list.length; i < len; i++) {
bounds = boundsDataHandle ? boundsDataHandle(list[i]) : list[i] as IBoundsData
bounds = boundsDataFn ? boundsDataFn(list[i]) : list[i] as IBoundsData
if (bounds && (bounds.width || bounds.height)) {

@@ -232,10 +237,20 @@ if (first) {

setByPoints(t: IBoundsData, points: IPointData[]): void {
points.forEach((point, index) => {
index === 0 ? setPoint(tempPointBounds, point.x, point.y) : addPoint(tempPointBounds, point.x, point.y)
})
setPoints(t: IBoundsData, points: IPointData[]): void {
points.forEach((point, index) => index === 0 ? setPoint(tempPointBounds, point.x, point.y) : addPoint(tempPointBounds, point.x, point.y))
toBounds(tempPointBounds, t)
},
hitRadiusPoint(t: IBoundsData, point: IRadiusPointData, pointMatrix?: IMatrixWithLayoutData): boolean {
getPoints(t: IBoundsData): IPointData[] {
const { x, y, width, height } = t
return [
{ x, y }, // topLeft
{ x: x + width, y }, // topRight
{ x: x + width, y: y + height }, // bottomRight
{ x, y: y + height } // bottomLeft
]
},
hitRadiusPoint(t: IBoundsData, point: IRadiusPointData, pointMatrix?: IMatrixWithScaleData): boolean {
if (pointMatrix) point = P.tempToInnerRadiusPointOf(point, pointMatrix)

@@ -285,2 +300,3 @@ return (point.x >= t.x - point.radiusX && point.x <= t.x + t.width + point.radiusX) && (point.y >= t.y - point.radiusY && point.y <= t.y + t.height + point.radiusY)

isSame(t: IBoundsData, bounds: IBoundsData): boolean {

@@ -287,0 +303,0 @@ return t.x === bounds.x && t.y === bounds.y && t.width === bounds.width && t.height === bounds.height

@@ -6,6 +6,6 @@ export { IncrementId } from './IncrementId'

export { AutoBounds } from './AutoBounds'
export { TwoPointBounds } from './TwoPointBounds'
export { Matrix } from './Matrix'
export { PointHelper } from './PointHelper'
export { AroundHelper } from './AroundHelper'
export { BoundsHelper } from './BoundsHelper'

@@ -12,0 +12,0 @@ export { TwoPointBoundsHelper } from './TwoPointBoundsHelper'

@@ -0,1 +1,3 @@

const { round, pow, PI } = Math
export const MathHelper = {

@@ -9,16 +11,14 @@

fourNumber(num: number | number[]): number[] {
let one: number, two: number, three: number, four: number // = top right bottom left || topLeft, topRight, bottomRight, bottomLeft
fourNumber(num: number | number[], maxValue?: number): number[] { // top right bottom left || topLeft, topRight, bottomRight, bottomLeft
let data: number[]
if (num instanceof Array) {
switch (num.length) {
case 4:
return num
data = num
break
case 2:
one = three = num[0]
two = four = num[1]
data = [num[0], num[1], num[0], num[1]]
break
case 3:
one = num[0]
two = four = num[1]
three = num[2]
data = [num[0], num[1], num[2], num[1]]
break

@@ -32,3 +32,5 @@ case 1:

}
return one === undefined ? [num as number, num as number, num as number, num as number] : [one, two, three, four]
if (!data) data = [num as number, num as number, num as number, num as number]
if (maxValue) for (let i = 0; i < 4; i++) if (data[i] > maxValue) data[i] = maxValue
return data
},

@@ -47,3 +49,4 @@

getGapRotation(rotation: number, gap: number): number {
getGapRotation(addRotation: number, gap: number, oldRotation: number = 0): number {
let rotation = addRotation + oldRotation
if (gap > 1) {

@@ -53,7 +56,9 @@ const r = Math.abs(rotation % gap)

}
return rotation
return rotation - oldRotation
},
formatSkew(skew: number): number {
return MathHelper.within(skew, -90, 90)
float(num: number, maxLength?: number): number {
const a = maxLength ? pow(10, maxLength) : 1000000000000 // default
num = round(num * a) / a
return num === -0 ? 0 : num
}

@@ -63,4 +68,4 @@

export const OneRadian = Math.PI / 180
export const PI2 = Math.PI * 2
export const PI_2 = Math.PI / 2
export const OneRadian = PI / 180
export const PI2 = PI * 2
export const PI_2 = PI / 2

@@ -1,2 +0,2 @@

import { IMatrix, IMatrixData, IPointData, IMatrixDecompositionData } from '@leafer/interface'
import { IMatrix, IMatrixData, IPointData, ILayoutData } from '@leafer/interface'
import { MatrixHelper as M } from './MatrixHelper'

@@ -15,12 +15,13 @@

constructor(a?: number | IMatrixData, b?: number, c?: number, d?: number, e?: number, f?: number) {
typeof a === 'object' ? M.copy(this, a) : M.set(this, a, b, c, d, e, f)
this.set(a, b, c, d, e, f)
}
public set(a?: number, b?: number, c?: number, d?: number, e?: number, f?: number): void {
M.set(this, a, b, c, d, e, f)
public set(a?: number | IMatrixData, b?: number, c?: number, d?: number, e?: number, f?: number): IMatrix {
typeof a === 'object' ? M.copy(this, a) : M.set(this, a, b, c, d, e, f)
return this
}
public copy(matrix: IMatrixData): IMatrix {
M.copy(this, matrix)
return this
public get(): IMatrixData {
const { a, b, c, d, e, f } = this
return { a, b, c, d, e, f }
}

@@ -89,17 +90,23 @@

public multiply(matrix: IMatrixData): IMatrix {
M.multiply(this, matrix)
public multiply(child: IMatrixData): IMatrix {
M.multiply(this, child)
return this
}
public preMultiply(matrix: IMatrixData): IMatrix {
M.preMultiply(this, matrix)
public multiplyParent(parent: IMatrixData): IMatrix {
M.multiplyParent(this, parent)
return this
}
public divide(matrix: IMatrixData): IMatrix {
M.divide(this, matrix)
public divide(child: IMatrixData): IMatrix {
M.divide(this, child)
return this
}
public divideParent(parent: IMatrixData): IMatrix {
M.divideParent(this, parent)
return this
}
public invert(): IMatrix {

@@ -119,7 +126,13 @@ M.invert(this)

public decompose(): IMatrixDecompositionData {
return M.decompose(this)
public setLayout(data: ILayoutData, origin?: IPointData): IMatrix {
M.setLayout(this, data, origin)
return this
}
public getLayout(origin?: IPointData, firstSkewY?: boolean): ILayoutData {
return M.getLayout(this, origin, firstSkewY)
}
public reset(): void {

@@ -126,0 +139,0 @@ M.reset(this)

@@ -1,6 +0,7 @@

import { IMatrixData, IPointData, IMatrixDecompositionData } from '@leafer/interface'
import { OneRadian } from './MathHelper'
import { IMatrixData, IPointData, ILayoutData, IMatrixWithLayoutData } from '@leafer/interface'
import { MathHelper, OneRadian, PI_2 } from './MathHelper'
const { sin, cos, acos, atan, sqrt, PI } = Math
const { sin, cos, acos, sqrt } = Math
const { float } = MathHelper
const tempPoint = {} as IPointData

@@ -12,2 +13,6 @@

function getWorld(): IMatrixWithLayoutData {
return { ...get(), x: 0, y: 0, width: 0, height: 0, scaleX: 1, scaleY: 1, rotation: 0, skewX: 0, skewY: 0 }
}
export const MatrixHelper = {

@@ -17,2 +22,4 @@

defaultWorld: getWorld(),
tempMatrix: {} as IMatrixData,

@@ -31,2 +38,4 @@

getWorld,
copy(t: IMatrixData, matrix: IMatrixData): void {

@@ -41,3 +50,2 @@ t.a = matrix.a

translate(t: IMatrixData, x: number, y: number): void {

@@ -53,18 +61,17 @@ t.e += x

scale(t: IMatrixData, x: number, y: number = x): void {
t.a *= x
t.b *= x
t.c *= y
t.d *= y
scale(t: IMatrixData, scaleX: number, scaleY: number = scaleX): void {
t.a *= scaleX
t.b *= scaleX
t.c *= scaleY
t.d *= scaleY
},
scaleOfOuter(t: IMatrixData, origin: IPointData, x: number, y: number = x): void {
scaleOfOuter(t: IMatrixData, origin: IPointData, scaleX: number, scaleY?: number): void {
M.toInnerPoint(t, origin, tempPoint)
M.scaleOfInner(t, tempPoint, x, y)
M.scaleOfInner(t, tempPoint, scaleX, scaleY)
},
scaleOfInner(t: IMatrixData, origin: IPointData, x: number, y: number = x): void {
scaleOfInner(t: IMatrixData, origin: IPointData, scaleX: number, scaleY: number = scaleX): void {
M.translateInner(t, origin.x, origin.y)
M.scale(t, x, y)
M.scale(t, scaleX, scaleY)
M.translateInner(t, -origin.x, -origin.y)

@@ -74,22 +81,23 @@ },

rotate(t: IMatrixData, angle: number): void {
angle *= OneRadian
const cosR = cos(angle)
const sinR = sin(angle)
rotate(t: IMatrixData, rotation: number): void {
const { a, b, c, d } = t
const { a, b, c, d } = t
t.a = (a * cosR) - (b * sinR)
t.b = (a * sinR) + (b * cosR)
t.c = (c * cosR) - (d * sinR)
t.d = (c * sinR) + (d * cosR)
rotation *= OneRadian
const cosR = cos(rotation)
const sinR = sin(rotation)
t.a = a * cosR - b * sinR
t.b = a * sinR + b * cosR
t.c = c * cosR - d * sinR
t.d = c * sinR + d * cosR
},
rotateOfOuter(t: IMatrixData, origin: IPointData, angle: number): void {
rotateOfOuter(t: IMatrixData, origin: IPointData, rotation: number): void {
M.toInnerPoint(t, origin, tempPoint)
M.rotateOfInner(t, tempPoint, angle)
M.rotateOfInner(t, tempPoint, rotation)
},
rotateOfInner(t: IMatrixData, origin: IPointData, angle: number): void {
rotateOfInner(t: IMatrixData, origin: IPointData, rotation: number): void {
M.translateInner(t, origin.x, origin.y)
M.rotate(t, angle)
M.rotate(t, rotation)
M.translateInner(t, -origin.x, -origin.y)

@@ -99,24 +107,26 @@ },

skew(t: IMatrixData, x: number, y?: number): void {
skew(t: IMatrixData, skewX: number, skewY?: number): void {
const { a, b, c, d } = t
if (y) {
y *= OneRadian
t.a = a + c * y
t.b = b + d * y
if (skewY) {
skewY *= OneRadian
t.a = a + c * skewY
t.b = b + d * skewY
}
if (x) {
x *= OneRadian
t.c = c + a * x
t.d = d + b * x
if (skewX) {
skewX *= OneRadian
t.c = c + a * skewX
t.d = d + b * skewX
}
},
skewOfOuter(t: IMatrixData, origin: IPointData, x: number, y?: number): void {
skewOfOuter(t: IMatrixData, origin: IPointData, skewX: number, skewY?: number): void {
M.toInnerPoint(t, origin, tempPoint)
M.skewOfInner(t, tempPoint, x, y)
M.skewOfInner(t, tempPoint, skewX, skewY)
},
skewOfInner(t: IMatrixData, origin: IPointData, x: number, y?: number): void {
skewOfInner(t: IMatrixData, origin: IPointData, skewX: number, skewY: number = 0): void {
M.translateInner(t, origin.x, origin.y)
M.skew(t, x, y)
M.skew(t, skewX, skewY)
M.translateInner(t, -origin.x, -origin.y)

@@ -126,36 +136,74 @@ },

multiply(t: IMatrixData, matrix: IMatrixData): void {
multiply(t: IMatrixData, child: IMatrixData): void {
const { a, b, c, d, e, f } = t
t.a = matrix.a * a + matrix.b * c
t.b = matrix.a * b + matrix.b * d
t.c = matrix.c * a + matrix.d * c
t.d = matrix.c * b + matrix.d * d
t.e = matrix.e * a + matrix.f * c + e
t.f = matrix.e * b + matrix.f * d + f
t.a = child.a * a + child.b * c
t.b = child.a * b + child.b * d
t.c = child.c * a + child.d * c
t.d = child.c * b + child.d * d
t.e = child.e * a + child.f * c + e
t.f = child.e * b + child.f * d + f
},
preMultiply(t: IMatrixData, matrix: IMatrixData): void {
const { a, b, c, d, e, f } = t
multiplyParent(t: IMatrixData, parent: IMatrixData, to?: IMatrixData, abcdChanged?: boolean | number, childLayout?: ILayoutData): void { // = transform
const { e, f } = t
if (matrix.a !== 1 || matrix.b !== 0 || matrix.c !== 0 || matrix.d !== 1) {
t.a = (a * matrix.a) + (b * matrix.c)
t.b = (a * matrix.b) + (b * matrix.d)
t.c = (c * matrix.a) + (d * matrix.c)
t.d = (c * matrix.b) + (d * matrix.d)
to || (to = t)
if (abcdChanged === undefined) abcdChanged = t.a !== 1 || t.b || t.c || t.d !== 1
if (abcdChanged) {
const { a, b, c, d } = t
to.a = a * parent.a + b * parent.c
to.b = a * parent.b + b * parent.d
to.c = c * parent.a + d * parent.c
to.d = c * parent.b + d * parent.d
if (childLayout) M.multiplyParentLayout(to as unknown as ILayoutData, parent as unknown as ILayoutData, childLayout)
} else {
to.a = parent.a
to.b = parent.b
to.c = parent.c
to.d = parent.d
if (childLayout) M.multiplyParentLayout(to as unknown as ILayoutData, parent as unknown as ILayoutData)
}
t.e = (e * matrix.a) + (f * matrix.c) + matrix.e
t.f = (e * matrix.b) + (f * matrix.d) + matrix.f
to.e = e * parent.a + f * parent.c + parent.e
to.f = e * parent.b + f * parent.d + parent.f
},
divide(t: IMatrixData, matrix: IMatrixData): void {
M.preMultiply(t, M.tempInvert(matrix))
multiplyParentLayout(t: ILayoutData, parent: ILayoutData, child?: ILayoutData): void {
if (child) {
t.scaleX = parent.scaleX * child.scaleX
t.scaleY = parent.scaleY * child.scaleY
t.rotation = parent.rotation + child.rotation
t.skewX = parent.skewX + child.skewX
t.skewY = parent.skewY + child.skewY
} else {
t.scaleX = parent.scaleX
t.scaleY = parent.scaleY
t.rotation = parent.rotation
t.skewX = parent.skewX
t.skewY = parent.skewY
}
},
divide(t: IMatrixData, child: IMatrixData): void {
M.multiply(t, M.tempInvert(child))
},
divideParent(t: IMatrixData, parent: IMatrixData): void {
M.multiplyParent(t, M.tempInvert(parent))
},
tempInvert(t: IMatrixData): IMatrixData {
const { tempMatrix: temp } = M
M.copy(temp, t)
M.invert(temp)
return temp
const { tempMatrix } = M
M.copy(tempMatrix, t)
M.invert(tempMatrix)
return tempMatrix
},

@@ -165,9 +213,23 @@

const { a, b, c, d, e, f } = t
const s = 1 / (a * d - b * c)
t.a = d * s
t.b = -b * s
t.c = -c * s
t.d = a * s
t.e = -(e * d - f * c) * s
t.f = -(f * a - e * b) * s
if (!b && !c) {
if (a === 1 && d === 1) {
t.e = -e
t.f = -f
} else {
const s = 1 / (a * d)
t.a = d * s
t.d = a * s
t.e = -e * d * s
t.f = -f * a * s
}
} else {
const s = 1 / (a * d - b * c)
t.a = d * s
t.b = -b * s
t.c = -c * s
t.d = a * s
t.e = -(e * d - f * c) * s
t.f = -(f * a - e * b) * s
}
},

@@ -181,4 +243,4 @@

to || (to = inner)
to.x = (x * t.a) + (y * t.c)
to.y = (x * t.b) + (y * t.d)
to.x = x * t.a + y * t.c
to.y = x * t.b + y * t.d

@@ -192,6 +254,7 @@ if (!distance) {

toInnerPoint(t: IMatrixData, outer: IPointData, to?: IPointData, distance?: boolean): void {
const { x, y } = outer
const { a, b, c, d } = t
const s = 1 / (a * d - b * c)
const { x, y } = outer
// inner

@@ -209,33 +272,92 @@ to || (to = outer)

setLayout(t: IMatrixData, layout: ILayoutData, origin?: IPointData, bcChanged?: boolean | number): void {
const { x, y, scaleX, scaleY } = layout
decompose(t: IMatrixData): IMatrixDecompositionData {
const { a, b, c, d } = t
let scaleX = a, scaleY = d, rotation = 0, skewX = 0, skewY = 0
if (bcChanged === undefined) bcChanged = layout.rotation || layout.skewX || layout.skewY
if (bcChanged) {
const { rotation, skewX, skewY } = layout
const r = rotation * OneRadian
const cosR = cos(r)
const sinR = sin(r)
if (skewX || skewY) {
// rotate -> skew -> scale
const sx = skewX * OneRadian
const sy = skewY * OneRadian
t.a = (cosR + sy * -sinR) * scaleX
t.b = (sinR + sy * cosR) * scaleX
t.c = (-sinR + sx * cosR) * scaleY
t.d = (cosR + sx * sinR) * scaleY
} else {
// rotate -> scale
t.a = cosR * scaleX
t.b = sinR * scaleX
t.c = -sinR * scaleY
t.d = cosR * scaleY
}
} else {
t.a = scaleX
t.b = 0
t.c = 0
t.d = scaleY
}
t.e = x
t.f = y
if (origin) M.translateInner(t, -origin.x, -origin.y)
},
getLayout(t: IMatrixData, origin?: IPointData, firstSkewY?: boolean): ILayoutData {
const { a, b, c, d, e, f } = t
let x = e, y = f, scaleX: number, scaleY: number, rotation: number, skewX: number, skewY: number
if (b || c) {
const s = a * d - b * c
const k = a * c + b * d
if (b) {
const ab = a * a + b * b
scaleX = sqrt(ab)
if (c && !firstSkewY) {
scaleX = sqrt(a * a + b * b)
scaleY = s / scaleX
const r = a / scaleX
rotation = b > 0 ? acos(r) : -acos(r)
skewX = atan(k / ab) / OneRadian
const cosR = a / scaleX
rotation = b > 0 ? acos(cosR) : -acos(cosR)
} else {
const cd = c * c + d * d
scaleY = sqrt(cd)
scaleY = sqrt(c * c + d * d)
scaleX = s / scaleY
const r = c / scaleY
rotation = PI / 2 - (d > 0 ? acos(-r) : -acos(r))
skewY = atan(k / cd) / OneRadian
const cosR = c / scaleY
rotation = PI_2 - (d > 0 ? acos(-cosR) : -acos(cosR))
}
rotation /= OneRadian
const cosR = cos(rotation)
const sinR = sin(rotation)
scaleX = float(scaleX), scaleY = float(scaleY)
skewX = float((c / scaleY + sinR) / cosR / OneRadian)
skewY = float((b / scaleX - sinR) / cosR / OneRadian)
rotation = float(rotation / OneRadian)
} else {
scaleX = a
scaleY = d
rotation = skewX = skewY = 0
}
return { x: t.e, y: t.f, scaleX, scaleY, rotation, skewX, skewY }
if (origin) {
x += origin.x * a + origin.y * c
y += origin.x * b + origin.y * d
}
return { x, y, scaleX, scaleY, rotation, skewX, skewY }
},

@@ -242,0 +364,0 @@

@@ -10,14 +10,16 @@ import { IPoint, IPointData, IMatrixData } from '@leafer/interface'

constructor(x?: number | IPointData, y?: number) {
typeof x === 'object' ? P.copy(this, x) : P.set(this, x, y)
this.set(x, y)
}
public set(x?: number, y?: number): void {
P.set(this, x, y)
public set(x?: number | IPointData, y?: number): IPoint {
typeof x === 'object' ? P.copy(this, x) : P.set(this, x, y)
return this
}
public copy(point: IPointData): IPoint {
P.copy(this, point)
return this
public get(): IPointData {
const { x, y } = this
return { x, y }
}
public clone(): IPoint {

@@ -27,8 +29,18 @@ return new Point(this)

public rotate(angle: number, center?: IPointData): IPoint {
P.rotate(this, angle, center)
public rotate(rotation: number, origin?: IPointData): IPoint {
P.rotate(this, rotation, origin)
return this
}
public rotateOf(origin: IPointData, rotation: number): IPoint {
P.rotate(this, rotation, origin)
return this
}
public getRotation(origin: IPointData, to: IPointData, toOrigin?: IPointData): number {
return P.getRotation(this, origin, to, toOrigin)
}
public toInnerOf(matrix: IMatrixData, to?: IPointData): IPoint {

@@ -44,4 +56,5 @@ P.toInnerOf(this, matrix, to)

public getCenter(to: IPointData): IPointData {
return P.getCenter(this, to)
public getCenter(to: IPointData): IPoint {
return new Point(P.getCenter(this, to))
}

@@ -53,2 +66,6 @@

public getDistancePoint(to: IPointData, distance: number): IPoint {
return new Point(P.getDistancePoint(this, to, distance))
}
public getAngle(to: IPointData): number {

@@ -62,6 +79,8 @@ return P.getAngle(this, to)

public reset(): void {
public reset(): IPoint {
P.reset(this)
return this
}
}

@@ -1,8 +0,9 @@

import { IPointData, IMatrixData, IRadiusPointData, IMatrixWithLayoutData } from '@leafer/interface'
import { OneRadian } from './MathHelper'
import { IPointData, IMatrixData, IRadiusPointData, IMatrixWithScaleData } from '@leafer/interface'
import { OneRadian, PI2 } from './MathHelper'
import { MatrixHelper as M } from './MatrixHelper'
const { toInnerPoint, toOuterPoint } = M
const { sin, cos, abs, sqrt, atan2 } = Math
const { sin, cos, abs, sqrt, atan2, min, PI } = Math

@@ -37,10 +38,11 @@

rotate(t: IPointData, rotation: number, center?: IPointData): void {
if (!center) center = P.defaultPoint
const cosR = cos(rotation * OneRadian)
const sinR = sin(rotation * OneRadian)
const rx = t.x - center.x
const ry = t.y - center.y
t.x = center.x + rx * cosR - ry * sinR
t.y = center.y + rx * sinR + ry * cosR
rotate(t: IPointData, rotation: number, origin?: IPointData): void {
if (!origin) origin = P.defaultPoint
rotation *= OneRadian
const cosR = cos(rotation)
const sinR = sin(rotation)
const rx = t.x - origin.x
const ry = t.y - origin.y
t.x = origin.x + rx * cosR - ry * sinR
t.y = origin.y + rx * sinR + ry * cosR
},

@@ -63,3 +65,3 @@

tempToInnerRadiusPointOf(t: IRadiusPointData, matrix: IMatrixWithLayoutData): IRadiusPointData {
tempToInnerRadiusPointOf(t: IRadiusPointData, matrix: IMatrixWithScaleData): IRadiusPointData {
const { tempRadiusPoint: temp } = P

@@ -71,3 +73,3 @@ P.copy(temp, t)

toInnerRadiusPointOf(t: IRadiusPointData, matrix: IMatrixWithLayoutData, to?: IRadiusPointData): void {
toInnerRadiusPointOf(t: IRadiusPointData, matrix: IMatrixWithScaleData, to?: IRadiusPointData): void {
to || (to = t)

@@ -93,8 +95,24 @@ toInnerPoint(matrix, t, to)

getCenterX(x1: number, x2: number): number {
return x1 + (x2 - x1) / 2
},
getCenterY(y1: number, y2: number): number {
return y1 + (y2 - y1) / 2
},
getDistance(t: IPointData, point: IPointData): number {
const x = abs(point.x - t.x)
const y = abs(point.y - t.y)
return P.getDistanceFrom(t.x, t.y, point.x, point.y)
},
getDistanceFrom(x1: number, y1: number, x2: number, y2: number): number {
const x = abs(x2 - x1)
const y = abs(y2 - y1)
return sqrt(x * x + y * y)
},
getMinDistanceFrom(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number): number {
return min(P.getDistanceFrom(x1, y1, x2, y2), P.getDistanceFrom(x2, y2, x3, y3))
},
getAngle(t: IPointData, to: IPointData): number {

@@ -104,10 +122,13 @@ return P.getAtan2(t, to) / OneRadian

getChangeAngle(t: IPointData, orign: IPointData, to: IPointData, toOrigin?: IPointData): number {
if (!toOrigin) toOrigin = orign
getRotation(t: IPointData, origin: IPointData, to: IPointData, toOrigin?: IPointData): number {
if (!toOrigin) toOrigin = origin
return P.getRadianFrom(t.x, t.y, origin.x, origin.y, to.x, to.y, toOrigin.x, toOrigin.y) / OneRadian
},
let fromAngle = P.getAngle(t, orign)
let toAngle = P.getAngle(to, toOrigin)
const angle = toAngle - fromAngle
return angle < -180 ? angle + 360 : angle
getRadianFrom(fromX: number, fromY: number, originX: number, originY: number, toX: number, toY: number, toOriginX?: number, toOriginY?: number): number {
if (toOriginX === undefined) toOriginX = originX, toOriginY = originY
let fromAngle = atan2(fromY - originY, fromX - originX)
let toAngle = atan2(toY - toOriginY, toX - toOriginX)
const radian = toAngle - fromAngle
return radian < -PI ? radian + PI2 : radian
},

@@ -114,0 +135,0 @@

@@ -31,3 +31,3 @@ import { ITwoPointBoundsData, IBoundsData } from '@leafer/interface'

add(t: ITwoPointBoundsData, pb: ITwoPointBoundsData): void {
addPointBounds(t: ITwoPointBoundsData, pb: ITwoPointBoundsData): void {
t.minX = pb.minX < t.minX ? pb.minX : t.minX

@@ -34,0 +34,0 @@ t.minY = pb.minY < t.minY ? pb.minY : t.minY

@@ -1,2 +0,2 @@

import { INumberMap, IPoint, IPointData, IMatrixData, IBounds, IBoundsData, IMatrix, IObject, IBoundsDataHandle, IRadiusPointData, IMatrixWithLayoutData, IAutoBounds, IAutoBoundsData, ISizeData, ITwoPointBounds, ITwoPointBoundsData, IMatrixDecompositionData, IOffsetBoundsData } from '@leafer/interface';
import { INumberMap, IPoint, IPointData, IMatrixData, IBounds, IBoundsData, IMatrix, IObject, IBoundsDataFn, IRadiusPointData, IMatrixWithLayoutData, IAutoBounds, IAutoBoundsData, ISizeData, ILayoutData, IMatrixWithScaleData, IAround, IOffsetBoundsData, ITwoPointBoundsData } from '@leafer/interface';

@@ -17,13 +17,16 @@ declare const IncrementId: {

constructor(x?: number | IPointData, y?: number);
set(x?: number, y?: number): void;
copy(point: IPointData): IPoint;
set(x?: number | IPointData, y?: number): IPoint;
get(): IPointData;
clone(): IPoint;
rotate(angle: number, center?: IPointData): IPoint;
rotate(rotation: number, origin?: IPointData): IPoint;
rotateOf(origin: IPointData, rotation: number): IPoint;
getRotation(origin: IPointData, to: IPointData, toOrigin?: IPointData): number;
toInnerOf(matrix: IMatrixData, to?: IPointData): IPoint;
toOuterOf(matrix: IMatrixData, to?: IPointData): IPoint;
getCenter(to: IPointData): IPointData;
getCenter(to: IPointData): IPoint;
getDistance(to: IPointData): number;
getDistancePoint(to: IPointData, distance: number): IPoint;
getAngle(to: IPointData): number;
getAtan2(to: IPointData): number;
reset(): void;
reset(): IPoint;
}

@@ -36,5 +39,9 @@

height: number;
get minX(): number;
get minY(): number;
get maxX(): number;
get maxY(): number;
constructor(x?: number | IBoundsData, y?: number, width?: number, height?: number);
set(x?: number, y?: number, width?: number, height?: number): void;
copy(bounds: IBoundsData): IBounds;
set(x?: number | IBoundsData, y?: number, width?: number, height?: number): IBounds;
get(): IBoundsData;
clone(): IBounds;

@@ -49,7 +56,8 @@ scale(scaleX: number, scaleY?: number): IBounds;

add(bounds: IBoundsData): IBounds;
addList(boundsList: IBounds[]): IBounds;
setByList(boundsList: IBounds[], addMode?: boolean): IBounds;
addListWithHandle(list: IObject[], boundsDataHandle: IBoundsDataHandle): IBounds;
setByListWithHandle(list: IObject[], boundsDataHandle: IBoundsDataHandle, addMode?: boolean): IBounds;
setByPoints(points: IPointData[]): IBounds;
addList(boundsList: IBoundsData[]): IBounds;
setList(boundsList: IBoundsData[]): IBounds;
addListWithFn(list: IObject[], boundsDataFn: IBoundsDataFn): IBounds;
setListWithFn(list: IObject[], boundsDataFn: IBoundsDataFn): IBounds;
setPoints(points: IPointData[]): IBounds;
getPoints(): IPointData[];
hitPoint(point: IPointData, pointMatrix?: IMatrixData): boolean;

@@ -79,13 +87,2 @@ hitRadiusPoint(point: IRadiusPointData, pointMatrix?: IMatrixWithLayoutData): boolean;

declare class TwoPointBounds implements ITwoPointBounds {
minX: number;
minY: number;
maxX: number;
maxY: number;
constructor(x: number, y: number);
addPoint(x: number, y: number): void;
addBounds(x: number, y: number, width: number, height: number): void;
add(pb: ITwoPointBoundsData): void;
}
declare class Matrix implements IMatrix {

@@ -99,4 +96,4 @@ a: number;

constructor(a?: number | IMatrixData, b?: number, c?: number, d?: number, e?: number, f?: number);
set(a?: number, b?: number, c?: number, d?: number, e?: number, f?: number): void;
copy(matrix: IMatrixData): IMatrix;
set(a?: number | IMatrixData, b?: number, c?: number, d?: number, e?: number, f?: number): IMatrix;
get(): IMatrixData;
clone(): IMatrix;

@@ -114,9 +111,11 @@ translate(x: number, y: number): IMatrix;

skewOfInner(origin: IPointData, x: number, y?: number): IMatrix;
multiply(matrix: IMatrixData): IMatrix;
preMultiply(matrix: IMatrixData): IMatrix;
divide(matrix: IMatrixData): IMatrix;
multiply(child: IMatrixData): IMatrix;
multiplyParent(parent: IMatrixData): IMatrix;
divide(child: IMatrixData): IMatrix;
divideParent(parent: IMatrixData): IMatrix;
invert(): IMatrix;
toOuterPoint(inner: IPointData, to?: IPointData, distance?: boolean): void;
toInnerPoint(outer: IPointData, to?: IPointData, distance?: boolean): void;
decompose(): IMatrixDecompositionData;
setLayout(data: ILayoutData, origin?: IPointData): IMatrix;
getLayout(origin?: IPointData, firstSkewY?: boolean): ILayoutData;
reset(): void;

@@ -133,13 +132,18 @@ }

move(t: IPointData, x: number, y: number): void;
rotate(t: IPointData, rotation: number, center?: IPointData): void;
rotate(t: IPointData, rotation: number, origin?: IPointData): void;
tempToInnerOf(t: IPointData, matrix: IMatrixData): IPointData;
tempToOuterOf(t: IPointData, matrix: IMatrixData): IPointData;
tempToInnerRadiusPointOf(t: IRadiusPointData, matrix: IMatrixWithLayoutData): IRadiusPointData;
toInnerRadiusPointOf(t: IRadiusPointData, matrix: IMatrixWithLayoutData, to?: IRadiusPointData): void;
tempToInnerRadiusPointOf(t: IRadiusPointData, matrix: IMatrixWithScaleData): IRadiusPointData;
toInnerRadiusPointOf(t: IRadiusPointData, matrix: IMatrixWithScaleData, to?: IRadiusPointData): void;
toInnerOf(t: IPointData, matrix: IMatrixData, to?: IPointData): void;
toOuterOf(t: IPointData, matrix: IMatrixData, to?: IPointData): void;
getCenter(t: IPointData, to: IPointData): IPointData;
getCenterX(x1: number, x2: number): number;
getCenterY(y1: number, y2: number): number;
getDistance(t: IPointData, point: IPointData): number;
getDistanceFrom(x1: number, y1: number, x2: number, y2: number): number;
getMinDistanceFrom(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number): number;
getAngle(t: IPointData, to: IPointData): number;
getChangeAngle(t: IPointData, orign: IPointData, to: IPointData, toOrigin?: IPointData): number;
getRotation(t: IPointData, origin: IPointData, to: IPointData, toOrigin?: IPointData): number;
getRadianFrom(fromX: number, fromY: number, originX: number, originY: number, toX: number, toY: number, toOriginX?: number, toOriginY?: number): number;
getAtan2(t: IPointData, to: IPointData): number;

@@ -150,2 +154,8 @@ getDistancePoint(t: IPointData, to: IPointData, distance: number): IPointData;

declare const AroundHelper: {
center: IPointData;
tempPoint: IPointData;
toPoint(around: IAround, bounds: IBoundsData, to?: IPointData, onlySize?: boolean): void;
};
declare const BoundsHelper: {

@@ -156,4 +166,6 @@ tempBounds: IBoundsData;

copyAndSpread(t: IBoundsData, bounds: IBoundsData, spreadX: number, spreadY?: number): void;
right(t: IBoundsData): number;
bottom(t: IBoundsData): number;
minX(t: IBoundsData): number;
minY(t: IBoundsData): number;
maxX(t: IBoundsData): number;
maxY(t: IBoundsData): number;
move(t: IBoundsData, x: number, y: number): void;

@@ -174,7 +186,8 @@ getByMove(t: IBoundsData, x: number, y: number): IBoundsData;

addList(t: IBoundsData, list: IBoundsData[]): void;
setByList(t: IBoundsData, list: IBoundsData[], addMode?: boolean): void;
addListWithHandle(t: IBoundsData, list: IObject[], boundsDataHandle: IBoundsDataHandle): void;
setByListWithHandle(t: IBoundsData, list: IObject[], boundsDataHandle: IBoundsDataHandle, addMode?: boolean): void;
setByPoints(t: IBoundsData, points: IPointData[]): void;
hitRadiusPoint(t: IBoundsData, point: IRadiusPointData, pointMatrix?: IMatrixWithLayoutData): boolean;
setList(t: IBoundsData, list: IBoundsData[], addMode?: boolean): void;
addListWithFn(t: IBoundsData, list: IObject[], boundsDataFn: IBoundsDataFn): void;
setListWithFn(t: IBoundsData, list: IObject[], boundsDataFn: IBoundsDataFn, addMode?: boolean): void;
setPoints(t: IBoundsData, points: IPointData[]): void;
getPoints(t: IBoundsData): IPointData[];
hitRadiusPoint(t: IBoundsData, point: IRadiusPointData, pointMatrix?: IMatrixWithScaleData): boolean;
hitPoint(t: IBoundsData, point: IPointData, pointMatrix?: IMatrixData): boolean;

@@ -196,3 +209,3 @@ hit(t: IBoundsData, other: IBoundsData, otherMatrix?: IMatrixData): boolean;

copy(t: ITwoPointBoundsData, pb: ITwoPointBoundsData): void;
add(t: ITwoPointBoundsData, pb: ITwoPointBoundsData): void;
addPointBounds(t: ITwoPointBoundsData, pb: ITwoPointBoundsData): void;
toBounds(t: ITwoPointBoundsData, setBounds: IBoundsData): void;

@@ -202,22 +215,27 @@ };

declare function get(): IMatrixData;
declare function getWorld(): IMatrixWithLayoutData;
declare const MatrixHelper: {
defaultMatrix: IMatrixData;
defaultWorld: IMatrixWithLayoutData;
tempMatrix: IMatrixData;
set(t: IMatrixData, a?: number, b?: number, c?: number, d?: number, e?: number, f?: number): void;
get: typeof get;
getWorld: typeof getWorld;
copy(t: IMatrixData, matrix: IMatrixData): void;
translate(t: IMatrixData, x: number, y: number): void;
translateInner(t: IMatrixData, x: number, y: number): void;
scale(t: IMatrixData, x: number, y?: number): void;
scaleOfOuter(t: IMatrixData, origin: IPointData, x: number, y?: number): void;
scaleOfInner(t: IMatrixData, origin: IPointData, x: number, y?: number): void;
rotate(t: IMatrixData, angle: number): void;
rotateOfOuter(t: IMatrixData, origin: IPointData, angle: number): void;
rotateOfInner(t: IMatrixData, origin: IPointData, angle: number): void;
skew(t: IMatrixData, x: number, y?: number): void;
skewOfOuter(t: IMatrixData, origin: IPointData, x: number, y?: number): void;
skewOfInner(t: IMatrixData, origin: IPointData, x: number, y?: number): void;
multiply(t: IMatrixData, matrix: IMatrixData): void;
preMultiply(t: IMatrixData, matrix: IMatrixData): void;
divide(t: IMatrixData, matrix: IMatrixData): void;
scale(t: IMatrixData, scaleX: number, scaleY?: number): void;
scaleOfOuter(t: IMatrixData, origin: IPointData, scaleX: number, scaleY?: number): void;
scaleOfInner(t: IMatrixData, origin: IPointData, scaleX: number, scaleY?: number): void;
rotate(t: IMatrixData, rotation: number): void;
rotateOfOuter(t: IMatrixData, origin: IPointData, rotation: number): void;
rotateOfInner(t: IMatrixData, origin: IPointData, rotation: number): void;
skew(t: IMatrixData, skewX: number, skewY?: number): void;
skewOfOuter(t: IMatrixData, origin: IPointData, skewX: number, skewY?: number): void;
skewOfInner(t: IMatrixData, origin: IPointData, skewX: number, skewY?: number): void;
multiply(t: IMatrixData, child: IMatrixData): void;
multiplyParent(t: IMatrixData, parent: IMatrixData, to?: IMatrixData, abcdChanged?: boolean | number, childLayout?: ILayoutData): void;
multiplyParentLayout(t: ILayoutData, parent: ILayoutData, child?: ILayoutData): void;
divide(t: IMatrixData, child: IMatrixData): void;
divideParent(t: IMatrixData, parent: IMatrixData): void;
tempInvert(t: IMatrixData): IMatrixData;

@@ -227,3 +245,4 @@ invert(t: IMatrixData): void;

toInnerPoint(t: IMatrixData, outer: IPointData, to?: IPointData, distance?: boolean): void;
decompose(t: IMatrixData): IMatrixDecompositionData;
setLayout(t: IMatrixData, layout: ILayoutData, origin?: IPointData, bcChanged?: boolean | number): void;
getLayout(t: IMatrixData, origin?: IPointData, firstSkewY?: boolean): ILayoutData;
reset(t: IMatrixData): void;

@@ -234,6 +253,6 @@ };

within(value: number, min: number, max: number): number;
fourNumber(num: number | number[]): number[];
fourNumber(num: number | number[], maxValue?: number): number[];
formatRotation(rotation: number, unsign?: boolean): number;
getGapRotation(rotation: number, gap: number): number;
formatSkew(skew: number): number;
getGapRotation(addRotation: number, gap: number, oldRotation?: number): number;
float(num: number, maxLength?: number): number;
};

@@ -246,2 +265,2 @@ declare const OneRadian: number;

export { AutoBounds, Bounds, BoundsHelper, IncrementId, MathHelper, Matrix, MatrixHelper, OneRadian, PI2, PI_2, Point, PointHelper, StringNumberMap, TwoPointBounds, TwoPointBoundsHelper };
export { AroundHelper, AutoBounds, Bounds, BoundsHelper, IncrementId, MathHelper, Matrix, MatrixHelper, OneRadian, PI2, PI_2, Point, PointHelper, StringNumberMap, TwoPointBoundsHelper };
import { ITwoPointBounds, ITwoPointBoundsData } from '@leafer/interface'
import { TwoPointBoundsHelper as P } from './TwoPointBoundsHelper'
export class TwoPointBounds implements ITwoPointBounds {
public minX: number
public minY: number
public maxX: number
public maxY: number
constructor(x: number, y: number) {
P.setPoint(this, x, y)
}
addPoint(x: number, y: number): void {
P.addPoint(this, x, y)
}
addBounds(x: number, y: number, width: number, height: number): void {
P.addBounds(this, x, y, width, height)
}
add(pb: ITwoPointBoundsData): void {
P.add(this, pb)
}
}