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.
上一篇: 如何在Razor View Page中导入名称空间?
下一篇: 计算矩形内最大旋转矩形的点和维数