Skip to main content

Picking and/or coordinate axes

Please note these java.net forums are being decommissioned and use the new and improved forums at https://community.oracle.com/community/java.
3 replies [Last post]
mu88
Offline
Joined: 2012-08-30

Hey,

actually, I'm developing an application with Java3D imitating 3D-Modelling-Programs like Surpac, Gocad, Blender, ...

I have two different questions:

1) I want to a "coordinate cross" in the bottom left corner of the screen which indicates how I'm orientated in the 3D-space, please have a look at the attached picture.
This object shouldn't be zoomed or translated, only rotated. How can I implement this?

2) I have several spheres representing sample points. I want to edit the z-value of these points with the mouse. The picking, dragging and translating itself is already implemented and works fine, but I add or subtract the following value:

dist = Math.sqrt(Math.pow(cur_pos_new.x - cur_pos.x, 2) + Math.pow(cur_pos_new.y - cur_pos.y, 2));

cur_pos is the screen position (in pixels) where mouse_down is caused, cur_pos_new where mouse_released is caused, so dist is the distance between the two mouse positions.

I would like to have the following: I pick a sphere and drag the mouse. The new z-value should be the projection of the mouse coordinates into 3D, so that the z-value of the picked sphere is always at the same position as the mouse. With other words, the sphere follows the mouse respectively is at the same position with respect to the x-y-coordinates of the sphere.

Is this possible?

Kind regards and thanks in advance

AttachmentSize
example.jpg16 KB

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
mu88
Offline
Joined: 2012-08-30

*push*

bhupendra_aole
Offline
Joined: 2006-01-31

I havn't checked it out, but below should be useful ...
org.jdesktop.j3d.examples.axisbehavior.ObjLoadAxis (checkout the source)

-Bhupen

mu88
Offline
Joined: 2012-08-30

Thank you for your answer, I haven't checked out yet, because I solved it on my own. Here is the code:

panel_coordinate_cross = new JPanel()
        {
private static final long serialVersionUID = 1L;
Vector3f x_axis, y_axis, z_axis;

            protected void paintComponent(Graphics g)
            {
            super.paintComponent(g);
           
            // initialize axis
            x_axis = new Vector3f(1, 0, 0);
            y_axis = new Vector3f(0, 1, 0);
            z_axis = new Vector3f(0, 0, 1);
           
            // get current rotation
            Matrix3d cur_rotation = new Matrix3d();
        Transform3D temp = new Transform3D();
        rootTransformGroup.getTransform(temp);
        temp.getRotationScale(cur_rotation);
           
        // rotate all axis
        x_axis = multMatVec(cur_rotation, x_axis);
        y_axis = multMatVec(cur_rotation, y_axis);
        z_axis = multMatVec(cur_rotation, z_axis);

            // draw x_axis
        drawArrow(Color.blue, x_axis, "X", (float)45, (float)0.3, g);
           
            // draw y_axis
        drawArrow(Color.red, y_axis, "Y", (float)45, (float)0.3, g);
           
            // draw z_axis
        drawArrow(Color.green, z_axis, "Z", (float)45, (float)0.3, g);
            }
           
            public void drawArrow(Color color, Vector3f cur_axis, String caption, float angle, float length, Graphics g)
            {
            // calculate all coordinates relative to {0; 0}
        // center => origin of axis
            int vec_x_1 = 0;
        int vec_y_1 = 0;
       
        // end of axis
        float vec_x_2 = cur_axis.x;
        float vec_y_2 = cur_axis.y;
       
        // first part of the arrow
        float a1_x = (float)(length * ((vec_x_1 - vec_x_2) * Math.cos(Math.PI * angle / 180) - (vec_y_1 - vec_y_2) * Math.sin(Math.PI * angle / 180)) + vec_x_2);
            float a1_y = (float)(length * ((vec_x_1 - vec_x_2) * Math.sin(Math.PI * angle / 180) + (vec_y_1 - vec_y_2) * Math.cos(Math.PI * angle / 180)) + vec_y_2);
           
            //second part of the arrow
            float a2_x = (float)(length * ((vec_x_1 - vec_x_2) * Math.cos(Math.PI * -angle / 180) - (vec_y_1 - vec_y_2) * Math.sin(Math.PI * -angle / 180)) + vec_x_2);
            float a2_y = (float)(length * ((vec_x_1 - vec_x_2) * Math.sin(Math.PI * -angle / 180) + (vec_y_1 - vec_y_2) * Math.cos(Math.PI * -angle / 180)) + vec_y_2);

        g.setColor(color);
        // center {0; 0} is shifted to {50 px; 50 px}
        // length of axis is set to 40
            g.drawLine(50, 50, (int)(50 + 40 * vec_x_2), (int)(50 - 40 * vec_y_2)); // draw axis
            g.drawLine((int)(50 + 40 * vec_x_2), (int)(50 - 40 * vec_y_2), (int)(50 + 40 * a1_x), (int)(50 - 40 * a1_y)); // draw first part of the arrow
            g.drawLine((int)(50 + 40 * vec_x_2), (int)(50 - 40 * vec_y_2), (int)(50 + 40 * a2_x), (int)(50 - 40 * a2_y)); // draw second part of the arrow
           
            g.drawString(caption, (int)(50 + 20 * vec_x_2), (int)(50 - 20 * vec_y_2)); // draw caption
            }
        };
        panel_coordinate_cross.setBounds(0, (int)dim.getHeight() - 200, 100, 100);
        panel_coordinate_cross.setOpaque(false); // make background transparent
        panel_coordinate_cross.setBorder(new BevelBorder(BevelBorder.RAISED)); // add border
       
        JLayeredPane layered_pane = getLayeredPane();
        layered_pane.add(panel_coordinate_cross, JLayeredPane.FRAME_CONTENT_LAYER + 1, 0);

multMatVec is just the matrix-vector-product, like this:

public Vector3f multMatVec(Matrix3d matrix, Vector3f vector)
{
// product of a matrix and a vector
Vector3f result;
float x, y, z;

x = (float)(matrix.m00 * vector.x + matrix.m01 * vector.y + matrix.m02 * vector.z);
y = (float)(matrix.m10 * vector.x + matrix.m11 * vector.y + matrix.m12 * vector.z);
z = (float)(matrix.m20 * vector.x + matrix.m21 * vector.y + matrix.m22 * vector.z);

result = new Vector3f(x, y, z);

return result;
}

Maybe it will help someone!