錐台内に収まる最大の球を見つけるにはどうすればよいですか?


12

遠近法で描くことができる最大の球をどのように見つけますか?

上から見ると、次のようになります。

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

追加:右側の錐台に、私たちが何か知っていると思う4つのポイントをマークしました。錐台の8つの角すべて、および近端と遠端の中心の投影を解除できます。したがって、ポイント1、3、および4がわかります。また、ポイント2は3から4までの距離と同じ距離であることがわかります。センター?しかし、実際の数学とコードは私を免れます。

モデル(ほぼ球形で、ミニボールの境界球を持っている)をできるだけ大きく描きたい。

更新: boboboboとNathan Reedが示唆するように、 2平面上の円内アプローチを実装しようとしました。

function getFrustumsInsphere(viewport,invMvpMatrix) {
    var midX = viewport[0]+viewport[2]/2,
        midY = viewport[1]+viewport[3]/2,
        centre = unproject(midX,midY,null,null,viewport,invMvpMatrix),
        incircle = function(a,b) {
            var c = ray_ray_closest_point_3(a,b);
            a = a[1]; // far clip plane
            b = b[1]; // far clip plane
            c = c[1]; // camera
            var A = vec3_length(vec3_sub(b,c)),
                B = vec3_length(vec3_sub(a,c)),
                C = vec3_length(vec3_sub(a,b)),
                P = 1/(A+B+C),
                x = ((A*a[0])+(B*a[1])+(C*a[2]))*P,
                y = ((A*b[0])+(B*b[1])+(C*b[2]))*P,
                z = ((A*c[0])+(B*c[1])+(C*c[2]))*P;
            c = [x,y,z]; // now the centre of the incircle
            c.push(vec3_length(vec3_sub(centre[1],c))); // add its radius
            return c;
        },
        left = unproject(viewport[0],midY,null,null,viewport,invMvpMatrix),
        right = unproject(viewport[2],midY,null,null,viewport,invMvpMatrix),
        horiz = incircle(left,right),
        top = unproject(midX,viewport[1],null,null,viewport,invMvpMatrix),
        bottom = unproject(midX,viewport[3],null,null,viewport,invMvpMatrix),
        vert = incircle(top,bottom);
    return horiz[3]<vert[3]? horiz: vert;
}

私はそれを翼にしていることを認めます。2Dコードを3次元に拡張することで適応させようとしています。非球面を正しく計算しません。球の中心点は毎回カメラと左上を結ぶ線上にあり、大きすぎる(または近すぎる)ようです。コードに明らかな間違いはありますか?アプローチが修正された場合、機能しますか?


球体は、画像のように完全に遠方面の後ろ側にある必要がありますか?
ミカエルヘグストローム

@MikaelHögström可能な限り大きくするために、彼らはそうなると思いますか?
ウィル

うーん、それはあなたの目的次第だと思います...もしあなたが遠方面の半分を越えて球を描くなら、それはもっと大きいでしょうが、多分それはあなたの目的に反するでしょうか?
ミカエルヘグストローム

@MikaelHögströmaha私はあなたの質問を理解しています。はい、モデル全体を描画し、遠方のプレーンがクリップしないようにします。
ウィル

回答:


12

あなたの図面がそう示唆しているように見えるので、私はあなたの錐台が対称であると仮定します。3つの制約があります(錐台が2Dの場合は2つ):

A.球は、近距離面と遠距離面の間の距離より大きくすることはできません

場合はD、遠近距離があり、第1の制約は単純です:

R  D / 2

B.球は側面よりも広く成長できない

次に、もう1つの制約について、次の図に示すようにα、錐台のL半角と遠方面の半角であるとします。

錐台

最初の式は、三角形の三角法によって与えられます。2つ目は、三角形の角度の合計に由来します。これにより、2番目の制約が与えられます。

R  L tan((π - 2α) / 4)

錐台が3Dの場合、新しい値Lα値を持つ3番目の制約があります。

最終結果

Rあなたが探している値がmin3つの境界の。

パラメータを取得する方法

視界またはワールド空間で錐台の投影を解除できる場合、次の方法でL、D、およびαを計算できます。ここで、Pポイントは近い平面Qから、ポイントは遠い平面からです。

フォーミュラ2

矢印はベクトルを意味し、「。」は内積です。|| ベクトルの長さを示します。Q2with Q3およびP2with P3を置き換えて、垂直次元のLとαを取得します。


どのように、視錐台(ビューポートポイントを投影解除して近距離と遠距離を計算する)から、視野を決定しますか?そして、3Dでは3つではなく2つの選択肢しかありませんよね?コードにあなたのアルゴリズムを置くための私の試みはいつも私に非常に大きなR.与える
ウィル

@願わくば役立つと思われる数式を含む2つ目の図面を追加します。
サムホセバー

2

2D:錐台を三角形(2D)として考える

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

次に、三角形の内接円を見つけます。

3D問題として、正方形ベースのピラミッドの非球面を見つける必要があります。

数式があれば、ここで印刷しますが、残念ながら、数式はわかりません。


2
少なくとも「標準的な」フルスタ(せん断などのないもの)の場合は、2Dの垂直または水平の錐台のどちらか小さい方のFOVがあれば、おそらくそれで十分です。
ネイサンリード

1

可能な限り最大の球体は、中央の遠い面(ここではビューフラストラムの用語を使用)に触れる必要があります。また、どのFoV角度が小さいかに応じて、上下の平面または左右の平面に接触します。私は、これらの仮定に対する実際の数学的証拠は持っていないと言わざるを得ませんが、正しいはずです。誰かがこれを証明する方法についてアイデアを持っているかもしれません。

球は、その中心点と半径によって定義できます。CxとCyは、ファープレーンの中心と同じです。

Czと半径は、上記の仮定に基づいて方程式系を解くことによって取得できます。

Tは、正規化された法線ベクトルとしてt1、t2およびt3を、原点からの距離としてt4を使用して、下/上平面または左/右平面(上記参照)のいずれかです。fはファープレーンの中心です。

t1 * cx + t2 * cy + t3 * cz-t4 = r

-fz + cz = r

t1 * cx + t2 * cy + t3 * cz-t4 = -fz + cz

t1 * cx + t2 * cy + fz-t2 = + cz-t3 * cz

t1 * cx + t2 * cy-fz-t2 = cz *(1-t3)

cz =(t1 * cx + t2 * cy-fz-t2)/(1-t3)

次に、これをczに挿入してrを計算します。-fz + cz = r

射影行列からすべての平面を取得できます。(この場合はViewProjectionではありません)

その後、球を正しいスペースに移動する必要があります:C '= inverse(View)* C


1

似たようなことをしようとしていますが、私の場合、球が錐台の境界の外側に存在しない限り、速度は精度よりも重要です。

線分(または3dの面)間の最短距離を計算する場合、見つかった最短距離は、錐台の完全に内側にある内接円/非球面の直径として使用できます。内接円/非球面の原点は、単純にすべての頂点の平均(合計と除算)になります。それは非常に高速で、すべてのタイプの凸多面体でも機能します。

唯一の欠点は、円または球が必ずしも可能な限り最大の円または球ではないことです。ボリュームが多く、エッジが非常に短い錐台の場合、円/球の共有する錐台スペースは可能な限り少なくなります。

別のアイデア

3D視錐台の非球面が必要で、この錐台を作成するために使用される透視行列がある場合、ユニットキューブの非球面でその行列を使用するだけで、錐台の完全な非球面になります。(立方体の非球面の直径は、立方体のエッジの1つの長さであり、中心は立方体の頂点であり、立方体の頂点の平均です)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.