• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2022-2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import { Array_from_number, float32, float64 } from "@koalaui/compat"
17
18export function mat33(array?: Float32Array): Matrix33 {
19    return (array == undefined) ? new Matrix33 () : new Matrix33(array)
20}
21
22const tolerance: float32 = (1.0 / (1 << 12))
23
24export class Matrix33 {
25    public readonly array: Float32Array
26    constructor (array: Float32Array = new Float32Array(Array_from_number([
27        1.0, 0.0, 0.0,
28        0.0, 1.0, 0.0,
29        0.0, 0.0, 1.0
30    ]))) {
31        this.array = array.slice()
32    }
33
34    static zero(): Matrix33 {
35        return new Matrix33(new Float32Array(Array_from_number([0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0])))
36    }
37
38    static makeTranslate(dx: float32, dy: float32): Matrix33 {
39        return new Matrix33(new Float32Array(Array_from_number([1.0, 0.0, dx as float64, 0.0, 1.0, dy as float64, 0.0, 0.0, 1.0])))
40    }
41
42    static makeScale(dx: float32, dy: float32 = dx): Matrix33 {
43        return new Matrix33(new Float32Array(Array_from_number([dx as float64, 0.0, 0.0, 0.0, dy as float64, 0.0, 0.0, 0.0, 1.0])))
44    }
45
46    static makeRotate(degrees: float32, pivotX?: float32, pivotY?: float32): Matrix33 {
47        let rads = degrees * Math.PI / 180
48        let cos = Math.cos(rads)
49        let sin = Math.sin(rads)
50        if (Math.abs(sin) <= tolerance) sin = 0.0
51        if (Math.abs(cos) <= tolerance) cos = 0.0
52        if (pivotX !== undefined && pivotY != undefined) {
53            let dx = pivotX - pivotX * cos + pivotY * sin
54            let dy = pivotY - pivotY * cos - pivotX * sin
55            return new Matrix33(new Float32Array(Array_from_number([cos, -sin, dx, sin, cos, dy, 0.0, 0.0, 1.0])))
56        } else {
57            return new Matrix33(new Float32Array(Array_from_number([cos, -sin, 0.0, sin, cos, 0.0, 0.0, 0.0, 1.0])))
58        }
59    }
60
61    static makeSkew(sx: float32, sy: float32): Matrix33 {
62        return new Matrix33(new Float32Array(Array_from_number([1.0, sx, 0.0, sy, 1.0, 0.0, 0.0, 0.0, 1.0])))
63    }
64
65    makeConcat(rhs: Matrix33): Matrix33 {
66        return new Matrix33(new Float32Array(Array_from_number([
67            this.array[0] * rhs.array[0] + this.array[1] * rhs.array[3] + this.array[2] * rhs.array[6],
68            this.array[0] * rhs.array[1] + this.array[1] * rhs.array[4] + this.array[2] * rhs.array[7],
69            this.array[0] * rhs.array[2] + this.array[1] * rhs.array[5] + this.array[2] * rhs.array[8],
70            this.array[3] * rhs.array[0] + this.array[4] * rhs.array[3] + this.array[5] * rhs.array[6],
71            this.array[3] * rhs.array[1] + this.array[4] * rhs.array[4] + this.array[5] * rhs.array[7],
72            this.array[3] * rhs.array[2] + this.array[4] * rhs.array[5] + this.array[5] * rhs.array[8],
73            this.array[6] * rhs.array[0] + this.array[7] * rhs.array[3] + this.array[8] * rhs.array[6],
74            this.array[6] * rhs.array[1] + this.array[7] * rhs.array[4] + this.array[8] * rhs.array[7],
75            this.array[6] * rhs.array[2] + this.array[7] * rhs.array[5] + this.array[8] * rhs.array[8],
76        ])))
77    }
78
79    makeTranspose(): Matrix33{
80        return new Matrix33(new Float32Array(Array_from_number([
81            this.array[0], this.array[3], this.array[6],
82            this.array[1], this.array[4], this.array[7],
83            this.array[2], this.array[5], this.array[8]
84        ])))
85    }
86}