Java Graphics2D 平移和缩放/平移和缩放

发布于 2024-08-05 21:31:46 字数 991 浏览 7 评论 0原文

我有一个正在绘制的 JPanel,并且正在尝试获取它,以便您可以使用鼠标滚轮通过修改变量比例来“放大”和缩小。现在发生的情况是,您可以放大或缩小,但当您放大时,所有绘图都会向右和向下移动,而在缩小时会向上和向左移动。

我想让它像放大 JPanel 中心的点一样进行调整,但我不知道如何计算要平移的正确偏移量……

任何人都知道如何做到这一点,或者甚至更好的更干净的方式来实现整个平移和缩放功能?

我基本上绘制了来自系统的一堆坐标,其中 0,0 位于左下角并落在边界之间:

xMin = 661208
xMax = 662618

yMin = 4291657
yMax = 4293285

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);

    Graphics2D g2 = (Graphics2D) g;

    double scale = details.getScale();
    double xOffset = details.getxOffset();
    double yOffset = details.getyOffset();

    g2.scale(scale, -scale);

    // Dividing offset by scale makes panning 1:1 with the cursor still. yMax to account for the
    // fact we needed to flip around the y axis to make it right-side up.
    g2.translate((-xMin + xOffset / scale), (-yMax + yOffset / scale));

    // Code to draw stuff goes here.  It uses coordinates between xMin-xMax and yMin-yMax to draw.
    .
    .
    .
}

I've got a JPanel I'm drawing onto and I'm trying to get it so that you can use the mouse wheel to "zoom" in and out by modifying the variable scale. Right now what happens is you can zoom in or out but all of the drawing shifts to the right and downwards when you zoom in and then back up and left when zooming out.

I want to make it so that it adjusts as if you were zooming in on the point at the center of the JPanel but I can't figure out how to calculate the right offset to translate by…

Anybody got an idea of how to do this, or even better a cleaner way of achieving this whole pan and zoom ability?

I am basically plotting a bunch of coordinates that came from a system where 0,0 is in the lower left corner and fall between the bounds:

xMin = 661208
xMax = 662618

yMin = 4291657
yMax = 4293285

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);

    Graphics2D g2 = (Graphics2D) g;

    double scale = details.getScale();
    double xOffset = details.getxOffset();
    double yOffset = details.getyOffset();

    g2.scale(scale, -scale);

    // Dividing offset by scale makes panning 1:1 with the cursor still. yMax to account for the
    // fact we needed to flip around the y axis to make it right-side up.
    g2.translate((-xMin + xOffset / scale), (-yMax + yOffset / scale));

    // Code to draw stuff goes here.  It uses coordinates between xMin-xMax and yMin-yMax to draw.
    .
    .
    .
}

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

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

发布评论

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

评论(1

就像说晚安 2024-08-12 21:31:46

这是一个带有轮子的示例:

 public class GraphicsOnly extends JPanel implements MouseWheelListener {
      Shape[] shapes;
      Dimension size;
      double scale = 1.0;
      private static int source = 100;
      public GraphicsOnly() {
        addMouseWheelListener(this);
        size = new Dimension(10,10);
        setBackground(new Color(240,200,200));
    }



    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                            RenderingHints.VALUE_ANTIALIAS_ON);
        if(shapes == null) initShapes();
        // Keep shapes centered on panel.
        double x = (getWidth()  - scale*size.width)/2;
        double y = (getHeight() - scale*size.height)/2;
        AffineTransform at = AffineTransform.getTranslateInstance(x, y);
        at.scale(scale, scale);
        g2.setPaint(Color.blue);
        g2.draw(at.createTransformedShape(shapes[0]));
        g2.setPaint(Color.green.darker());
        g2.draw(at.createTransformedShape(shapes[1]));
        g2.setPaint(new Color(240,240,200));
        g2.fill(at.createTransformedShape(shapes[2]));
        g2.setPaint(Color.red);
        g2.draw(at.createTransformedShape(shapes[2]));
    }

    public Dimension getPreferredSize() {
        int w = (int)(scale*size.width);
        int h = (int)(scale*size.height);
        return new Dimension(w, h);
    }

    private void initShapes() {
        shapes = new Shape[3];
        int w = getWidth();
        int h = getHeight();
        shapes[0] = new Rectangle2D.Double(w/16, h/16, w*7/8, h*7/8);
        shapes[1] = new Line2D.Double(w/16, h*15/16, w*15/16, h/16);
        shapes[2] = new Ellipse2D.Double(w/4, h/4, w/2, h/2);
        size.width = w;
        size.height = h;
    }


    public static void main(String[] args) {
        GraphicsOnly app = new GraphicsOnly();
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.getContentPane().add(new JScrollPane(app));
        f.setSize(400, 400);
        f.setLocation(200,200);
        f.setVisible(true);
    }

    @Override
    public void mouseWheelMoved(MouseWheelEvent e) {
        // TODO Auto-generated method stub
        if(e.getWheelRotation() >0){
            source = source-e.getScrollAmount();
        }else{
            source = source+e.getScrollAmount();
        }
        scale = source/100.0;
        System.out.println(scale);
        repaint();
        revalidate();
    }
}

Here is an example with the wheel:

 public class GraphicsOnly extends JPanel implements MouseWheelListener {
      Shape[] shapes;
      Dimension size;
      double scale = 1.0;
      private static int source = 100;
      public GraphicsOnly() {
        addMouseWheelListener(this);
        size = new Dimension(10,10);
        setBackground(new Color(240,200,200));
    }



    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                            RenderingHints.VALUE_ANTIALIAS_ON);
        if(shapes == null) initShapes();
        // Keep shapes centered on panel.
        double x = (getWidth()  - scale*size.width)/2;
        double y = (getHeight() - scale*size.height)/2;
        AffineTransform at = AffineTransform.getTranslateInstance(x, y);
        at.scale(scale, scale);
        g2.setPaint(Color.blue);
        g2.draw(at.createTransformedShape(shapes[0]));
        g2.setPaint(Color.green.darker());
        g2.draw(at.createTransformedShape(shapes[1]));
        g2.setPaint(new Color(240,240,200));
        g2.fill(at.createTransformedShape(shapes[2]));
        g2.setPaint(Color.red);
        g2.draw(at.createTransformedShape(shapes[2]));
    }

    public Dimension getPreferredSize() {
        int w = (int)(scale*size.width);
        int h = (int)(scale*size.height);
        return new Dimension(w, h);
    }

    private void initShapes() {
        shapes = new Shape[3];
        int w = getWidth();
        int h = getHeight();
        shapes[0] = new Rectangle2D.Double(w/16, h/16, w*7/8, h*7/8);
        shapes[1] = new Line2D.Double(w/16, h*15/16, w*15/16, h/16);
        shapes[2] = new Ellipse2D.Double(w/4, h/4, w/2, h/2);
        size.width = w;
        size.height = h;
    }


    public static void main(String[] args) {
        GraphicsOnly app = new GraphicsOnly();
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.getContentPane().add(new JScrollPane(app));
        f.setSize(400, 400);
        f.setLocation(200,200);
        f.setVisible(true);
    }

    @Override
    public void mouseWheelMoved(MouseWheelEvent e) {
        // TODO Auto-generated method stub
        if(e.getWheelRotation() >0){
            source = source-e.getScrollAmount();
        }else{
            source = source+e.getScrollAmount();
        }
        scale = source/100.0;
        System.out.println(scale);
        repaint();
        revalidate();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文