Development/Javascript | Typescript

[TS|TIP] 회전된 사각형을 내접하는 사각형(BoundingBox) 구하기

대범하게 2024. 7. 24. 23:49
반응형

회전된 사각형을 내접하는 사각형(BoundingBox) 구하기

해당 아이디어를 기억해놓기 위한 기록이다. 

아래는 순서대로 BoundingBox를 구하기 위한 함수들이다.

가능한 한 함수가 하나의 기능을 하도록 구현하였다. 

 

1. 각도를 라디안(radians)으로 변환하는 함수

const toRadians = (angle: number): number => {
    return (angle * Math.PI) / 180;
};

 

2. 회전한 사각형의 경계 계산에 사용되는 코사인, 사인 값을 구하는 함수

const getCosSin = (radians: number): { cos: number; sin: number } => {
    return {
        cos: Math.abs(Math.cos(radians)),
        sin: Math.abs(Math.sin(radians)),
    };
};

 

3. 사각형의 스케일된 너비, 높이 그리고 회전 각도에 따른 경계를 계산하는 함수

*복잡해보이지만, BoundingBox로 명명한 내접하는 사각형의 width, height를 수월하게 계산하기 위해 분리한 함수이다. 

*정확하게는 width를 구성하는 widthCos와 heightSin / height를 구성하는 heightCos, widthSin을 사용할 목적으로.

export const getBoundingBoxDimensionDetails = (
    dimension: { width: number; height: number },
    transform: { scaleX: number; scaleY: number; rotate: number }
): {
    width: { widthCos: number; heightSin: number };
    height: { heightCos: number; widthSin: number };
} => {
    const { width, height } = dimension;
    const { scaleX, scaleY, rotate } = transform;
    const { cos, sin } = getCosSin(toRadians(rotate));
    const scaledWidth = scaleX * width;
    const scaledHeight = scaleY * height;

    return {
        width: { widthCos: scaledWidth * cos, heightSin: scaledHeight * sin },
        height: { heightCos: scaledHeight * cos, widthSin: scaledWidth * sin },
    };
};

해당 함수의 목적은 바로 boundingBox의 width와 height를 구성하는 detail한 값들을 구하기 위한 함수

 

4. 회전된 사각형이 내접하는 사각형의 너비/높이를 구하는 함수

export const getBoundingBox = (
    dimension: { width: number; height: number },
    transform: { scaleX: number; scaleY: number; rotate: number },
): { width: number; height: number } => {
    const { width, height } = dimension;
    const { scaleX, scaleY, rotate } = transform;
    const { width: dimensionWidth, height: dimensionHeight } = getBoundingBoxDimensionDetails(
        { width, height },
        { scaleX, scaleY, rotate },
    );

    return {
        width: dimensionWidth.widthCos + dimensionWidth.heightSin,
        height: dimensionHeight.heightCos + dimensionHeight.widthSin,
    };
};

 

 

끝.