我有一个可以旋转的矩形。在每次旋转时,我需要知道其新的顶部,左侧,右侧和底部顶点。
我尝试遍历新的矩形坐标,但是我想不经循环计算顶点以减少执行时间
首先,我计算新的旋转坐标,然后找到新的顶点。
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
}
答案 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
在任何情况下都不必计算顶点坐标(更多时间)