确定点是否在球体曲面的一部分内

时间:2012-12-17 16:19:41

标签: javascript math 3d three.js

您好我正在使用Three.js开始使用webGL,我需要检测一个球体上的点击是否在其表面的某个部分内。

目前,我可以检测球体是否被点击并获得点击的点的坐标。现在我需要的是根据该球体的一个3D点数来检测该点击是否在该球体的某个区域内(另一个建议是可以的)。

球体位于中心点,并且该点被限制在球体的表面上。现在我需要计算它是否只是在一节内。有什么建议?我的问题接缝更加数学化。 此外,我更喜欢通用的方法,因为这些部分可能只是一个三角形或可能是更复杂的数字。

4 个答案:

答案 0 :(得分:0)

我的第一个想法是将3D点投影到屏幕坐标(即从世界坐标到视图坐标,就像在屏幕上绘制形状一样)。这为您提供了与感兴趣表面相对应的视觉区域。这将是一个使用您的视图进行简单的3D到2D投影,然后您可以看到点击位置是否位于2D多边形中。

然后我意识到这种方法存在问题,即如果您感兴趣的区域绕到球体的后表面,它将无法工作。

如果这是一个问题,则需要沿摄像机方向构建鼠标单击投影。如果您使用等距相机,这应该是可能的......

答案 1 :(得分:0)

从该点绘制(大圆)光线。找到与曲线段最近的交点。当且仅当片段从右到左穿过光线时,该点在曲线内。

答案 2 :(得分:0)

一种解决方案是渲染伪彩色图像,其中您的区域每个都具有纹理的颜色。然后对图像进行采样,使用pesudocolor作为数组索引。 *出于特殊原因,编码应该将值扩散一点。

答案 3 :(得分:0)

我结束时使用了与建议不同的方法。

我正在使用矩阵行列式,其中:(T1,T2,T3)是形成三角形的点,X是我想知道它是否在这个三角形内的点,然后我简单地计算3个决定因素:

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

如果所有决定因素都是相同的符号,则该点位于三角形内。 现在我根据选择区域形成一个三角形列表,并检查该点是否位于其中一个三角形内。

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;
};