2012-02-28 8 views
2

再び、悪いタイトルのためにお詫び - 非常に説明するのは難しい。数学とJava - スケール値から利用可能なインデックスを見つけよう

私はこのプロジェクトで使用している言語だからJavaのタグを使用しましたが、実際にはどの言語にも当てはまります。

私は、わかりやすくするために簡単な例を使用します。

「ズーム」できるグラフィックを表示していて、スケールを表す0と1の間の浮動小数点にアクセスできます。

ここで同じグラフィックの異なるバージョンがあるとすると、「クローズアップ」の詳細が細かいレベルで表示され、遠いバージョンでは重要な機能のみが明瞭に示されます。

これらのバージョンのそれぞれは、次に大きなバージョンの半分のサイズです。最も近いクローズアップは1のズームレベルに相当します。

バージョンがいくつでもあり、それぞれが最後のものの半分の大きさのビューを表します。

だから、ユーザーがグラフィックをズームすると、別のバージョンを表示した方が良いかどうかを確認する必要があります。彼らがその点に達していない場合、私は以前のレベルの縮小版を表示します。

たとえば、5つの異なるバージョンがありますが(数字はありますが)、最小のものから最大のものまでありますが(これが簡単な場合は逆にすることもできます)、バージョン[4]が最大ですバージョン[0]は最小です。

例1のズームで

  • 、ショーバージョン0.5のズームで[4]
  • 、ショーバージョン0.25で[3]
  • 、ショーバージョン[2]
  • で0.125、ショーバージョン[1] 0.0625で
  • 、ショーバージョン[0]

には、バージョン無駄がないのでバージョン[0]の半分に対応できますが、バージョンは[0]ですが、半分のサイズで表示されます。別のバージョンが追加された場合は、全体の縮尺(ズーム)が0.03125以下になったときに表示されます。

スケールの間には、次に大きいイメージを表示する必要がありますが、サイズは小さくしてください。

例えば、1のズーム時

  • 、Iは最大表示したい(バージョン[4])、スケーリングされていません。 0.8のズーム時
  • は、依然として0.5のズームで最大しかし0.8規模
  • に示す、ショーバージョン[3] 0.3のズーム時
  • スケーリングされていない、ショーバージョン[3] 0.6スケール
  • 0.2のズームでは、0.8スケールでバージョン[2]を表示します。
  • 0.1のズームで、バージョン[1]を0に示します。8スケール

私はおそらくなどの条件文、またはリンクしMath.abs、一緒にこれをハック可能性がありますが、私は純粋数学でこれを処理するための非常にエレガントな、効率的な方法があります賭けだろう - それはちょうど道の上に私をです頭。そうでない場合は、クリーンで予測可能なコードを使用したアプローチに関する提案も歓迎されます。

ここでの目標は、表示するバージョンのバージョン(配列インデックス)とそれを表示する相対的なスケールを完全に「グローバル」スケールに基づいて見つけることです。

TYIA。

答えて

4
int indexToUse = 0-Math.round(Math.log(zoom)/Math.log(2)); 
double zoomToUse = zoom/Math.pow(2, -indexToUse); 

これは、各画像が前のものと大とまったく2倍であるという情報を使用します。これは指数的なスケールなので、その逆のログは、使用するインデックスを見つけるために使用されます。

その後、実際にズームレベルを取得するためにインデックスを2倍にし、目的のズームレベルを実際の倍率で除算して係数を取得します。

(ズームは常に0と1の間で行われるため、ログは常に負になりますので先に進み、無効にします)これに合わせて画像を並べ替えるのは簡単でしょう。実際のインデックスを使用するには長さを引いてください。)

BigMoMoはJavaのMath.logが自然なログであると指摘しました。また、彼が指摘したように、自然対数を自然対数2で割ってlog2を得ることができます。これをサンプルコードに反映しました。以下のような順序を逆にした場合

double getZoom(int index, double zoomOnImage){ 
    return Math.pow(2, -index) * zoomOnImage; 
} 
+0

非常に印象的bdares :)返信用 – John

+0

@bdaresのおかげで - 私は場合は恐れ入ります簡単な間違いをしますが、Math.logは1つの引数しか受け付けません。 – momo

+0

@bdares - Math.log(zoom)/ Math.log(2)ですか? – momo

0

Google Mapsのようなインターフェイスを試してみると、の連続したスケールではないことがわかります。代わりに、ステップで移動します。

1つのアプローチは、ユーザーが段階的にズームすることだけを許可し、これらのステップをさまざまな実数スケールでグラフィックバージョンに直接マップすることです。あなたはまださまざまなスケールでタイルの各セットを表示することができます。

Zoom Tileset Scale 
    1  1  0.5 
    2  1  1 
    3  2  0.25 
    4  2  0.5 
    5  2  1 
    ... 
+0

返事に感謝、私は状態間のスムーズな補間を提供しているこの - ユーザー規模の主要なモードは、ピンチジェスチャーを経由して – momo

0

、あなたの二次の質問に対処するため

:[0](最大)1のズーム、ショーのバージョンで

。 0.5のズームで、バージョンを表示[1]; 0.25で、バージョン[2]を示します。 0.125で、バージョンを表示[3]。 0.0625で、バージョンを表示[4]。 ...

インデックスがi = log(zoom)/ log(0.5)であることがわかります。またはズーム= pow(0.5、i)。 ズームが正確に0.5の累乗でない場合は、天井または整数部分を取るだけです。ズーム= 0.4、log(0.4)/ log(0.5)= 1.32192のとき、インデックスは1になるはずです。したがって、単純なインデックスはlog(zoom)/ log(0.5)の整数部分です。

実際ズームは:ズーム0.4を与えズーム/ Z [i]は(iはインデックスであり、zはズームアレイ{1、0.5、0.25、0.125、0.0625}である)

は、上記の例を続行します、インデックス= 1(上から)、最終ズームは0.4/z [i] = 0.4/z [1] = 0.4/0.5 = 0.8である。

実際にインデックスを取得するには、log(x)を計算する必要はありません。ズーム値を比較して、どのスロット/インデックスに一致するかを確認します。インデックスが見つかると、最終的なズームはズーム/ z [i]で計算されます。

+0

応答ありがとう。純粋な数学的解法とは対照的に、あなたが言及したアプローチを使用することに利点がありますか? – momo

+0

最初に私は数学的方法でそれを説明しました。私は数学的方法を知っていて、私はそれに反対しませんでした:-)私は配列のインデックスを取得するために、特に、ズームのレベルが多い場合、その位置の検索(比較)は、フロートでの "ログ"操作のほうが効率的でなければなりません。 – Richard

+0

クール、ありがとう - 私はそれをチェックします – momo

関連する問題