计算矩形内最大旋转矩形的点和尺寸

时间:2012-10-29 20:08:48

标签: objective-c math

我有一个必须旋转的矩形总是相同的度数。让我们称这个角度为alpha()。

此矩形的宽度(w)和高度(h)可以变化。矩形始终适合在大矩形内旋转。它必须按比例放大或缩小以适合灰色矩形。

注意:Alpha是w和水平线之间的角度。

所以,有3种矩形

w > h
w < h  or
w = h

见下图。

enter image description here

我所知道的:

  1. 大矩形的宽度为R,高度为K,我知道两个值;
  2. w和h未知;
  3. 矩形始终旋转度;
  4. 我知道w / h的价值。我称之为“ratioWH”;
  5. 红色矩形始终在灰色矩形上水平和垂直居中
  6. 我需要知道的事情:

    1. w和h的最大值,适合w和h的每种情况的灰色矩形。
    2. P 的坐标,假设0,0位于灰色矩形的左上角。
    3. 这是我到目前为止所做的,但这并没有给出正确的值:

      CGPoint P = CGPointZero;
      
      if (ratioWH > 0) { // means w > h
      
          maxH = R / (ratioWH * fabsf(cosf(theta)) + fabsf(sinf(theta)));
          maxW = maxH * ratioWH;
      
          // P.x = 0.0f;  // P.x is already zero
          CGFloat marginY = (K - maxW * fabsf(sinf(theta)) - maxH * fabsf(cosf(theta))) / 2.0f;
          P.y = marginY +  maxW * fabsf(sinf(theta));
      
      } else { // w <= h
      
          maxW  = K / (fabsf(cosf(theta) / ratioImagemXY) + fabsf(sinf(theta)));
          maxH = maxW / ratioWH;
      
      
          P.x = (R - maxW * fabsf(cosf(theta)) - maxH * fabsf(sinf(theta))) / 2.0f;
          P.y = maxW * fabsf(sinf(theta));
      
      } 
      

      任何线索?感谢。

1 个答案:

答案 0 :(得分:4)

我看到它的方式是这样的......你计算出矩形的总宽度和总高度。为此,您只需沿着两条边走。像这样:

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

这些可能是负面的,因此如果将矩形旋转到其他象限中,则会应用特殊处理。这将在以后发生。

您现在只需要宽度和高度之间的比例。您可以在此决定是按垂直量还是水平量进行缩放。它与wh无关 - 它实际上是关于矩形因旋转而结束的位置。这就是dxdy的用途。

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

如果rectratio大于viewratio,则意味着需要缩放旋转的矩形的水平足迹。否则,您可以按垂直足迹进行缩放。

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

并且比例本身应用于原始宽度和高度

sw = scale * w
sh = scale * h

现在你可以计算矩形的角。你从哪里开始并不重要。

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)

我假设图像坐标为(0,0)左上角,因此增加y向下移动。所以,如果我在数学上没有犯错误,上面给出了矩形顶点(按顺时针顺序)。

最后要做的是将它们标准化...这意味着找到pxpy的最小值。称他们为pxminpymin。我不需要显示代码。我们的想法是计算矩形的偏移量,使得视图区域由矩形(0,0)定义为(R,K)

首先我们需要找到完全包含旋转矩形的子视图的左右值...记住之前的比率:

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

lefttop现在是我们子视图的“最小”坐标,它完全包含矩形(豁免浮点舍入误差)。所以:

left += pxmin
top += pymin

现在它们是将矩形移动到所需位置所需的偏移量。您所做的只是将lefttop添加到您的所有矩形坐标中,您就完成了。 P的位置为px[0]py[0]。如果旋转90度或更多,它将不是左上角的顶点。