3

我为 MATLAB 编写了一个 JAVA-3D 扩展,以便能够以良好的性能进行 3D 绘图。我现在可以画线、点等。

但是如果你运行我的程序——即使在 main 中加载了几个对象——从某些查看位置一切都会消失。

如果任何熟悉 Java 3D 的人可以帮助我,我会非常高兴。从它工作的那一刻起,我计划在 Mathworkscentral 上发布它,包括感谢所有帮助解决问题的人。这是代码:

import com.sun.j3d.utils.behaviors.vp.*;
import java.awt.BorderLayout;
import java.awt.event.*;
import java.awt.GraphicsConfiguration;
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;
import javax.swing.JFrame;
import javax.vecmath.*;

public class scatterJ3D extends JFrame {
    /**
     * 
     */
    private static final long serialVersionUID = 8657880087849824536L;

    public SimpleUniverse MyUniverse;
    BoundingSphere bounds;

    public scatterJ3D(int WindowWidth, int WindowHeight, String Title) {

        // Make sure MATLAB is not closed when GUI is closed:
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        addWindowListener(new WindowAdapter() {
            public void windowClosed(WindowEvent e) {
                dispose();
            }
        });

        // Launch and init GUI
        setTitle(Title);
        setSize(WindowWidth, WindowHeight);
        setLocationRelativeTo(null);
        setLayout(new BorderLayout());
        GraphicsConfiguration config = SimpleUniverse
                .getPreferredConfiguration();
        Canvas3D c = new Canvas3D(config);
        c.setSize(WindowWidth, WindowHeight);
        c.setDoubleBufferEnable(true);
        add("Center", c);

        // Create MyUniverse
        MyUniverse = new SimpleUniverse(c);

        // Init Bounds
        bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);

        // Enable Mouse rotation - new Way
        OrbitBehavior orbit = new OrbitBehavior(c, OrbitBehavior.REVERSE_ALL);
        // Option vertikales Drehen verhindern:
        // orbit.setRotYFactor(0.0f); 
        orbit.setSchedulingBounds(bounds);

        // Create Viewing Platform
        ViewingPlatform vp = MyUniverse.getViewingPlatform();
        vp.setViewPlatformBehavior(orbit);

        MyUniverse.getViewingPlatform().setNominalViewingTransform();


        // Set near Plane clipping
        View myview = c.getView();
        myview.setFrontClipDistance(0.0f);
        myview.setBackClipDistance(100.0f);
        myview.setVisibilityPolicy(View.VISIBILITY_DRAW_ALL);

    }

    public void setView(String Mode) {

        ViewingPlatform vp = MyUniverse.getViewingPlatform();
        // Set the user's initial viewpoint using lookAt()
        TransformGroup vpTG = vp.getViewPlatformTransform();
        Transform3D t3d = new Transform3D();
        vpTG.getTransform(t3d);
        // lookAt Arguments are: viewer position, where looking, up direction
        if (Mode.compareToIgnoreCase("Lab") == 0) {
            System.out.println("View set to Lab Mode!");
            t3d.lookAt(new Point3d(0.0f, 0.0f, -2.0f), new Point3d(0.0f, 0.0f,
                    0.0f), new Vector3d(1.0, 0.0, 0.0));
        } else if (Mode.compareToIgnoreCase("RGB") == 0) {
            System.out.println("View set to Lab Mode!");
            t3d.lookAt(new Point3d(3.0f, -1.0f, -2.0f), new Point3d(0.0f, 0.0f,
                    0.0f), new Vector3d(1.0, 1.0, 1.0));
        } else {
            System.out
                    .println("ERROR --> View can only be set to RGB or Lab Mode!");
        }
        t3d.invert();
        vpTG.setTransform(t3d);
    }

    public void setView(float viewerPosition[],float lookAt[], float upVector[]) {
        // Convert MATLAB float to Java Data Types
        Point3d JviewerPosition = new Point3d(viewerPosition[0], viewerPosition[1], viewerPosition[2]);
        Point3d JlookAt = new Point3d(lookAt[0], lookAt[1], lookAt[2]);
        Vector3d JupVector = new Vector3d(upVector[0], upVector[1], upVector[2]);

        ViewingPlatform vp = MyUniverse.getViewingPlatform();
        // Set the user's initial viewpoint using lookAt()
        TransformGroup vpTG = vp.getViewPlatformTransform();
        Transform3D t3d = new Transform3D();
        vpTG.getTransform(t3d);

        // Set LookAt to input Values
        t3d.lookAt(JviewerPosition, JlookAt, JupVector);
        t3d.invert();
        vpTG.setTransform(t3d);
    }

    public Background setBackgroundColor(float r, float g, float b) {
        // Create BranchGroup MyRoot
        BranchGroup MyRoot = new BranchGroup();

        // Set the background color
        Background back = new Background(r, g, b);
        back.setApplicationBounds(bounds);
        back.setCapability(Background.ALLOW_COLOR_WRITE);

        // System.out.println("Hier komma noch hin");
        MyRoot.addChild(back);
        MyRoot.compile();
        MyUniverse.addBranchGraph(MyRoot);
        return back;
    }

    // public Shape3D createPoints(float Coords[][], float Colors[][],int pointsize, float pivot[])
    public PointArray createPoints(float Coords[][], float Colors[][],
            int pointsize, float pivot[])
    {

        // Convert MATLAB float to Java Data Types
        Vector3f Jpivot = new Vector3f(pivot[0], pivot[1], pivot[2]);
        Point3f Jcoords[] = new Point3f[Coords.length];
        Color4f Jcolors[] = new Color4f[Colors.length];

        for (int i = 0; i < Coords.length; i++) {
            Jcoords[i] = new Point3f(Coords[i][0], Coords[i][1], Coords[i][2]);
            // x-Achse zeigt nach oben, y-Achse nach rechts:
            Jcolors[i] = new Color4f(Colors[i][0], Colors[i][1], Colors[i][2],
                    Colors[i][3]);
        }

        // set up the appearance to make large, transparent, antialiased points
        Appearance app = new Appearance();
        // increase the size of each point and turn on AA
        // PointAttributes pa = new PointAttributes(3.0f, true);
        // app.setPointAttributes(pa);
        // set up transparency
        TransparencyAttributes ta = new TransparencyAttributes();
        ta.setTransparencyMode(TransparencyAttributes.NICEST);
        ta.setTransparency(0.5f); // used if color is not COLOR_4
        app.setTransparencyAttributes(ta);

        PointArray pointCloud = new PointArray(Jcoords.length,
                PointArray.COORDINATES | PointArray.COLOR_4);
        pointCloud.setCoordinates(0, Jcoords);
        pointCloud.setColors(0, Jcolors);
        pointCloud.setCapability(PointArray.ALLOW_COORDINATE_WRITE);
        // Point size 10
        PointAttributes pa = new PointAttributes(pointsize, true);
        app.setPointAttributes(pa);
        // Make Shape
        Shape3D pointCloudShape = new Shape3D(pointCloud, app);

        // Create BranchGroup MyRoot
        BranchGroup MyRoot = new BranchGroup();
        Transform3D zTrans = new Transform3D();
        // zTrans.set(new Vector3f(0.0f, 0.0f, -1.0f));
        Jpivot.negate();
        zTrans.set(Jpivot);
        TransformGroup objTrans = new TransformGroup(zTrans);
        objTrans.addChild(pointCloudShape);
        MyRoot.addChild(objTrans);

        // Content-Branch optimieren und zurueckgeben
        MyRoot.compile();
        MyUniverse.addBranchGraph(MyRoot);

        //return pointCloudShape;
        return pointCloud;
    }

    //public Shape3D movePoints(Shape3D pointCloudShape, float Coords[][]) {
    public PointArray movePoints(PointArray pointCloud, float Coords[][]) {

        // Convert MATLAB float to Java Data Types
        Point3f Jcoords[] = new Point3f[Coords.length];

        for (int i = 0; i < Coords.length; i++) {
            Jcoords[i] = new Point3f(Coords[i][0], Coords[i][1], Coords[i][2]);
        }

        // return pointCloudShape;
        return pointCloud;
    }

    public Shape3D createLines(float fromCoords[][], float toCoords[][],
            float Colors[][], float linesize, float pivot[]) {

        // Convert MATLAB float to Java Data Types
        Vector3f Jpivot = new Vector3f(pivot[0], pivot[1], pivot[2]);
        Point3f JCoords[] = new Point3f[toCoords.length * 2];
        Color4f JColors[] = new Color4f[Colors.length * 2];

        for (int i = 0; i < fromCoords.length; i++) {
            JCoords[i * 2] = new Point3f(fromCoords[i][0], fromCoords[i][1],
                    fromCoords[i][2]);
            JCoords[i * 2 + 1] = new Point3f(toCoords[i][0], toCoords[i][1],
                    toCoords[i][2]);
            // x-Achse zeigt nach oben, y-Achse nach rechts:
            JColors[i * 2] = new Color4f(Colors[i][0], Colors[i][1],
                    Colors[i][2], Colors[i][3]);
            JColors[i * 2 + 1] = new Color4f(Colors[i][0], Colors[i][1],
                    Colors[i][2], Colors[i][3]);
        }

        // Set Appearance
        Appearance app = new Appearance();
        // // Transparency
        TransparencyAttributes ta = new TransparencyAttributes();
        ta.setTransparencyMode(TransparencyAttributes.NICEST);
        ta.setTransparency(1.0f); // used if color is not COLOR_4
        app.setTransparencyAttributes(ta);
        // // SetLinesize and Pattern (SOLID, DASH, DOT)
        LineAttributes la = new LineAttributes(linesize,
                LineAttributes.PATTERN_SOLID, true);
        app.setLineAttributes(la);

        // Create Line Array
        LineArray dot = new LineArray(JCoords.length, LineArray.COORDINATES
                | LineArray.COLOR_4);
        // System.out.println(JCoords[0]);
        dot.setCoordinates(0, JCoords, 0, JCoords.length);
        dot.setColors(0, JColors, 0, JColors.length);

        // Make Shape
        Shape3D dotShape = new Shape3D(dot, app);

        // Create BranchGroup MyRoot
        BranchGroup MyRoot = new BranchGroup();
        Transform3D zTrans = new Transform3D();

        Jpivot.negate(); // move Object Pivot to Universe(0,0,0)
        zTrans.set(Jpivot);
        TransformGroup objTrans = new TransformGroup(zTrans);
        objTrans.addChild(dotShape);
        MyRoot.addChild(objTrans);

        // Content-Branch optimieren und zurueckgeben
        MyRoot.compile();
        MyUniverse.addBranchGraph(MyRoot);
        return dotShape;
    }

    public static void main(String[] args) {

        // Init some Values
        float colors[][] = new float[8][4];
        float coords[][] = new float[8][3];

        colors[0][0] = 0.0f; colors[0][1] = 0.0f; colors[0][2] = 0.0f; colors[0][3] = 1.0f;
        colors[1][0] = 1.0f; colors[1][1] = 0.0f; colors[1][2] = 0.0f; colors[1][3] = 1.0f;
        colors[2][0] = 0.0f; colors[2][1] = 1.0f; colors[2][2] = 0.0f; colors[2][3] = 1.0f;
        colors[3][0] = 0.0f; colors[3][1] = 0.0f; colors[3][2] = 1.0f; colors[3][3] = 1.0f;
        colors[4][0] = 1.0f; colors[4][1] = 1.0f; colors[4][2] = 0.0f; colors[4][3] = 1.0f;
        colors[5][0] = 0.0f; colors[5][1] = 1.0f; colors[5][2] = 1.0f; colors[5][3] = 1.0f;
        colors[6][0] = 1.0f; colors[6][1] = 0.0f; colors[6][2] = 1.0f; colors[6][3] = 1.0f;
        colors[7][0] = 1.0f; colors[7][1] = 1.0f; colors[7][2] = 1.0f; colors[7][3] = 1.0f;

        coords[0][0] = 0.0f; coords[0][1] = 0.0f; coords[0][2] = 0.0f;
        coords[1][0] = 1.0f; coords[1][1] = 0.0f; coords[1][2] = 0.0f;
        coords[2][0] = 0.0f; coords[2][1] = 1.0f; coords[2][2] = 0.0f;
        coords[3][0] = 0.0f; coords[3][1] = 0.0f; coords[3][2] = 1.0f;
        coords[4][0] = 1.0f; coords[4][1] = 1.0f; coords[4][2] = 0.0f;
        coords[5][0] = 0.0f; coords[5][1] = 1.0f; coords[5][2] = 1.0f;
        coords[6][0] = 1.0f; coords[6][1] = 0.0f; coords[6][2] = 1.0f;
        coords[7][0] = 1.0f; coords[7][1] = 1.0f; coords[7][2] = 1.0f;

        float pivot[] = new float[3];
        pivot[0] = 0.5f; pivot[1] = 0.5f; pivot[2] = 0.5f;
        // Create Window
        scatterJ3D MyGFX = new scatterJ3D(800, 600, "Trallala");
        MyGFX.setVisible(true);

        // Load Points
        PointArray MyPoints1 = MyGFX.createPoints(coords, colors, 15, pivot);

        // Init Values for Lines
        float lscoords[][] = new float[4][3];
        lscoords[0][0] = 0.0f;lscoords[0][1] = 0.0f;lscoords[0][2] = 0.0f;
        lscoords[1][0] = 0.0f;lscoords[1][1] = 0.0f;lscoords[1][2] = 0.0f;
        lscoords[2][0] = 0.0f;lscoords[2][1] = 0.0f;lscoords[2][2] = 0.0f;
        lscoords[3][0] = 0.0f;lscoords[3][1] = 0.0f;lscoords[3][2] = 0.0f;

        float ldcoords[][] = new float[4][3];
        ldcoords[0][0] = 1.5f;ldcoords[0][1] = 0.0f;ldcoords[0][2] = 0.0f;
        ldcoords[1][0] = 0.0f;ldcoords[1][1] = 1.5f;ldcoords[1][2] = 0.0f;
        ldcoords[2][0] = 0.0f;ldcoords[2][1] = 0.0f;ldcoords[2][2] = 1.5f;
        ldcoords[3][0] = 1.0f;ldcoords[3][1] = 1.0f;ldcoords[3][2] = 1.0f;

        float lcolors[][] = new float[4][4];
        lcolors[0][0] = 1.0f;lcolors[0][1] = 0.0f;lcolors[0][2] = 0.0f;lcolors[0][3] = 1.0f;
        lcolors[1][0] = 0.0f;lcolors[1][1] = 1.0f;lcolors[1][2] = 0.0f;lcolors[1][3] = 1.0f;
        lcolors[2][0] = 0.2f;lcolors[2][1] = 0.2f;lcolors[2][2] = 1.0f;lcolors[2][3] = 1.0f;
        lcolors[3][0] = 1.0f;lcolors[3][1] = 1.0f;lcolors[3][2] = 1.0f;lcolors[3][3] = 1.0f;


        // Load Lines
        MyGFX.createLines(lscoords, ldcoords, lcolors, 2, pivot);

        // Set Background color
        MyGFX.setBackgroundColor(0.5f, 0.5f, 0.5f);
        MyGFX.setView("rgb");

    }

}
4

1 回答 1

3

根据 View 的 javadoc, “前剪辑距离必须大于 0.0”。在渲染到屏幕窗口的情况下,我更喜欢“VIRTUAL_EYE”剪辑策略

可见性策略从默认状态“VISIBILITY_DRAW_VISIBLE”更改为“VISIBILITY_DRAW_ALL”可能对您的程序没有影响。当使用 RenderingAttributes 并且根据“setVisible(boolean visible)”禁用可见性时,这是相关的。

通过以下更改,您的程序运行良好:

// Set near Plane clipping
View myview = c.getView();
myview.setFrontClipDistance(0.1f); // was 0.0f
myview.setBackClipDistance(100.0f);
//myview.setVisibilityPolicy(View.VISIBILITY_DRAW_ALL);
myview.setBackClipPolicy(View.VIRTUAL_EYE);
myview.setFrontClipPolicy(View.VIRTUAL_EYE);

八月

于 2012-12-19T10:19:57.660 回答