当前位置:  开发笔记 > 编程语言 > 正文

从旋转的矩形计算边界框坐标

如何解决《从旋转的矩形计算边界框坐标》经验,为你挑选了4个好方法。

我有一个矩形左上角的坐标,以及从0到180和-0到-180的宽度,高度和旋转.

我试图获取矩形周围的实际框的边界坐标.

什么是计算边界框坐标的简单方法

Min y,max y,min x,max x?

A点并不总是在最小值上,它可以在任何地方.

如果需要,我可以在as3中使用矩阵变换工具包.



1> MarkusQ..:

变换所有四个角的坐标

找到所有四个x中最小的一个 min_x

找到所有四个x中最大的并调用它 max_x

与y同上

你的边界框是 (min_x,min_y), (min_x,max_y), (max_x,max_y), (max_x,min_y)

AFAIK,没有任何皇家之路可以让你快得多.

如果您想知道如何变换坐标,请尝试:

x2 = x0+(x-x0)*cos(theta)+(y-y0)*sin(theta)
y2 = y0-(x-x0)*sin(theta)+(y-y0)*cos(theta)

其中(x0,y0)是您旋转的中心.您可能需要修改这个,具体取决于您的三角函数(他们希望度数或弧度)坐标系的感觉/符号与指定角度的方式等.


@MarkusQ你提到的x2方程应该是x0 +(x-x0)*cos(theta) - (y-y0)*sin(theta)而不是x0 +(x-x0)*cos(theta)+(y-y0) )*罪(theta),我是对的吗?
实际上,由于对称性,你只需要转换2个角,如果你想一点额外的想法,它只是**1**角旋转.

2> Olie..:

我意识到你要求ActionScript,但是,如果有人来到这里寻找iOS或OS-X答案,它是这样的:

+ (CGRect) boundingRectAfterRotatingRect: (CGRect) rect toAngle: (float) radians
{
    CGAffineTransform xfrm = CGAffineTransformMakeRotation(radians);
    CGRect result = CGRectApplyAffineTransform (rect, xfrm);

    return result;
}

如果您的操作系统为您提供了所有艰苦的工作,那就试试吧!:)

迅速:

func boundingRectAfterRotatingRect(rect: CGRect, toAngle radians: CGFloat) -> CGRect {
    let xfrm = CGAffineTransformMakeRotation(radians)
    return CGRectApplyAffineTransform (rect, xfrm)
}


想要补充一点,角度必须是弧度,而不是度数.可以节省你一些时间.;)

3> Troubadour..:

MarkusQ概述的方法非常有效,但请记住,如果已经有A点,则不需要转换其他三个角.

另一种更有效的方法是测试旋转角度所在的象限,然后直接计算答案.这样做效率更高,因为你只有两个if语句的最坏情况(检查角度),而另一个方法的最差情况是12个(当检查其他三个角以查看它们是否大于当前时,每个组件为6个)我认为最大或小于当前最小值.

基本算法仅使用了毕达哥拉斯定理的一系列应用,如下所示.我用theta表示了旋转角度,并以度为单位表示检查,因为它是伪代码.

ct = cos( theta );
st = sin( theta );

hct = h * ct;
wct = w * ct;
hst = h * st;
wst = w * st;

if ( theta > 0 )
{
    if ( theta < 90 degrees )
    {
        // 0 < theta < 90
        y_min = A_y;
        y_max = A_y + hct + wst;
        x_min = A_x - hst;
        x_max = A_x + wct;
    }
    else
    {
        // 90 <= theta <= 180
        y_min = A_y + hct;
        y_max = A_y + wst;
        x_min = A_x - hst + wct;
        x_max = A_x;
    }
}
else
{
    if ( theta > -90 )
    {
        // -90 < theta <= 0
        y_min = A_y + wst;
        y_max = A_y + hct;
        x_min = A_x;
        x_max = A_x + wct - hst;
    }
    else
    {
        // -180 <= theta <= -90
        y_min = A_y + wst + hct;
        y_max = A_y;
        x_min = A_x + wct;
        x_max = A_x - hst;
    }
}

这种方法假定你拥有你所拥有的,即A点和θ的值,它位于[-180,180]的范围内.我还假设theta在顺时针方向上增加,因为图中旋转了30度的矩形似乎表明你正在使用,我不确定右边的部分是什么意思.如果这是错误的方法,那么只需交换对称子句以及st术语的符号.



4> 小智..:
    fitRect: function( rw,rh,radians ){
            var x1 = -rw/2,
                x2 = rw/2,
                x3 = rw/2,
                x4 = -rw/2,
                y1 = rh/2,
                y2 = rh/2,
                y3 = -rh/2,
                y4 = -rh/2;

            var x11 = x1 * Math.cos(radians) + y1 * Math.sin(radians),
                y11 = -x1 * Math.sin(radians) + y1 * Math.cos(radians),
                x21 = x2 * Math.cos(radians) + y2 * Math.sin(radians),
                y21 = -x2 * Math.sin(radians) + y2 * Math.cos(radians), 
                x31 = x3 * Math.cos(radians) + y3 * Math.sin(radians),
                y31 = -x3 * Math.sin(radians) + y3 * Math.cos(radians),
                x41 = x4 * Math.cos(radians) + y4 * Math.sin(radians),
                y41 = -x4 * Math.sin(radians) + y4 * Math.cos(radians);

            var x_min = Math.min(x11,x21,x31,x41),
                x_max = Math.max(x11,x21,x31,x41);

            var y_min = Math.min(y11,y21,y31,y41);
                y_max = Math.max(y11,y21,y31,y41);

            return [x_max-x_min,y_max-y_min];
        }

推荐阅读
家具销售_903
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有