简体   繁体   English

Java2D,放大功能的图形

[英]Java2D, zoom in on a function's graphic

I am working on a project and I have to display the graphic of a function and zoom in on the graphic. 我正在一个项目上,我必须显示功能的图形并放大该图形。 Zoom in entirely or simply have a rectangle and in that rectangle have only the selected part zoomed in. Thing is, I have no clue how to do that and I am requesting some guidance from your side, SO. 完全放大或仅放大一个矩形,而在该矩形中仅放大选定的部分。问题是,我不知道如何执行此操作,因此,我需要您这边的一些指导。

This is my code, how can I zoom in on the graphic? 这是我的代码,如何放大图形?

import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;

class SimpleJava2DExample extends Frame {
    private static final long serialVersionUID = 1L;
    double XRmin, XRmax, YRmin, YRmax;
    int XEmin, XEmax, YEmin, YEmax;
    double Sx, Sy;
    int Nsteps;
    String textMessage;
    double deltaY = 0.3;

    // Constructor
    SimpleJava2DExample() {
        textMessage = "";
        XEmin = YEmin = 10;
        Nsteps = 100;
        XRmin = -Math.PI / 2.;
        XRmax = 3 * Math.PI / 2.;// XRmax = 7*Math.PI;
        // Calculates YRmin, YRmax
        YRmin = F(XRmin);
        YRmax = F(XRmax);
        double xr, yr;
        for (int i = 0; i < Nsteps; i++) {
            xr = XRmin + (XRmax - XRmin) * i / Nsteps;
            yr = F(xr);
            if (yr < YRmin)
                YRmin = yr;
            if (yr > YRmax)
                YRmax = yr;
        }
        YRmax += deltaY;
        // Enables the closing of the window.
        WindowListener listener = new WindowAdapter() {
            // Override
            public void windowClosing(WindowEvent w) {
                System.exit(0);
            }
        };
        addWindowListener(listener);
        // Mouse click event
        MouseListener mouselistener = new MouseAdapter() {
            public void mouseClicked(MouseEvent e) {
                int ex = (int) e.getPoint().getX();
                int ey = (int) e.getPoint().getY();
                textMessage = "(x, y) : (" + Xreal(ex) + ", " + Yreal(ey) + ")";
                repaint();
            }
        };
        addMouseListener(mouselistener);
        // Enables the resize of the window.
        addComponentListener(new ComponentAdapter() {
            @Override
            public void componentResized(ComponentEvent arg0) {
                repaint();
            }
        });
    }

    // The function to be plotted
    double F(double x) {
        return (double) ((Math.sin(x) + 0.5 * Math.sin(3 * x)) * Math.exp(-1.0
                * x));
    }

    // Conversions between user (real) space and device space
    // Conversion Xreal --> Xdevice
    int Xpix(double xr) {
        return XEmin + (int) ((xr - XRmin) * Sx);
    }

    // Conversion Yreal --> Ydevice
    int Ypix(double yr) {
        return YEmax - (int) ((yr - YRmin) * Sy);
    }

    // Conversion Xdevice --> Xreal
    double Xreal(double xe) {
        return XRmin + (xe - XEmin) / Sx;
    }

    // Conversion Ydevice --> Yreal
    double Yreal(double ye) {
        return YRmin + (YEmax - ye) / Sy;
    }

    // This function plots the axes of the graph
    void drawAxes(Graphics2D g2d) {
        g2d.setColor(Color.black);
        g2d.drawLine(Xpix(XRmin), Ypix(0.0), Xpix(XRmax), Ypix(0.0));
        g2d.drawLine(Xpix(0.0), Ypix(YRmin), Xpix(0.0), Ypix(YRmax));
        int fontsize = this.getFont().getSize();
        g2d.drawString("0", Xpix(0.0) - fontsize, Ypix(0.0) + fontsize);
        g2d.drawString("" + XRmax, Xpix(XRmax) - 8 * fontsize, Ypix(0.0)
                - fontsize);
        g2d.drawString("" + XRmin, Xpix(XRmin), Ypix(0.0) - fontsize);
        g2d.drawString("" + YRmax, Xpix(0.0) + fontsize, Ypix(YRmax) + 4
                * fontsize);
        g2d.drawString("" + YRmin, Xpix(0.0) + fontsize, Ypix(YRmin) - fontsize);
    }

    public void paint(Graphics g) {
        super.paint(g);
        // In order to use Java 2D, it is necessary to cast the Graphics object
        // into a Graphics2D object.

        Graphics2D g2d = (Graphics2D) g;
        // The current size of the window
        XEmax = this.getWidth() - 50;
        YEmax = this.getHeight() - 50;
        // Calculates the scale factors
        Sx = (XEmax - XEmin) / (XRmax - XRmin);
        Sy = (YEmax - YEmin) / (YRmax - YRmin);
        // Draw the axes
        drawAxes(g2d);
        // Draw the graph
        g2d.setColor(Color.red);
        double xr, yr;
        Point2D lastPoint = new Point2D.Double(Xpix(XRmin), Ypix(YRmin));
        for (int i = 1; i < Nsteps; i++) {
            xr = XRmin + (XRmax - XRmin) * i / Nsteps;
            yr = F(xr);
            Point2D currentPoint = new Point2D.Double(Xpix(xr), Ypix(yr));
            g2d.draw(new Line2D.Double(lastPoint, currentPoint));
            lastPoint = currentPoint;
        }
        g2d.setColor(Color.blue);
        int fontsize = this.getFont().getSize();
        g2d.drawString(textMessage, 2 * fontsize, this.getHeight() - 2
                * fontsize);
        textMessage = "";
    }
}

public class MainJava2D {

    public static void main(String[] args) {
        //Generate the window.
        SimpleJava2DExample f = new SimpleJava2DExample();
        //Define a title for the window.
        String s = new String("The first Java 2D graph of a univariate function");
        f.setTitle(s);
        //Definition of the window size in pixels
        f.setSize(500, 400);
        //Show the window on the screen.
        f.setVisible(true);
    }
}

The easiest way to zoom everything is to scale the Graphics2D object at the beginning of the paint method, but before it save the old AffineTransform and reset it at the end. 缩放所有内容的最简单方法是在paint方法的开始处缩放 Graphics2D对象,但先保存旧的AffineTransform并在最后将其重置。

// save the original transform so that it can be restored later
AffineTransform oldTransform = g2d.getTransform();
g2d.scale(zoom, zoom);
...
// use g2d normally
...
// restore the transform because the same Graphics2D object
// might be used to draw other components
g2d.setTransform(oldTransform );

As Andrew Thompson commented, you should probably use Swing instead of the very old AWT - if you do so, then you need to override paintComponent (instead of paint), but the scaling mechanism is the same. 正如安德鲁·汤普森(Andrew Thompson)所评论的那样,您可能应该使用Swing而不是非常老的AWT-如果这样做,则需要覆盖paintComponent(而不是paint),但是缩放机制是相同的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM