为了账号安全,请及时绑定邮箱和手机立即绑定

在 Java2D AWT Frame 中使用世界坐标

在 Java2D AWT Frame 中使用世界坐标

慕丝7291255 2022-07-27 21:35:42
我在尝试实现世界坐标到设备坐标的转换时被卡住了。基本上我想绘制以下世界坐标:    // --- World Coordinates    //    //                  (xmax,ymax)    //      ┌────────────────┐    //      │                │    //      │                │    //      │                │    //      │                │    //      └────────────────┘    // (xmin,ymin)    //    // (xmin,ymin) = (0, 100)    // (xmax,ymax) = (1.5, 2.5)在这本书(第 31 页)之后,我正在尝试实现从世界坐标视口移动到设备坐标视口所需的仿射变换。    // Introduction to Computer Graphics Using Java 2D and 3D     // Frank Klawonn, Ed. Springer 2008    // Page 31我准备了一个包含两个测试的测试类,第一个(刚刚设置int test = 1)测试前两个转换为翻转 Y 轴(原点位于屏幕左上角,而不是左下角)。该测试工作正常,绘制一个矩形和线条来显示这一点。但是,在切换到包含所有预期转换的测试 2 时,我得到一个空白屏幕:    // --- Affine Transform 1 and 2    //    //   T(0, h) ◦ S(1,−1)    //    // --- Affine Transform 3, 4 and 5    //       //                     ╭ umax − umin   vmax − vmin ╮    //   T(umin, vmin) ◦ S | ----------- , ----------- | ◦ T(-xmin, -ymin)      //                     ╰ xmax − xmin   ymax − ymin ╯    //
查看完整描述

1 回答

?
潇潇雨雨

TA贡献1833条经验 获得超4个赞

我查看了这本书,发现用法AffineTransform.preConcatenate()令人困惑。我更喜欢使用AffineTransform.concatenate(),因为对我来说这提供了更自然的流程。


让我们看第一个例子(变换,然后交换 y 方向)。


这是你的代码:


    AffineTransform at1 = new AffineTransform();

    at1.setToScale(1,-1);

    AffineTransform at2 = new AffineTransform();

    at2.setToTranslation(insFrame.left, sizeFrame.getHeight() - insFrame.bottom - 1);

    at1.preConcatenate(at2);

使用 using concatenate,您可以将其写为:


    AffineTransform at1 = new AffineTransform();

    at1.setToTranslation(insFrame.left, sizeFrame.getHeight() - insFrame.bottom - 1);

    AffineTransform at2 = new AffineTransform();

    at2.setToScale(1,-1);

    at1.concatenate(at2);

或者,甚至更短:


    AffineTransform at = new AffineTransform();

    at.translate(insFrame.left, sizeFrame.getHeight() - insFrame.bottom - 1);

    at.scale(1,-1);

您可以看到代码中直接表示的“翻译,然后缩放”流程。


对于第二个测试,您可以应用相同的方法:


    // Affine Transformation 3, 4 and 5

    //                   ╭ umax − umin   vmax − vmin ╮

    // T(umin, vmin) ◦ S | ----------- , ----------- | ◦ T(-xmin, -ymin)

    //                   ╰ xmax − xmin   ymax − ymin ╯

    AffineTransform at = new AffineTransform();

    at.translate(umin, vmin);

    at.scale((umax-umin)/(xmax-xmin), (vmax-vmin)/(ymax-ymin));

    at.translate(-xmin, -ymin);

注意这一点:umin, vmin已经表示左下屏幕坐标和umax, vmax右上屏幕坐标,所以不需要额外的平移或y轴翻转!

一些结束语:

  • Java2D 中线的默认宽度是一个缩放单位。选择yminymax后,一个缩放单位会填满窗口的整个高度。g2d.setStroke(new BasicStroke(0.0f));为了不只得到一个填充的矩形,您应该在调用之前将线宽设置为可能的最小值g2d.draw()

  • 的参数Rectangle2D.Double()x, y, w, h,因此您在第二个示例中创建矩形对象的代码可能应该读取Rectangle2D.Double rectangle = new Rectangle2D.Double(0, 1.5, 100, 1);(高度为 2.5,上边框不会显示在屏幕上)。


查看完整回答
反对 回复 2022-07-27
  • 1 回答
  • 0 关注
  • 104 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信