Javascript 获取未旋转旋转矩形的边界
我有一个已经应用了旋转的矩形。我想得到未旋转的尺寸(x,y,宽度,高度) 以下是当前元素的尺寸:Javascript 获取未旋转旋转矩形的边界,javascript,canvas,ecmascript-6,transform,rectangles,Javascript,Canvas,Ecmascript 6,Transform,Rectangles,我有一个已经应用了旋转的矩形。我想得到未旋转的尺寸(x,y,宽度,高度) 以下是当前元素的尺寸: Bounds at a 90 rotation: { height 30 width 0 x 25 y 10 } 以下是旋转设置为“无”后的尺寸: Bounds at rotation 0 { height 0 width 30 x 10 y 25 } 在过去,我能够将旋转
Bounds at a 90 rotation: {
height 30
width 0
x 25
y 10
}
以下是旋转设置为“无”后的尺寸:
Bounds at rotation 0 {
height 0
width 30
x 10
y 25
}
在过去,我能够将旋转设置为0,然后读取更新的边界。但是,我使用的一个函数中有一个bug,所以现在我必须手动执行
是否有一个简单的公式可以使用我已有的信息来获得旋转0处的边界
更新:对象围绕对象中心旋转
更新:我需要的是下面的函数:
function getRectangleAtRotation(rect, rotation) {
var rotatedRectangle = {}
rotatedRectangle.x = Math.rotation(rect.x * rotation);
rotatedRectangle.y = Math.rotation(rect.y * rotation);
rotatedRectangle.width = Math.rotation(rect.width * rotation);
rotatedRectangle.height = Math.rotation(rect.height * rotation);
return rotatedRectangle;
}
var rectangle = {x: 25, y: 10, height: 30, width: 0 };
var rect2 = getRectangleAtRotation(rect, -90); // {x:10, y:25, height:0, width:30 }
我发现了一个类似的问题
更新2这是我的密码。它尝试获取直线的中心点,然后获取x、y、宽度和高度:
var centerPoint = getCenterPoint(line);
var lineBounds = {};
var halfSize;
halfSize = Math.max(Math.abs(line.end.x-line.start.x)/2, Math.abs(line.end.y-line.start.y)/2);
lineBounds.x = centerPoint.x-halfSize;
lineBounds.y = centerPoint.y;
lineBounds.width = line.end.x;
lineBounds.height = line.end.y;
function getCenterPoint(node) {
return {
x: node.boundsInParent.x + node.boundsInParent.width/2,
y: node.boundsInParent.y + node.boundsInParent.height/2
}
}
我知道我的例子使用了一个直角,你可以用它来交换x和y,但是旋转可以是任意大小
更新3
我需要一个函数,返回矩形的未旋转边界。我已经有了特定旋转的边界
function getUnrotatedRectangleBounds(rect, currentRotation) {
// magic
return unrotatedRectangleBounds;
}
我想我不需要太多的努力就可以处理边界大小的计算(方程式很少),相反,我不确定您希望如何处理
x
和y
首先,让我们正确地命名事物:
现在,我们要将其旋转一定角度alpha
(弧度):
要计算绿色边,很明显它由两个重复的矩形三角形组成,如下所示:
所以,首先求解角度,我们知道:
alpha
李>
gamma-alpha
李>
现在,知道了所有的角度和一条边,我们可以用正弦定律来计算其他边
简单回顾一下,正弦定律告诉我们,边长和它的对角之比是相等的。更多信息请点击此处:
在我们的例子中,对于左上角三角形(和右下角三角形),我们有:
记住,AD
是我们的原始高度
假设sin(gamma)
为1,并且我们也知道AD
的值,我们可以写出以下方程式:
对于右上角三角形(和左下角三角形),我们有:
有了所有需要的边,我们可以轻松计算宽度和高度:
width = EA + AF
height = ED + FB
此时,我们可以编写一个非常简单的方法,给定一个矩形和以弧度表示的旋转角度,可以返回新的边界:
function rotate(rectangle, alpha) {
const { width: AB, height: AD } = rectangle
const gamma = Math.PI / 4,
beta = gamma - alpha,
EA = AD * Math.sin(alpha),
ED = AD * Math.sin(beta),
FB = AB * Math.sin(alpha),
AF = AB * Math.sin(beta)
return {
width: EA + EF,
height: ED + FB
}
}
然后可以使用此方法,如下所示:
const rect = { width: 30, height: 50 }
const rotation = Math.PI / 4.2 // this is a random value it put here
const bounds = rotate(rect, rotation)
希望没有打字错误…这是怎么回事?
使用宽度、高度、x和y进行计算
弧度和角度
使用度计算弧度并计算sin
和cos
角度:
函数计算器diansandangles(){
常量旋转=此值;
常数dr=Math.PI/180;
常数s=数学sin(旋转*dr);
常数c=数学cos(旋转*dr);
控制台日志(旋转,s,c);
}
document.getElementById(“range”).oninput=calculateRadiansAndAngles代码>
我想我可能会找到一个解决方案,但为了安全起见,我宁愿事先重复我们所拥有的以及我们需要的,以确保我正确理解了所有内容。正如我在评论中所说,英语不是我的母语,由于我对这个问题缺乏理解,我已经写了一个错误的答案:)
我们所拥有的
我们知道在x
和y
有一个大小为w
和h
的边界矩形(绿色),其中包含另一个旋转角度为alpha
的矩形(灰色点)
我们知道y轴相对于笛卡尔轴是翻转的,这使得角度被认为是顺时针的,而不是逆时针的
我们需要什么
首先,我们需要找到内部矩形的4个顶点(A
,B
,C
和D
),并且知道顶点的位置,内部矩形的大小(W
和H
)
作为第二步,我们需要将内部矩形反向旋转0度,并找到它的位置X
和Y
找到顶点
一般来说,对于每个顶点,我们只知道一个坐标,x或y。另一个相对于角度alpha沿边界框的一侧“滑动”
让我们从A
开始:我们知道Ay
,我们需要Ax
我们知道,Ax
相对于角度alpha
位于x
和x+w
之间
当alpha
为0°时,Ax
为x+0
。当alpha
为90°时,Ax
为x+w
。当α为45°时,Ax
为x+w/2
基本上,Ax
随着sin(alpha)的关系而增长,给了我们:
使用Ax
,我们可以轻松计算Cx
:
同样,我们可以通过
计算,然后再计算Dy
:
编写一些代码:
// bounds is a POJO with shape: { x, y, w, h }, update if needed
// alpha is the rotation IN RADIANS
const vertices = (bounds, alpha) => {
const { x, y, w, h } = bounds,
A = { x: x + w * Math.sin(alpha), y },
B = { x, y: y + h * Math.sin(alpha) },
C = { x: x + w - w * Math.sin(alpha), y },
D = { x, y: y + h - h * Math.sin(alpha) }
return { A, B, C, D }
}
寻找双方
现在我们有了所有的顶点,我们可以很容易地计算内部矩形边,为了解释清楚,我们需要定义更多的点E
和F
:
很明显,我们可以使用Pitagorean定理计算W
和H
:
其中:
代码:
// bounds is a POJO with shape: { x, y, w, h }, update if needed
// vertices is a POJO with shape: { A, B, C, D }, as returned by the `vertices` method
const sides = (bounds, vertices) => {
const { x, y, w, h } = bounds,
{ A, B, C, D } = vertices,
EA = A.x - x,
ED = D.y - y,
AF = w - EA,
FB = h - ED,
H = Math.sqrt(EA * EA + ED * ED),
W = Math.sqrt(AF * AF + FB * FB
return { h: H, w: W }
}
查找反向旋转的内部矩形的位置
首先,我们必须找到角度(beta
// bounds is a POJO with shape: { x, y, w, h }, update if needed
// sides is a POJO with shape: { w, h }, as returned by the `sides` method
const origin = (bounds, sides) => {
const { x, y, w, h } = bounds
const { w: W, h: H } = sides
const GC = r = Math.sqrt(W * W + H * H) / 2,
IC = H / 2,
beta = Math.asin(IC / GC),
angleA = Math.PI + beta,
Ax = x + w / 2 + r * Math.cos(angleA),
Ay = y + h / 2 + r * Math.sin(angleA)
return { x: Ax, y: Ay }
}
// bounds is a POJO with shape: { x, y, w, h }, update if needed
// rotations is... the rotation of the inner rectangle IN RADIANS
const unrotate = (bounds, rotation) => {
const points = vertices(bounds, rotation),
dimensions = sides(bounds, points)
const { x, y } = origin(bounds, dimensions)
return { ...dimensions, x, y }
}
function getUnrotatedRectangleBounds(rect, currentRotation) {
//Convert deg to radians
var rot = currentRotation / 180 * Math.PI;
var hyp = Math.sqrt(rect.width * rect.width + rect.height * rect.height);
return {
x: rect.x + rect.width / 2 - hyp * Math.abs(Math.cos(rot)) / 2,
y: rect.y + rect.height / 2 - hyp * Math.abs(Math.sin(rot)) / 2,
width: hyp * Math.abs(Math.cos(rot)),
height: hyp * Math.abs(Math.sin(rot))
}
}