Created
November 3, 2022 19:01
-
-
Save jarommadsen/c2e9cf970265c2944778e7bbf3735d50 to your computer and use it in GitHub Desktop.
Given 2 points and an angle, find remaining points and width/height
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| type Point = {x: number; y: number}; | |
| type Rect = { | |
| topLeft: Point; | |
| topRight: Point; | |
| bottomLeft: Point; | |
| bottomRight: Point; | |
| width: number; | |
| height: number; | |
| }; | |
| const rotateAround = (point: Point, angle: number): Point => { | |
| const cosA = Math.cos(angle); | |
| const sinA = Math.sin(angle); | |
| return { | |
| x: point.x * cosA - point.y * sinA, | |
| y: point.y * cosA + point.x * sinA, | |
| }; | |
| }; | |
| /** | |
| * Given 2 points and an angle, find remaining points and width/height | |
| * | |
| * @param topLeft point 1 | |
| * @param bottomRight point 2 | |
| * @param angle Angle in radians (counter-clockwise) | |
| * @returns Full rectangle with width / height | |
| */ | |
| const getRotatedRectangle = ( | |
| topLeft: Point, | |
| bottomRight: Point, | |
| angle: number | |
| ): Rect => { | |
| // Get middle point | |
| const middle: Point = { | |
| x: bottomRight.x - topLeft.x, | |
| y: bottomRight.y - topLeft.y, | |
| }; | |
| // Translate origin to be at middle point | |
| const topLeftT: Point = { | |
| x: topLeft.x - middle.x, | |
| y: topLeft.y - middle.y, | |
| }; | |
| const bottomRightT: Point = { | |
| x: bottomRight.x - middle.x, | |
| y: bottomRight.y - middle.y, | |
| }; | |
| // Unrotate rotated points | |
| const topLeftU = rotateAround(topLeftT, -angle); | |
| const bottomRightU = rotateAround(bottomRightT, -angle); | |
| // Get unknown points and width/height | |
| const topRightU: Point = { x: bottomRightU.x, y: topLeftU.y }; | |
| const bottomLeftU: Point = { x: topLeftU.x, y: bottomRightU.y }; | |
| const width = Math.abs(bottomRightU.x - topLeftU.x); | |
| const height = Math.abs(bottomRightU.y - topLeftU.y); | |
| // Rotate new points back | |
| const topRightT: Point = rotateAround(topRightU, angle); | |
| const bottomLeftT: Point = rotateAround(bottomLeftU, angle); | |
| // Translate new points back | |
| const topRight: Point = { | |
| x: topRightT.x + middle.x, | |
| y: topRightT.y + middle.y, | |
| }; | |
| const bottomLeft: Point = { | |
| x: bottomLeftT.x + middle.x, | |
| y: bottomLeftT.y + middle.y, | |
| }; | |
| return { | |
| topLeft, | |
| topRight, | |
| bottomLeft, | |
| bottomRight, | |
| width, | |
| height, | |
| }; | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment