1/* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17import {Point} from 'common/geometry/point'; 18 19export class Rect { 20 constructor( 21 readonly x: number, 22 readonly y: number, 23 readonly w: number, 24 readonly h: number, 25 ) {} 26 27 isAlmostEqual(other: Rect, eps: number): boolean { 28 const isClose = (a: number, b: number) => Math.abs(a - b) <= eps; 29 return ( 30 isClose(this.x, other.x) && 31 isClose(this.y, other.y) && 32 isClose(this.w, other.w) && 33 isClose(this.h, other.h) 34 ); 35 } 36 37 containsPoint(point: Point): boolean { 38 return ( 39 this.x <= point.x && 40 point.x <= this.x + this.w && 41 this.y <= point.y && 42 point.y <= this.y + this.h 43 ); 44 } 45 46 cropRect(other: Rect): Rect { 47 const maxLeft = Math.max(this.x, other.x); 48 const minRight = Math.min(this.x + this.w, other.x + other.w); 49 const maxTop = Math.max(this.y, other.y); 50 const minBottom = Math.min(this.y + this.h, other.y + other.h); 51 return new Rect(maxLeft, maxTop, minRight - maxLeft, minBottom - maxTop); 52 } 53 54 containsRect(other: Rect): boolean { 55 return ( 56 this.w > 0 && 57 this.h > 0 && 58 this.x <= other.x && 59 this.y <= other.y && 60 this.x + this.w >= other.x + other.w && 61 this.y + this.h >= other.y + other.h 62 ); 63 } 64 65 intersectsRect(other: Rect): boolean { 66 if ( 67 this.x < other.x + other.w && 68 other.x < this.x + this.w && 69 this.y <= other.y + other.h && 70 other.y <= this.y + this.h 71 ) { 72 let [x, y, w, h] = [this.x, this.y, this.w, this.h]; 73 74 if (this.x < other.x) { 75 x = other.x; 76 } 77 if (this.y < other.y) { 78 y = other.y; 79 } 80 if (this.x + this.w > other.x + other.w) { 81 w = other.w; 82 } 83 if (this.y + this.h > other.y + other.h) { 84 h = other.h; 85 } 86 87 return !new Rect(x, y, w, h).isEmpty(); 88 } 89 90 return false; 91 } 92 93 isEmpty(): boolean { 94 const [x, y, w, h] = [this.x, this.y, this.w, this.h]; 95 const nullValuePresent = 96 x === -1 || y === -1 || x + w === -1 || y + h === -1; 97 const nullHeightOrWidth = w <= 0 || h <= 0; 98 return nullValuePresent || nullHeightOrWidth; 99 } 100} 101