7

常に同じ角度で回転する必要がある長方形があります。この角度をアルファ()と呼びましょう。

この長方形の幅(w)と高さ(h)はさまざまです。長方形は常に大きな長方形の内側に回転して収まる必要があります。灰色の長方形の内側に収まるように拡大または縮小する必要があります。

注:アルファは、wと水平線の間の角度です。

つまり、3種類の長方形があります

w > h
w < h  or
w = h

下の写真を参照してください。

ここに画像の説明を入力してください

私が知っていること:

  1. 大きな長方形の幅はR、高さはKで、両方の値を知っています。
  2. wとhは不明です。
  3. 長方形は常に度回転します。
  4. 私はw/hの値を知っています。私はこれを「ratioWH」と呼んでいます。
  5. 赤い長方形は常に灰色の長方形の水平方向と垂直方向の中央に配置されます

私が知る必要があること:

  1. wとhの各ケースの灰色の長方形に適合するwとhの最大値。
  2. 0,0が灰色の長方形の左上にあると仮定した場合の点Pの座標。

これは私がこれまでに行ったことですが、これは正しい値を与えていません:

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));

} 

手がかりはありますか?ありがとう。

4

1 に答える 1

4

私の見方はこんな感じです…長方形の全幅と全高を計算します。そのためには、2つのエッジに沿って歩くだけです。このような:

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

これらは負の値になる可能性があるため、長方形が他の象限に回転する場合は、特別な処理が適用されます。これは後で起こります。

これで、幅と高さの比率が必要になります。ここで、垂直方向の量でスケーリングするか、水平方向の量でスケーリングするかを決定します。それは何の関係もありませんw-hそれは実際には回転の結果として長方形がどこで終わるかについてです。それが何のため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すると下に移動します。したがって、数学を間違えていなければ、上記は長方形の頂点を(時計回りに)示しています。

px最後に行うことは、それらを正規化することです...これは、との最小値を見つけることを意味しますpypxminそれらを呼び出してpymin。そのためのコードを表示する必要はありません。(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

leftこれでtop、サブビューの「最小」座標になり、長方形が正確に含まれます(浮動小数点の丸め誤差は除外されます)。それで:

left += pxmin
top += pymin

これで、長方形を目的の場所に移動するために必要なオフセットになります。すべての長方形の座標に追加するだけで、完了leftです。topの位置はとPです。90度以上回転すると、左上の頂点にはなりません。px[0]py[0]

于 2012-10-29T21:42:48.433 に答える