【发布时间】:2019-10-13 10:24:14
【问题描述】:
我有一个可以旋转的矩形。在每次旋转时,我都需要知道它的新顶部、左侧、右侧和底部顶点。
我尝试循环遍历新的矩形坐标,但我想在没有循环的情况下计算顶点以减少执行时间
首先,我计算新的旋转坐标,然后找到新的顶点。
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
}
【问题讨论】:
-
没有循环?复杂的计算需要像循环这样的算法,否则为什么要使用程序?使用循环可以减少时间或至少是正确编写的时间。
-
@zer00ne,我相信应该有数学解决方案
-
@BohdanVovchuck 你是对的,这种问题可以用矩阵乘法来解决,但是为了在javascript中实现矩阵乘法,你需要一个循环。 zer00ne 是对的,循环不会自动效率低下。
-
如果您打算提高执行时间,那么您可以通过将乘积计算(例如 x * xAx)存储在中间变量中来改进
rotatedRectCorners函数,目前每个都是计算的在返回结果之前两次。您还可以将rectVertices中的条件句数减少一半,例如if (maxX === null ||corner.x > maxX) { maxX =corner.x; vertices.right =corner } 这将减少处理器需要执行的指令数量,但速度提升将在几毫秒内。
标签: javascript math vertices