WorldWindJava 画布上的 2D 图形动画?

发布于 2024-11-04 06:07:43 字数 7833 浏览 1 评论 0原文

也许你们中有些人使用 WWJ 形式的 NASA 世界风。我刚刚开始在 NetBeans 中设置所有内容,以便最新的 WWJ 与 jogl 和 co 一起运行。 我用基本的演示代码对其进行了测试。

我的目标是在 WWJ 画布上显示一个图表,该图表将定期更新并以这种方式动画化。它将是数据集的 2D 图表,将在后台计算,WWJ 程序必须读取并显示它。

您有一些技巧和简单的示例/教程来指导我如何做到这一点吗?

您好,我能够插入 jfreechart 图表,但我还无法“更新”图表,您能帮助我吗?

package screensaver;

import gov.nasa.worldwind.BasicModel;
import gov.nasa.worldwind.avlist.AVKey;
import gov.nasa.worldwind.awt.WorldWindowGLCanvas;
import gov.nasa.worldwind.geom.Angle;
import gov.nasa.worldwind.geom.Position;
import gov.nasa.worldwind.layers.RenderableLayer;
import gov.nasa.worldwind.render.Offset;
import gov.nasa.worldwind.render.ScreenImage;
import gov.nasa.worldwind.render.Size;
import gov.nasa.worldwind.view.firstperson.BasicFlyView;
import gov.nasa.worldwind.view.firstperson.FlyToFlyViewAnimator;

import java.awt.Frame;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

import javax.imageio.ImageIO;

///
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartFrame;
import org.jfree.chart.JFreeChart;
import org.jfree.data.general.DefaultPieDataset;

import java.awt.image.BufferedImage;

public class FullScreenTest{

    public static double test = 0;

    /**
     * The animated view
     */
    public static BasicFlyView view;

    /**
     * The ScreenSaver entry point, should run in windowed mode
     * with interactivity or fullscreen mode depending on flags
     * http://boinc.berkeley.edu/trac/wiki/ScreensaverEnhancements
     * @param args
     */
    public static void main(String[] args) {

            view = new BasicFlyView();
        Frame frame = new Frame("WorldwindFull");
        final WorldWindowGLCanvas worldWindowGLCanvas = new WorldWindowGLCanvas();
        worldWindowGLCanvas.setModel(new BasicModel());
        worldWindowGLCanvas.setView(view);

        worldWindowGLCanvas.addKeyListener(new java.awt.event.KeyListener() {
            public void keyTyped(KeyEvent e) {
            }

            public void keyReleased(KeyEvent e) {
            }

            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
                    System.exit(0);
                }
            }
        });

        RenderableLayer creditsLayer = new RenderableLayer();
        creditsLayer.setName("Credits");
        try {
            creditsLayer.addRenderables(createCredits());
        } catch (IOException ioEx) {

            ioEx.printStackTrace();
        }
        worldWindowGLCanvas.getModel().getLayers().add(creditsLayer);

                ////
                RenderableLayer chartsLayer = new RenderableLayer();
        chartsLayer.setName("Charts");
        try {
            chartsLayer.addRenderables(createCharts());
        } catch (IOException ioEx) {

            ioEx.printStackTrace();
        }
        worldWindowGLCanvas.getModel().getLayers().add(chartsLayer);



        frame.add(worldWindowGLCanvas);
        frame.setSize(640, 480);
        frame.setUndecorated(true);
        int size = frame.getExtendedState();
        size |= Frame.MAXIMIZED_BOTH;
        frame.setExtendedState(size);

        frame.setVisible(true);
        worldWindowGLCanvas.requestFocus();

        setUpTimer();
    }

    /**
     * Static method to produce credits for all involved
     * organisations
     * @return
     * @throws IOException
     */
    public static List<ScreenImage> createCredits() throws IOException
    {
        List<ScreenImage> allCredits = new ArrayList<ScreenImage>();
        ScreenImage creditWWC = new ScreenImage();
        creditWWC.setImageSource(ImageIO.read(
                new File("src/images/worldwindcentral.gif")));
        //TODO: More flexible out of code layout policy
        creditWWC.setScreenOffset(new Offset(0.10, 0.90, AVKey.FRACTION, AVKey.FRACTION));
        creditWWC.setSize(new Size(Size.MAINTAIN_ASPECT_RATIO, 0.05,
                AVKey.FRACTION,Size.MAINTAIN_ASPECT_RATIO, 0.05,
                AVKey.FRACTION));

                ScreenImage creditRKN = new ScreenImage();
        creditRKN.setImageSource(ImageIO.read(
                new File("src/images/logo_selfnet1.png")));
        //TODO: More flexible out of code layout policy
        creditRKN.setScreenOffset(new Offset(0.50, 0.90, AVKey.FRACTION, AVKey.FRACTION));
        creditRKN.setSize(new Size(Size.MAINTAIN_ASPECT_RATIO, 0.05,
                AVKey.FRACTION,Size.MAINTAIN_ASPECT_RATIO, 0.05,
                AVKey.FRACTION));

        allCredits.add(creditWWC);
                allCredits.add(creditRKN);
        return allCredits;
    }

        public static List<ScreenImage> createCharts() throws IOException
    {

            // create a dataset...
DefaultPieDataset dataset = new DefaultPieDataset();
dataset.setValue("Category 1", 43.2-test);
dataset.setValue("Category 2", 27.9+test);
dataset.setValue("Category 3", 79.5);
// create a chart...
JFreeChart chart = ChartFactory.createPieChart(
"Sample Pie Chart",
dataset,
true, // legend?
true, // tooltips?
false // URLs?
);
//chart.createBufferedImage(100, 100);
// create and display a frame...

//ChartFrame frame1 = new ChartFrame("First", chart);
//frame1.pack();
//frame1.setVisible(true);
//frame1.createImage(100, 100);

final BufferedImage image = chart.createBufferedImage(400, 300);

        List<ScreenImage> allCharts = new ArrayList<ScreenImage>();
        ScreenImage chart1 = new ScreenImage();
        chart1.setImageSource(image);
        //TODO: More flexible out of code layout policy
        chart1.setScreenOffset(new Offset(0.17, 0.60, AVKey.FRACTION, AVKey.FRACTION));
        chart1.setSize(new Size(Size.MAINTAIN_ASPECT_RATIO, 0.05,
                AVKey.FRACTION,Size.MAINTAIN_ASPECT_RATIO, 0.05,
                AVKey.FRACTION));

        allCharts.add(chart1);
        return allCharts;
    }

    /**
     * The globe auto-rotate animator
     * @param pos
     */
    public static void moveToLocation(Position pos) {
        if (pos == null) {
            return;
        }
        double elevation = view.getGlobe().getElevation(pos.getLatitude(),
                pos.getLongitude());
        FlyToFlyViewAnimator animator = FlyToFlyViewAnimator.
                createFlyToFlyViewAnimator(view, view.getEyePosition(),
                        new Position(pos.latitude, pos.longitude, elevation),
                        view.getHeading(), view.getHeading(), view.getPitch(),
                        view.getPitch(), view.getEyePosition().getElevation(),
                        view.getEyePosition().getElevation(), 10000, 0);
        view.addAnimator(animator);
        animator.start();
        view.firePropertyChange(AVKey.VIEW, null, view);
    }

    /**
     * Convenience timer set-up to periodically rotate the globe
     */
    public static void setUpTimer()
    {
        int delay = 5000;   // delay for 5 sec.
        int period = 10000;  // repeat every sec.
        Timer timer = new Timer();

        timer.scheduleAtFixedRate(new TimerTask() {
                public void run() {
                    Position pos = new Position(Angle.fromDegrees(
                            180*new Random().nextFloat()-90.0),
                                                Angle.fromDegrees(
                            360*new Random().nextFloat()-180.0),
                                                0.0);
                    moveToLocation(pos);

                            Random rn = new Random();
int n = 10 - 0 + 1;
int i = rn.nextInt() % n;
FullScreenTest.test =  0 + i;
System.out.println(FullScreenTest.test);

                }
            }, delay, period);
    }
}

Perhaps there are some of you using NASA's worldwind in WWJ form. I just started and set up everything in NetBeans, so that the latest WWJ runs there with jogl and co.
I tested it with basic demo code.

My aim is to display a graph on the WWJ canvas, that will be updated regularly and will be animated in this way. It will be a 2D graph of a dataset, that will be computed in the background and the WWJ programm has to read and display it.

Do you have some tips and EASY examples/tutorials for how I can do that?

Hi, I was able to insert a jfreechart chart, but I haven't been able to "update" the chart yet, could you help me?

package screensaver;

import gov.nasa.worldwind.BasicModel;
import gov.nasa.worldwind.avlist.AVKey;
import gov.nasa.worldwind.awt.WorldWindowGLCanvas;
import gov.nasa.worldwind.geom.Angle;
import gov.nasa.worldwind.geom.Position;
import gov.nasa.worldwind.layers.RenderableLayer;
import gov.nasa.worldwind.render.Offset;
import gov.nasa.worldwind.render.ScreenImage;
import gov.nasa.worldwind.render.Size;
import gov.nasa.worldwind.view.firstperson.BasicFlyView;
import gov.nasa.worldwind.view.firstperson.FlyToFlyViewAnimator;

import java.awt.Frame;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

import javax.imageio.ImageIO;

///
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartFrame;
import org.jfree.chart.JFreeChart;
import org.jfree.data.general.DefaultPieDataset;

import java.awt.image.BufferedImage;

public class FullScreenTest{

    public static double test = 0;

    /**
     * The animated view
     */
    public static BasicFlyView view;

    /**
     * The ScreenSaver entry point, should run in windowed mode
     * with interactivity or fullscreen mode depending on flags
     * http://boinc.berkeley.edu/trac/wiki/ScreensaverEnhancements
     * @param args
     */
    public static void main(String[] args) {

            view = new BasicFlyView();
        Frame frame = new Frame("WorldwindFull");
        final WorldWindowGLCanvas worldWindowGLCanvas = new WorldWindowGLCanvas();
        worldWindowGLCanvas.setModel(new BasicModel());
        worldWindowGLCanvas.setView(view);

        worldWindowGLCanvas.addKeyListener(new java.awt.event.KeyListener() {
            public void keyTyped(KeyEvent e) {
            }

            public void keyReleased(KeyEvent e) {
            }

            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
                    System.exit(0);
                }
            }
        });

        RenderableLayer creditsLayer = new RenderableLayer();
        creditsLayer.setName("Credits");
        try {
            creditsLayer.addRenderables(createCredits());
        } catch (IOException ioEx) {

            ioEx.printStackTrace();
        }
        worldWindowGLCanvas.getModel().getLayers().add(creditsLayer);

                ////
                RenderableLayer chartsLayer = new RenderableLayer();
        chartsLayer.setName("Charts");
        try {
            chartsLayer.addRenderables(createCharts());
        } catch (IOException ioEx) {

            ioEx.printStackTrace();
        }
        worldWindowGLCanvas.getModel().getLayers().add(chartsLayer);



        frame.add(worldWindowGLCanvas);
        frame.setSize(640, 480);
        frame.setUndecorated(true);
        int size = frame.getExtendedState();
        size |= Frame.MAXIMIZED_BOTH;
        frame.setExtendedState(size);

        frame.setVisible(true);
        worldWindowGLCanvas.requestFocus();

        setUpTimer();
    }

    /**
     * Static method to produce credits for all involved
     * organisations
     * @return
     * @throws IOException
     */
    public static List<ScreenImage> createCredits() throws IOException
    {
        List<ScreenImage> allCredits = new ArrayList<ScreenImage>();
        ScreenImage creditWWC = new ScreenImage();
        creditWWC.setImageSource(ImageIO.read(
                new File("src/images/worldwindcentral.gif")));
        //TODO: More flexible out of code layout policy
        creditWWC.setScreenOffset(new Offset(0.10, 0.90, AVKey.FRACTION, AVKey.FRACTION));
        creditWWC.setSize(new Size(Size.MAINTAIN_ASPECT_RATIO, 0.05,
                AVKey.FRACTION,Size.MAINTAIN_ASPECT_RATIO, 0.05,
                AVKey.FRACTION));

                ScreenImage creditRKN = new ScreenImage();
        creditRKN.setImageSource(ImageIO.read(
                new File("src/images/logo_selfnet1.png")));
        //TODO: More flexible out of code layout policy
        creditRKN.setScreenOffset(new Offset(0.50, 0.90, AVKey.FRACTION, AVKey.FRACTION));
        creditRKN.setSize(new Size(Size.MAINTAIN_ASPECT_RATIO, 0.05,
                AVKey.FRACTION,Size.MAINTAIN_ASPECT_RATIO, 0.05,
                AVKey.FRACTION));

        allCredits.add(creditWWC);
                allCredits.add(creditRKN);
        return allCredits;
    }

        public static List<ScreenImage> createCharts() throws IOException
    {

            // create a dataset...
DefaultPieDataset dataset = new DefaultPieDataset();
dataset.setValue("Category 1", 43.2-test);
dataset.setValue("Category 2", 27.9+test);
dataset.setValue("Category 3", 79.5);
// create a chart...
JFreeChart chart = ChartFactory.createPieChart(
"Sample Pie Chart",
dataset,
true, // legend?
true, // tooltips?
false // URLs?
);
//chart.createBufferedImage(100, 100);
// create and display a frame...

//ChartFrame frame1 = new ChartFrame("First", chart);
//frame1.pack();
//frame1.setVisible(true);
//frame1.createImage(100, 100);

final BufferedImage image = chart.createBufferedImage(400, 300);

        List<ScreenImage> allCharts = new ArrayList<ScreenImage>();
        ScreenImage chart1 = new ScreenImage();
        chart1.setImageSource(image);
        //TODO: More flexible out of code layout policy
        chart1.setScreenOffset(new Offset(0.17, 0.60, AVKey.FRACTION, AVKey.FRACTION));
        chart1.setSize(new Size(Size.MAINTAIN_ASPECT_RATIO, 0.05,
                AVKey.FRACTION,Size.MAINTAIN_ASPECT_RATIO, 0.05,
                AVKey.FRACTION));

        allCharts.add(chart1);
        return allCharts;
    }

    /**
     * The globe auto-rotate animator
     * @param pos
     */
    public static void moveToLocation(Position pos) {
        if (pos == null) {
            return;
        }
        double elevation = view.getGlobe().getElevation(pos.getLatitude(),
                pos.getLongitude());
        FlyToFlyViewAnimator animator = FlyToFlyViewAnimator.
                createFlyToFlyViewAnimator(view, view.getEyePosition(),
                        new Position(pos.latitude, pos.longitude, elevation),
                        view.getHeading(), view.getHeading(), view.getPitch(),
                        view.getPitch(), view.getEyePosition().getElevation(),
                        view.getEyePosition().getElevation(), 10000, 0);
        view.addAnimator(animator);
        animator.start();
        view.firePropertyChange(AVKey.VIEW, null, view);
    }

    /**
     * Convenience timer set-up to periodically rotate the globe
     */
    public static void setUpTimer()
    {
        int delay = 5000;   // delay for 5 sec.
        int period = 10000;  // repeat every sec.
        Timer timer = new Timer();

        timer.scheduleAtFixedRate(new TimerTask() {
                public void run() {
                    Position pos = new Position(Angle.fromDegrees(
                            180*new Random().nextFloat()-90.0),
                                                Angle.fromDegrees(
                            360*new Random().nextFloat()-180.0),
                                                0.0);
                    moveToLocation(pos);

                            Random rn = new Random();
int n = 10 - 0 + 1;
int i = rn.nextInt() % n;
FullScreenTest.test =  0 + i;
System.out.println(FullScreenTest.test);

                }
            }, delay, period);
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一向肩并 2024-11-11 06:07:43

因此,您添加了一个名为 CreditsLayer 的可渲染层,用于显示图像。更新图像的一种简单(可能有点粗略)的方法是处置图层(creditsLayer.dispose()),并在 worldWindowGLCanvas.redraw() 之后用另一个图像重新添加它。。由于屏幕保护程序不会经常更新,这可能是可以接受的。或者,您可以为每个图像设置不同的图层,并根据需要启用/禁用它们并重新绘制画布。华泰

So you added a renderable layer called creditsLayer which displays an image. A simple (maybe a bit crude) way to update the image is to dispose the layer (creditsLayer.dispose()) and re-add it with another image and after worldWindowGLCanvas.redraw(). As the screensaver won't update too often this might be acceptable. Or you can have different layers for each image you have and enable/disable them as you need and redraw the canvas. HTH

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文