ユニットが追加または削除されたときに長方形の形成を維持するにはどうすればよいですか?


18

行と列のある長方形のボットがあります。ボットがフォーメーションに追加または削除されると、問題が発生します。これが発生すると、ボットは、長方形の構成がほぼ同じアスペクト比で、可能な限り長方形になるように、自分自身再配置する必要があります。これを行う方法?

いくつかのアイデア:

  • ボットを追加または削除する場合、ボットの新しい合計数と目的の一定のアスペクト比を使用して、そのアスペクト比に最も近いフォーメーションの新しい幅と高さを計算します。次に、何らかの方法でボットをシャッフルし、新しい次元に合わせます。

  • ボットが削除されたら、その背後にあったボットをその場所に移動し、フォーメーションの最後に到達するまで続行します。次に、バックランクのボットを何らかの方法でシャッフルすることにより、バックランクを可能な限り均等にします。

  • まったく異なる別のアイデアは、分子構造が一緒に留まる方法を模倣することです。4つの最も近いボットを引き付け、残りのボットを撃退することで、すべてのボットを4つの他のボットに囲ませます。逆二乗則を使用して分離を確保するには近すぎるボット(4つを含む)をすべて撃退します。また、構造全体の形状に追加の力が必要になります。しかし、これは非常に計算コストがかかります。

更新:だからサラームの答えを見て、良い次元を与える良い一般的な関数を思いついた。

最初に、以下の幅と高さの連立方程式を解いてから、答えを丸めました。

width/height=aspect ratio of your choice
width*height=number of bots

これにより、ボット数に対してそのアスペクト比に最も近い整数の長方形が得られます。最も近い長方形は、半分の時間が大きすぎ、半分の時間が小さすぎます(もちろん、ちょうどいいかもしれませんが、それらを気にする人もいます)。長方形が少し大きすぎる場合は、何もする必要はありません。バックランクはほぼ満杯になり、理想的です。長方形が少し小さすぎる場合は、問題が発生します。小さなオーバーフローは独自のランクに移動する必要があるため、少数のボットのみのランクが作成されますが、見た目は美しくありません。違いが大きい場合もあります(幅の半分よりも大きい)。この場合、1つのランクを加算または減算して、差を小さくします。次に、長方形が小さすぎる場合は、列を1つ追加して少し大きくします。それを行った後、バックランクは常に他のランクの少なくとも半分のボットを持っているように見えます。

更新

寸法を取得したら、それらを現在の寸法と比較します。新しい次元の間口が大きい場合、ランクごとに、下のランクからボットをポップし、そのランクのボットの数が間口と等しくなるまで、現在のランクにプッシュします。バックランクに達するまで、そのアルゴリズムを続けます。このアルゴリズムを使用すると、ボットは新しい次元に効率的に収まるように移動します。その後、単に新しい古いものをバックランクにプッシュします。アルゴリズムは、新しい間口が小さい場合と若干異なりますが、あなたはそれを把握できます!

次に、さらに2つの問題があります。削除、および新しいボットが必ずしもバックランクに割り当てられるわけではなく、追加された時点で最も近い位置にあるボットの柔軟な追加方法。


ユニット内のボットの最大数はいくつですか?比較的小さい場合、特定の数のボットに対してフォーメーションが持つ行と列の数をハードコーディングできます。
Exilyth

3
有効か無効かのフォーメーションの画像を投稿できますか?あなたが何を求めているのか理解するのに少し苦労しています。不完全な行/列は許可されますか?
マイケルハウス

3
これは素数では機能しないことを理解していますか?たとえば、ボットが7つある場合、背面に1つのボットがある3x2ユニットを作成する必要があります。
Exilyth

1
まあ、これは恥ずかしいです。私は素数を完全に忘れていました。次に、ALMOSTが満たされている行と列のみを許可することが次の最善策です。行の1つのボットは正しく見えませんが、行の1つのボットが悪く見えません。
Tiby312

3
トラブルを引き起こすのは素数だけではありません。ファクタリングによってフォーメーションサイズを選択すると、不当に長くて細いフォーメーションが得られる可能性があります。たとえば、ボットが14個ある場合、唯一の完全な長方形のフォーメーションは7x2ですが、ボットが2列追加された3x4フォーメーションの見栄えがよくなります。
ネイサンリード

回答:


16

別のテクニックは、ナポレオンの大隊で使用されているものを模倣することです(さらに、ギリシャのファランクスまでさかのぼります)。

間口は一般に一定に保たれ、男が倒れると(背中を除くあらゆる階級で)、彼は一歩進んだ彼のすぐ後ろの男に置き換えられます。NCOによってバックランクがシャッフルされ、各側面の極端に数人の男性が確保され、そうでなければ均等に埋められます。

間口は、バックランクが事前に指定された密度を下回る場合にのみ減少します。同様に、バックランクがいっぱいになると、エキストラは最初に両方の側面から追加のランクを埋め始め、それから間口が増加します。

間口を変更するときは、間口を増やすときにボットを後部ランクから両方の側面にファイリングし、間口を減らすときに両方の側面からバックランクにファイリングすることをお勧めします。

あなたが「軍事」印象を求めていると推測し、ボット組織をファランクスのように見せることが正しい場合、この順序変更はその目的を達成するためのより良い方法だと思います。

更新
後列を管理する簡単な方法の1つは、後列ユニットを3つの分隊に分割することです:各側面に1つと中央に1つです。間口が奇数か偶数か、および後列ユニットの数が0、1、または2 mod 3に一致するかどうかに応じて、管理するケースは正確に6つあります。

上記の機能強化として、
xxx.x .... x.xxx.x .... xのように、塗りつぶしがしきい値を下回ったら、各後列部隊の最後のユニットの間隔を空けることを検討してください。 xxx
またはこれ:
xx.xx..x.xxx.x ... xxxx
さらに見栄えを良くするには、もう少し作業が必要です。

更新#2
フォーメーションの深さに関する追加の考え。ボレー火の影響は、現代の銃剣と相まって、18世紀後半から19世紀初頭に3か4の深さで十分になりました。(イギリスは、戦いの終わりまで、2つのランクで戦うことめったにありませんでした。1つは、すぐにスクエアを形成するにはラインが長すぎたためです。)それ以前は、より深い、おそらく最大8または、サリッサを装備したギリシャのファランクスの場合は10。あなたが望む印象を作り出す深さを選択してください。

現実の軍隊は、戦場のレイアウトを簡素化するため、ユニットの脆弱性を犠牲にして、ユニットの正面をできるだけ長く維持しようとします。PharsalusのCaesarは、Pompeyの部隊に合わせて間口を広げるために、意図的にユニットの深さを減らしました。引用にあるように、「今日は勝つか死ぬか。ポンペイの部下には他の選択肢がある」。(もちろん、Caesarは賢明かつ慎重に保証しました)。


これは、はるかにエレガントなソリューションのようです。素数やアスペクト比について大騒ぎする必要はまったくありませんが、それでもボットの数が異常に少ない行は回避されます。また、チェックする必要がある唯一の条件は、バックランクがどれだけいっぱいかです!
Tiby312

しかし、ちょっと待ってください。バックランクには3つのボットのみがあり、列1、2、および3にあるとします。そして、5番目の列から誰かを削除します。5番目の列の最後から2番目から最後の行に、その場所をとるボットなしで無料のスポットができました。誰がこのスポットを埋めるべきですか?
Tiby312

おそらく、バックランクの最も近いボット(つまり、列3のボット)が実行されて、それを満たす必要があります。または、最後から2番目のランクの列3および4のボットを1列上に移動し、ギャップを列3に移動してから、列3のボットを前進させることで、少し時間を節約できますそれ。(IMO、最も「自然な」見た目戦略は、おそらく2つのヒューリスティックな組み合わせで、おそらくランダムにスローされます。)
Ilmari Karonen

1
バックランクのメンバーが少なすぎる場合(他のランクの50%未満など)、間口を増やした場合、これにより問題が修正されることが保証されますか、それともバックランクのメンバーが増えた後でもメンバーが少なすぎる可能性がありますそれを繰り返す必要がある間口か何か?
Tiby312

1
@ Tiby312:あなたはそれを考えすぎていると思います。後でチューンそれをいつもあなたをすることができます知って、それを試してみる
ピーターGeerkens

7

ユニットがボットの線形データ構造(リストなど)であると仮定します。

最初に、データ構造にボット追加/削除し、ユニット内のボットの新しい数を決定する必要があります。

次に、https://en.wikipedia.org/wiki/Integer_factorizationを使用して、新しい行と列の量を決定する必要があります。

もちろん、これは素数のために常に可能であるとは限りません。新しい単位サイズが素数の場合、次に大きな単位サイズを使用する必要がありますが、そうではありません。

次に、データ構造を反復処理し、行と列に順番にボットを割り当てます。

ボットを配置するには、データ構造を反復し、各ボットに、ユニットの位置からボットの行と列で決定される量だけオフセットした位置を割り当てます(または、そのポイントをボットの移動のターゲットとして設定します)。

中心を1つの角に持つユニットを作成するには、ボットの位置は

unitPosition + 見出し * columnNumber * botSeparationDistance + rightVector * rowNumber * botSeparationDistance

中央が中央のユニットを作成するには、ボットの位置を次のように指定します

unitPosition + heading *(columnNumber * unitSeparationDistance-0.5 *(numberOfColumns * botSeparationDistance)+ rightVector * rowNumber * botSeparationDistance-0.5 *(numberOfRows * botSeparationDistance)

ここで、見出しは方向ユニットポインティングベクトル対向され、rightVectorは直交するベクトルである見出し

botSeparationDistanceを調整して、ボットをさらに遠くに近づけたり、近づけたりすることができます。

あなたのしている感じの空想した場合は、オフセットすることができますボットの最後の行をすることによって rightVectorする- * 0.5 *(actualNumberOfBotsInRow numberOfColumns)中心にそれらを形成に


これは私が探しているものに非常に近いです!私の唯一の予約は、新しい位置を割り当てるときに、ある行の右にあるボットが新しい長方形の次の行の一番左に割り当てられる可能性があり、その結果、ボットの移動距離とプロセスが長くなることです自分の新しい割り当てられた位置に到達しようとする他のボットの邪魔になる。ボットが追加または削除されると、ボットが遠く離れた目的地に向かうのに忙しくなり、フォーメーション全体がゴチャゴチャになるのではないかと心配しています。
Tiby312

2
常に新しい位置を計算し、線形反復を行う代わりに、最も近いボットをその位置に移動できます。
Exilyth

平方計算で終わることなくこれを行う方法は?これを正しく理解している場合、各ボットについて、2D配列の現在の位置から2D配列の最も近い位置を見つける必要があります。
Tiby312

各反復で、1つのユニットが割り当てられ(したがって、それ以上の反復で考慮する必要がない)、ランタイムはO(n!)になります。それでも、それはあまり良くありません。繰り返しになりますが、[選択の最適化構造]を構築し、n個の範囲のクエリを実行することも高速ではありません。私が今考えることができるのは、列の最後のボットを後ろに移動するか、列の最後の場所を後ろからボットで満たすことだけです。
Exilyth

これはどう。新しいフォーメーションの行サイズが小さいとします。次に、各行に追加のボットがあります。そのボットを1つ下に、1つを左に割り当てます。次の行には、場所のない2つのボットがあります。これら2つを下に、1つを左に割り当てます。次に、場所のない3つのボットを取得しました。下部に余分な行ができるまで続けます。ここにボールを吐きます。私はそれがすべての方法を通過するとは思わなかったが、それは動作し、その高速のように聞こえます。
Tiby312

2

大きな値が小さな長方形であるグラフに可能な位置を保存します。

[4][3][2][1]
[3][3][2][1]
[2][2][2][1]
[1][1][1][1]

ロボットが削除されるたびに、他のすべてのロボットを検索し、最小値を持つノード内のロボットを見つけます。A *またはBSTアルゴリズムを使用して、その最小値から空きスペースまでのパスを見つけます。削除されたロボットより小さい値のロボットが存在しない場合、何もしません。

これを行うことで、長方形がどのように減衰するかを制御することもできるはずです。たとえば、下のグラフのように、ロボットが横から下を離れると、ロボットはその場所を埋めます。

[4.9][3.8][2.7][1.0]
[4.8][3.7][2.6][1.0]
[3.9][3.6][2.5][1.0]
[3.5][3.4][2.4][1.0]
[2.9][2.8][2.3][1.0]
[2.0][2.1][2.2][1.0]
[1.9][1.8][1.7][1.0]
[1.6][1.5][1.4][1.0]

ここでは、3.8の1つが削除され、2.5の1つが来てその場所を埋めます。

[o][x][o][ ]
[o][o][o][ ]
[o][o][r][ ]
[o][o][ ][ ]
[o][o][ ][ ]
[ ][ ][ ][ ]
[ ][ ][ ][ ]
[ ][ ][ ][ ]

もう一つの例。ここでは2.8が削除されているため、最小のノード2.2がその場所を埋めます。

[o][o][o][ ]
[o][o][o][ ]
[o][o][o][ ]
[o][o][o][ ]
[o][x][r][ ]
[ ][ ][ ][ ]
[ ][ ][ ][ ]
[ ][ ][ ][ ]

おそらく、値を0にしたノードのリングが必要です。これは、パスファインディングアルゴリズムが穴を見つけるために、外側の周囲には決して配置しません。

[0.0][0.0][0.0][0.0][0.0][0.0]
[0.0][4.9][3.8][2.7][1.0][0.0]
[0.0][4.8][3.7][2.6][1.0][0.0]
[0.0][3.9][3.6][2.5][1.0][0.0]
[0.0][3.5][3.4][2.4][1.0][0.0]
[0.0][2.9][2.8][2.3][1.0][0.0]
[0.0][2.0][2.1][2.2][1.0][0.0]
[0.0][1.9][1.8][1.7][1.0][0.0]
[0.0][1.6][1.5][1.4][1.0][0.0]
[0.0][0.0][0.0][0.0][0.0][0.0]

A *の優れたチュートリアルはこちらにあります


これはいい考えですが、これを正しく理解していれば、完全な長方形ではないフォーメーションを許可しています。境界線の行と列がいっぱいではない場合があります。常に長方形の境界線になるように作成して、代わりに行と列の数を変更することでこの要件を満たすようにアスペクト比を少し変更できると考えていました。これを達成する新しい幅と高さをすでに計算できますが、その後、ボットを最も近いスポットに再割り当てする複雑な方法があります。
Tiby312

@ Tiby312たとえば、7台のロボットで完璧な長方形を作る計画はありますか
ClassicThunder

決して私は素数を忘れていました。ごめんなさい。しかし、行と列の数を調整することで、行または列のボット数が異常に少なくなることを回避できると考えています。
Tiby312

@ Tiby312常に完全な長方形にするよりも、一貫したアスペクト比(つまり、常に4:3または8:5)を目指した方が良いと思います。
corsiKa
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.