2012-07-23 17 views
0

我已經實現了三維射線拾取並且有一些準確性問題。當在屏幕的底部或中心進行拾取時,一切都很完美,但屏幕頂部的座標看起來稍微偏離了一點。所以當我在屏幕頂部附近選擇物體時,我經常選擇的不是我正在敲擊的物體,而是更低的物體。三維射線拾取精度

下面是截圖http://img838.imageshack.us/img838/9192/device20120723171612.png

我認爲這個問題可以在矩陣,所以這裏是我如何定義他們:

模型視圖

GLU.gluLookAt(gl, 
     camera.position.x, camera.position.y, camera.position.z, 
     camera.target.x, camera.target.y, camera.target.z, 
     camera.upAxis.x, camera.upAxis.y, camera.upAxis.z); 

投影

horizontalCenter = 0f; 
verticalCenter = 0f; 
shortSideLength = 1.0f; 
zNear = 1f; 
zFar = 200.0f; 
surfaceAspectRatio = (float) w/(float) h; 
float n = shortSideLength/2f; 
gl.glFrustumf(horizontalCenter - surfaceAspectRatio*n, 
       horizontalCenter + surfaceAspectRatio*n, 
       verticalCenter - n, verticalCenter + n, zNear, zFar); 

我的採摘代碼:

public static Point3d pickSquare(int size, float step, float tapX, float tapY, float[] modelView, float[] projection) 
{ 

    float[] near = new float[4]; 
    GLU.gluUnProject(tapX, raypickingViewport[3] - tapY, 0f, modelView, 0, projection, 0, raypickingViewport, 0, near, 0); 
    if (near[3] != 0) 
    { 
     near[0] = near[0]/near[3]; 
     near[1] = near[1]/near[3]; 
     near[2] = near[2]/near[3]; 
    } 
    Point3d near3 = new Point3d(near[0], near[1], near[2]); 

    float[] far = new float[4]; 
    GLU.gluUnProject(tapX, raypickingViewport[3] - tapY, 1f, modelView, 0, projection, 0, raypickingViewport, 0, far, 0); 
    if (far[3] != 0) 
    { 
     far[0] = far[0]/far[3]; 
     far[1] = far[1]/far[3]; 
     far[2] = far[2]/far[3]; 
    } 
    Point3d far3 = new Point3d(far[0], far[1], far[2]); 

    // here I'm searching for intersection with x0z plane using equation 
    // (x-x1)/(x2-x1) = (y-y1)/(y2-y1) = (z-z1)/(z2-z1) 
    // My y is 0 so I can find x and y coords. 

    float intersectY = (-near3.y)/(far3.y - near3.y); 
    float pickX = intersectY * (far3.x - near3.x) + near3.x; 
    float pickZ = intersectY * (far3.z - near3.z) + near3.z; 
    return new Point3d(pickX, 0f, pickZ); 
} 

感謝您的答覆。

回答

0

的問題是在Android狀態欄中。在480x800的屏幕上它的高度爲38個像素,所以我在挑選方法添加此行:

tapY-=38; 

,現在一切都很正常