Javascript 获取未旋转旋转矩形的边界

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 } 在过去,我能够将旋转

我有一个已经应用了旋转的矩形。我想得到未旋转的尺寸(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
}
在过去,我能够将旋转设置为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
(弧度):

要计算绿色边,很明显它由两个重复的矩形三角形组成,如下所示:

所以,首先求解角度,我们知道:

  • 三角形的角度之和为π/2或180°
  • 旋转为
    alpha
  • 一个角度伽马为π/4或90°
  • 最后一个角度beta是
    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))
           } 
    }