根据给定的坐标,宽度和高度查找矩形顶点

时间:2019-05-27 22:06:03

标签: javascript math vertices

我有一个可以旋转的矩形。在每次旋转时,我需要知道其新的顶部,左侧,右侧和底部顶点。

Before After rotate 我尝试遍历新的矩形坐标,但是我想不经循环计算顶点以减少执行时间

首先,我计算新的旋转坐标,然后找到新的顶点。

rotatedRectCorners(element, center, angle) {
    const theta = (Math.PI / 180) * angle
    const ox = center.x
    const oy = center.y
    const xAx = Math.cos(theta)  // x axis x
    const xAy = Math.sin(theta)  // x axis y
    const x = element.left - ox  // move rectangle onto origin
    const y = element.top - oy

    return {
        topLeft: {
            x: x * xAx - y * xAy + ox,   // Get the top left rotated position
            y: x * xAy + y * xAx + oy
        },
        topRight: {
            x: (x + element.width) * xAx - y * xAy + ox,   // Get the top right rotated position
            y: (x + element.width) * xAy + y * xAx + oy
        },
        bottomRight: {
            x: (x + element.width) * xAx - (y + element.height) * xAy + ox,   // Get the bottom right rotated position
            y: (x + element.width) * xAy + (y + element.height) * xAx + oy
        },
        bottomLeft: {
            x: x * xAx - (y + element.height) * xAy + ox,   // Get the bottom left rotated position
            y: x * xAy + (y + element.height) * xAx + oy
        }
    }
}

rectVertices(element, center, angle) {
    const corners = rotatedRectCorners(element, center, angle)
    const vertices = {
        top: {x: 0, y: 0},
        left: {x: 0, y: 0},
        right: {x: 0, y: 0},
        bottom: {x: 0, y: 0}
    }
    let maxX = null
    let minX = null
    let minY = null
    let maxY = null
    each(corners, (corner) => {
        if (maxX === null) {
            maxX = corner.x
            vertices.right = corner
        }
        if (minX === null) {
            minX = corner.x
            vertices.left = corner
        }
        if (minY === null) {
            minY = corner.y
            vertices.top = corner
        }
        if (maxY === null) {
            maxY = corner.y
            vertices.bottom = corner
        }
        if (corner.y > maxY) {
            maxY = corner.y
            vertices.bottom = corner
        }
        if (corner.x > maxX) {
            maxX = corner.x
            vertices.right = corner
        }
        if (corner.x < minX) {
            minX = corner.x
            vertices.left = corner
        }
        if (corner.y < minY) {
            minY = corner.y
            vertices.top = corner
        }
    })

    return vertices
}

1 个答案:

答案 0 :(得分:1)

让左上角的数字矩形顶点沿顺时针方向旋转。我们可以看到V [0]是角度范围0..Pi/2中最左边的顶点(90度,CCW方向上的角度),V [1]成为角度范围Pi/2..Pi中最左边的顶点,依此类推。

所以我们可以循环地旋转对应于旋转角度的两个数组

V[0]    V[1]    V[2]    V[3]   
           <==>                      //small angle
left    top     right  bottom


V[2]    V[3]     V[0]    V[1]   
           <==>                     //angle in range 180..270 (Pi..3Pi/2)
left    top     right  bottom




left_index = angle / 90   //integer division if possible in JS
top_index = (1 + angle / 90) % 4 
right_index = (2 + angle / 90) % 4 
bottom_index = (3 + angle / 90) % 4 

在任何情况下都不必计算顶点坐标(更多时间)