一千萬個為什麽

搜索

如何基於鼠標單擊獲取3D點的坐標?

當我點擊屏幕上的特定點時,我想要一個函數調用,它返回我點擊的3d場景中的點。

例如,當我點擊屏幕的左上角時,它應該返回x = 0,y = 1,z = 1;請幫我創建一個方法來做到這一點。

edit:

Root = new BranchGroup();

setLayout(new BorderLayout());
add(canvas3D,BorderLayout.CENTER);
SimpleUniverse universe = new SimpleUniverse(canvas3D);

Shape();
universe.addBranchGraph(Root);
ViewingPlatform viewingPlatform = universe.getViewingPlatform();
OrbitBehavior behavior = new OrbitBehavior(canvas3D);
behavior.setSchedulingBounds(bounds);
viewingPlatform.setViewPlatformBehavior(behavior);
viewingPlatform.setNominalViewingTransform();
}

我在NetBeans中使用 SimpleUniverse

最佳答案

我擔心答案不是直截了當的。根據場景中的內容,單擊屏幕時鼠標坐標應該會發生變化。例如,如果你有兩個物體使前面的物體遮擋後面的物體那麽你就想要獲得前面的物體坐標。這稱為 mouse picking ,有幾種技術可供選擇。我發現了一些論壇,解釋了它是如何完成的,並有代碼示例。

基本上這個想法是你想象在用戶和屏幕之間存在激光(或其他投射光線的東西)。然後,這個東西投射光線通過屏幕表面上的點,鼠標被點擊進入屏幕。然後將拾取光線路徑上的任何內容,並且可選地解決光線路徑中對象的遮擋順序,以便為您提供最接近“屏幕”的對象。

我不熟悉J3D,但是從一些教程中刪除了以下代碼。它應該至少讓你開始。你要找的是底行的 Point3D intercept = ...

http://www.java3d.org/selection.html

package j3d_picking;

import java.awt.*;
import javax.swing.*;
import javax.media.j3d.*;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.picking.behaviors.*;
import com.sun.j3d.utils.geometry.*;
import com.sun.j3d.utils.picking.PickIntersection;
import com.sun.j3d.utils.picking.PickResult;
import com.sun.j3d.utils.picking.PickTool;
import javax.vecmath.Point3d;

public class HelloJava3D
        extends JFrame
{

    public HelloJava3D()
    {
        GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();
        Canvas3D canvas3D = new Canvas3D(config);

        BranchGroup scene = createSceneGraph();

       //SimpleUniverse is a Convenience Utility class
        SimpleUniverse simpleU = new SimpleUniverse(canvas3D);

       //This moves the ViewPlatform back a bit so the
       //objects in the scene can be viewed.
        simpleU.getViewingPlatform().setNominalViewingTransform();

        BoundingSphere behaveBounds = new BoundingSphere();
        ExamplePickBehavior behavior = new ExamplePickBehavior(canvas3D, scene, behaveBounds);
        scene.addChild(behavior);

        scene.compile();
        simpleU.addBranchGraph(scene);

        getContentPane().add(canvas3D, BorderLayout.CENTER);
    }//end of HelloJava3D (constructor)

    public BranchGroup createSceneGraph()
    {
       //Create the root of the branch graph
        BranchGroup objRoot = new BranchGroup();

       //Create a simple shape leaf node, add it to the scene graph.
       //ColorCube is a Convenience Utility class
        ColorCube cube = new ColorCube(0.4);
        cube.setCapability(Node.ENABLE_PICK_REPORTING);
        PickTool.setCapabilities(cube, PickTool.INTERSECT_FULL);
        objRoot.addChild(cube);

        return objRoot;
    }//end of createSceneGraph method of HelloJava3D

    public static void main(String[] args)
    {
        JFrame frame = new HelloJava3D();
        frame.setTitle("Hello Java3D");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setBounds(0, 0, 400, 300);
        frame.setVisible(true);
    }

    private class ExamplePickBehavior extends PickMouseBehavior
    {

        public ExamplePickBehavior(Canvas3D canvas, BranchGroup bg, Bounds bounds)
        {
            super(canvas, bg, bounds);
            setSchedulingBounds(bounds);

            pickCanvas.setMode(PickTool.GEOMETRY_INTERSECT_INFO);
           //allows PickIntersection objects to be returned
        }

        public void updateScene(int xpos, int ypos)
        {
            pickCanvas.setShapeLocation(xpos, ypos);
           //register mouse pointer location on the screen (canvas)

            Point3d eyePos = pickCanvas.getStartPosition();
           //get the viewer's eye location

            PickResult pickResult = null;
            pickResult = pickCanvas.pickClosest();
           //get the intersected shape closest to the viewer

            if (pickResult != null) {
                PickIntersection pi = pickResult.getClosestIntersection(eyePos);
               //get the closest intersect to the eyePos point
                Point3d intercept = pi.getPointCoordinatesVW();
                System.out.println(intercept);
               //extract the intersection pt in scene coords space
               //use the intersection pt in some way...
            }
        }//end of updateScene(  )
    }//end of ExamplePickBehavior class
}

轉載註明原文: 如何基於鼠標單擊獲取3D點的坐標?