0

こんにちは、Three.js を使用して webGL の作業を開始しています。球体をクリックしたときに、その表面の特定のセクション内にあるかどうかを検出する必要があります。

現在、球がクリックされたかどうかを検出し、クリックされたポイントの座標を取得できます。今私が必要としているのは、そのクリックがその球からの 3D ポイントの配列に基づいて、その球の特定の領域にあったかどうかを検出することです (別の提案は問題ありません)。

球は中心点にあり、その点は球の表面上にあることが保証されています。セクションセクション内にあるかどうかを計算する必要があります。助言がありますか?私の問題は、より数学的なものになっています。また、セクションが単なる三角形であるか、より複雑な図形である可能性があるため、これを行う一般的な方法を好みます。

4

4 に答える 4

0

私は別の方法と提案を使用することを終了しました。

私は行列式を使用しています。ここで、(T1、T2、T3)は三角形を形成する点であり、Xはこの三角形の内側にあるかどうかを知りたい点です。次に、3つの行列式を簡単に計算します。

d1 = det([T1 T2 X])
d2 = det([T1 X T3])
d3 = det([T1 T2 X])

すべての行列式が同じ符号の場合、点は三角形の内側にあります。次に、選択領域に基づいて三角形のリストを作成し、ポイントがそれらの三角形の1つの内側にあるかどうかを確認します。

this.Detector.triangleDetector = function(position, triangleArray){
    for(var idxString in triangleArray){
        var index = parseInt(idxString);
        if(this.pointInTriangle(position, triangleArray[index].coords1, triangleArray[index].coords2, triangleArray[index].coords3))
            return true;
    }
    return false;
}

この関数pointInTriangle(x,t1,t2,t3)は行列式の検証を行います。

this.Detector.pointInTriangle = function(x,T1,T2,T3){
    var array1 = [coord1.x ,coord1.y ,coord1.z];
    var array2 = [coord2.x ,coord2.y ,coord2.z];
    var array3 = [coord3.x ,coord3.y ,coord3.z];
    var zero = 0;
    var A = [[zero,zero,zero],[zero,zero,zero],[zero,zero,zero]];
    var d1,d2,d3;
    A[0][0] = position.x;
    A[0][1] = position.y;
    A[0][2] = position.z;
    A[1][0] = array2[0];
    A[1][1] = array2[1];
    A[1][2] = array2[2];
    A[2][0] = array3[0];
    A[2][1] = array3[1];
    A[2][2] = array3[2];
    d1 = MyMath.determinant(A,3);

    A[0][0] = array1[0];
    A[0][1] = array1[1];
    A[0][2] = array1[2];
    A[1][0] = position.x;
    A[1][1] = position.y;
    A[1][2] = position.z;
    d2 = MyMath.determinant(A,3);

    A[1][0] = array2[0];
    A[1][1] = array2[1];
    A[1][2] = array2[2];
    A[2][0] = position.x;
    A[2][1] = position.y;
    A[2][2] = position.z;
    d3 = MyMath.determinant(A,3);

    if((d1>=0 && d2 >=0 && d3>=0) || (d1<=0 && d2 <=0 && d3<=0)){
        return true;
    }
    return false;
};
于 2012-12-18T13:07:00.573 に答える
0

1 つの解決策は、各領域が独自の色を持つ疑似カラー イメージをテクスチャにレンダリングすることです。次に、画像をサンプリングし、疑似カラーを配列インデックスとして使用します。* 実際的な理由により、エンコーディングは値を少し分散させる必要があります。

于 2012-12-17T21:22:05.423 に答える
0

私の最初のアイデアは、3D ポイントを画面座標に投影することでした (つまり、画面上に図形を描くのとまったく同じように、ワールド座標からビュー座標へ)。これにより、関心のある表面に対応する視覚領域が得られます。これは、ビューを使用した単純な 3D から 2D への投影であり、クリック位置が 2D ポリゴン内にあるかどうかを確認できます。

次に、このアプローチの問題に気付きました。つまり、関心領域が球の背面に回り込むとうまくいかないということです。

これが問題になる場合は、カメラ方向に沿ってマウス クリックの投影を作成する必要があります。等角カメラを使用している場合、これは可能です...

于 2012-12-17T16:29:32.787 に答える
0

その点から (大円) 光線を描きます。曲線のセグメントとの最も近い交点を見つけます。セグメントが光線を右から左に横切る場合にのみ、点は曲線の内側にあります。

于 2012-12-17T17:48:11.960 に答える