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}