3Dヘックス様タイルマップのレイトレース(LOS)
-
27-09-2019 - |
質問
ご挨拶、
六角形のタイルマップの3Dバリアントを使用するゲームプロジェクトに取り組んでいます。タイルは実際には六角形ではなくキューブですが、六角形のようにレイアウトされています(正方形を立方体に回して2Dから3Dから外挿することができますが、ヘックスには3Dバージョンはありません)。冗長な説明ではなく、4x4x4マップの例を次のように説明します。
(私は、任意のタイル(緑)とその隣接するタイル(黄色)を強調して、全体がどのように機能するかを説明するのに役立ちました。しかし、隣接する機能は いいえ 問題、それはすでに解決されています。)
私はタイルを表すための構造体タイプを持っています、そして、マップは3Dのタイルとして表されます(に包まれています Map
いくつかのユーティリティ方法を追加するクラスですが、それはあまり関連性がありません)。各タイルは、aを表すことになっています 完璧です 立方体のスペース、そしてそれらはすべてです まさに 同じサイズ。また、隣接する「行」間のオフセットは まさに タイルの半分のサイズ。
それで十分なコンテキストです。私の質問は次のとおりです。
2つのポイントの座標が与えられます A
と B
, 、どのようにして、タイル(またはむしろ、それらの座標)のリストを生成できますか? A
と B
クロスしますか?
それは後に、視線の決定、充電経路の合法性など、さまざまな目的に使用されます。
ところで、これは便利かもしれません:私のマップは参照位置として(0,0,0)を使用します。マップの「ジャギング」は、各タイルを相殺するものとして定義できます ((y+z) mod 2) * tileSize/2.0
「正気な」デカルトシステムにある位置から右に。ジャグされていない行の場合、0は0を生成します。行の場合 (y+z) mod 2
1、0.5タイルを生成します。
.NETフレームワーク4.0をターゲットとするC#4に取り組んでいます。しかし、私は実際に特定のコードを必要としません。奇妙な幾何学的/数学的な問題を解決するためのアルゴリズムだけです。私はこれを何日も解決しようとしてきました。そして、すべてを紙に描いて「視覚化」しようとすることも、それも助けにはなりませんでした:(。
答えてくれてありがとう
解決
賢いそばの1つが現れるまで、ここに私の愚かな解決策があります。説明しやすくする2D 'COSで説明しますが、3Dに十分に簡単に一般化します。これを完全にセルインデックス空間で作業しようとする試みは失敗する運命にあると思います(ただし、それがまさに私が考えていることを認め、間違っていることを証明することを楽しみにしています)。
したがって、デカルト座標からセルインデックスにマッピングする関数を定義する必要があります。少し難しい場合、これは簡単です。まず、かどうかを決定します point(0,0)
の左下隅です cell(0,0)
またはセンター、または他のポイント。説明が簡単になるので、左下のコーナーを使用します。それを観察してください point(x,floor(y)==0)
マップへ cell(floor(x),0)
. 。確かに、 point(x,even(floor(y)))
マップへ cell(floor(x),floor(y))
.
ここでは、ブール関数を発明します even
その議論が偶数整数である場合、これは真実です。使用します odd
次:任意のポイント point(x,odd(floor(y))
マップへ cell(floor(x-0.5),floor(y))
.
これで、見通しを決定するためのレシピの基本があります。
また、マッピングする機能も必要です cell(m,n)
デカルト空間のポイントに戻ります。起源がどこにあるかを決定したら、それは簡単でなければなりません。
今、私がいくつかのブラケットを置き忘れない限り、あなたはあなたの道を進んでいると思います。あなたはする必要があります:
- どこにいるかを決めます
cell(0,0)
あなたは位置しますpoint(0,0)
;それに応じて関数を調整します。 - セルの境界に沿ったポイントがどこに落ちるかを決定します。と
- これを3つの次元に一般化します。
競技場のサイズに応じて、セル境界のデカルト座標をルックアップテーブル(または他のデータ構造)に保存できます。
他のヒント
おそらく、問題を別の方法で見ると、すべての複雑な数学を避けることができます。
私はあなたがブロックの半分のブロックに沿ってあなたのブロックを(交互に)シフトするだけであることがわかります。この軸に沿ってブロックを分割すると、上記の例は(シフト付き)(9x4x4)の単純なデカルト座標系になり、通常のスタックブロックを備えています。レイトレースを行うことは、はるかにシンプルになり、エラーが発生しやすくなります。