Javascript 找到给定坐标、宽度和高度的矩形顶点
我有一个矩形,可以旋转。在每次旋转时,我需要知道它的新顶部、左侧、右侧和底部顶点Javascript 找到给定坐标、宽度和高度的矩形顶点,javascript,math,vertices,Javascript,Math,Vertices,我有一个矩形,可以旋转。在每次旋转时,我需要知道它的新顶部、左侧、右侧和底部顶点 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(thet
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
}
我已经尝试在新的矩形坐标中循环,但是我想在不循环的情况下计算顶点,以减少执行时间
首先,我计算新的旋转坐标,然后找到新的顶点
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
}
rotatedRectCorners(元素、中心、角度){
常数θ=(Math.PI/180)*角度
常数x=中心.x
常数oy=中心y
const xAx=Math.cos(θ)//x轴
常数xAy=Math.sin(θ)//x轴y
const x=element.left-ox//将矩形移动到原点
常数y=元素.top-oy
返回{
左上角:{
x:x*xAx-y*xAy+ox,//获取左上角的旋转位置
y:x*xAy+y*xAx+oy
},
右上角:{
x:(x+element.width)*xAx-y*xAy+ox,//获取右上角的旋转位置
y:(x+元素宽度)*xAy+y*xAx+oy
},
右下角:{
x:(x+元素.宽度)*xAx-(y+元素.高度)*xAy+ox,//获得右下角的旋转位置
y:(x+元素.宽度)*xAy+(y+元素.高度)*xAx+oy
},
左下角:{
x:x*xAx-(y+元素.高度)*xAy+ox,//获取左下角的旋转位置
y:x*xAy+(y+元素高度)*xAx+oy
}
}
}
矩形顶点(元素、中心、角度){
常量角点=旋转的角点(元素、中心、角度)
常数顶点={
顶部:{x:0,y:0},
左:{x:0,y:0},
右:{x:0,y:0},
底部:{x:0,y:0}
}
设maxX=null
设minX=null
设minY=null
设maxY=null
每个(角,(角)=>{
如果(maxX==null){
maxX=角点.x
顶点。右=角点
}
如果(minX==null){
minX=corner.x
顶点。左=角
}
if(minY==null){
minY=拐角处
顶点。顶部=角点
}
如果(maxY==null){
maxY=角点.y
顶点。底部=角点
}
如果(角点y>最大值){
maxY=角点.y
顶点。底部=角点
}
if(corner.x>maxX){
maxX=角点.x
顶点。右=角点
}
if(角点x
从左上角顺时针方向为矩形顶点编号。我们可以看到V[0]是角度范围0..Pi/2
中最左侧的顶点(90度,逆时针方向的角度),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
V[0]V[1]V[2]V[3]
//小角度
左上右下
V[2]V[3]V[0]V[1]
//180..270范围内的角度(π..3Pi/2)
左上右下
左索引=角度/90//JS中的整数除法(如果可能)
顶部指数=(1+角度/90)%4
右指数=(2+角度/90)%4
底部指数=(3+角度/90)%4
不是说在任何情况下都必须计算顶点坐标(更多时间)而不使用循环?复杂的计算需要像循环一样的算法,否则为什么要使用程序?使用循环可以减少时间,或者至少可以正确地编写循环。@zer00ne,我认为应该有一个数学模型solution@BohdanVovchuck你是对的,这种问题可以通过矩阵乘法来解决,但是为了在javascript中实现矩阵乘法,你需要一个循环。zer00ne是对的,循环不会自动失效。如果您打算提高执行时间,则可以通过将乘积计算(例如x*xAx)存储在中间变量中来改进
rotatedRectCorners
函数,目前每个计算在返回结果之前会计算两次。您还可以将rectVertexts
中的条件数减少一半,例如,如果(maxX==null | | | corner.x>maxX){maxX=corner.x;texts.right=corner}这将减少处理器需要执行的指令数,但速度的提高将以毫秒为单位。我明白了。好主意!