Calculating point and dimensions of maximum rotated rectangle inside rectangle


The way I see it is like this... You work out the total width and total height of the rectangle. For that, you simply walk along two edges. Like this:

dx = w * cos(theta) + h * sin(theta)
dy = h * cos(theta) + w * sin(theta)

These could be negative, so special handling would apply if the rectangle is rotated into other quadrants. This will happen later.

You now just need the ratio between the width and height. This is where you decide whether to scale by the vertical amount or the horizontal amount. It's nothing to do with w and h -- it's actually about where the rectangle ends up as a result of rotation. That's what dx and dy are for.

rectratio = abs( dx / dy )
viewratio = R / K

If rectratio comes out larger than viewratio that means the rotated rectangle's horizontal footprint needs to be scaled. Otherwise you scale by the vertical footprint.

if rectratio > viewratio
    scale = R / abs(dx)
else
    scale = K / abs(dy)
end

And the scale itself is applied to the original width and height

sw = scale * w
sh = scale * h

So now you can compute the corners of your rectangle. It doesn't matter where you start.

x[0] = 0
x[1] = x[0] + sw * cos(theta)
x[2] = x[1] + sh * sin(theta)
x[3] = x[2] - sw * cos(theta)

y[0] = 0
y[1] = y[0] - sw * sin(theta)
y[2] = y[1] + sh * cos(theta)
y[3] = y[2] + sw * sin(theta)

I've assumed image co-ordinates given that (0,0) is top-left, so increasing y moves down. So, if I haven't made a mistake in my math, the above gives you the rectangle vertices (in clockwise order).

The last thing to do is normalise them... This means finding the min value of px and py . Call them pxmin and pymin . I don't need to show code for that. The idea is to calculate an offset for your rectangle such that the view area is defined by the rectangle (0,0) to (R,K) .

First we need to find the left and right value of the subview that completely contains our rotated rectangle... Remember the ratio before:

if( rectratio > viewratio )
    // view is too tall, so centre vertically:
    left = 0
    top = (K - scale * abs(dy)) / 2.0
else
    // view is too wide, so centre horizontally:
    left = (R - scale * abs(dx)) / 2.0
    top = 0
end

left and top are now the 'minimum' co-ordinate of our subview that exactly contains the rectangle (floating point rounding errors exempted). So:

left += pxmin
top += pymin

Now they are the offset required to shift the rectangle to where it's wanted. All you do is add left and top to all your rectangle co-ordinates, and you are done. The position of P is px[0] and py[0] . If you rotated by 90 degrees or more, it won't be the top-left vertex.

链接地址: http://www.djcxy.com/p/65502.html

上一篇: 如何在Razor View Page中导入名称空间?

下一篇: 计算矩形内最大旋转矩形的点和维数