旋转后图像不在正确的位置(图形)

2023-12-02

我试图以不同的速率显示两个直径为 512untis 的旋转轮,但我无法删除以前绘制的图像图形并将旋转的图形设置在正确的位置。 现在我正在以任意角度进行旋转。 我尝试了 affineTransform 并获得了旋转,但很奇怪,就像所有像素都散开一样。 我将 while 循环与 thread.sleep() 一起使用。以下是代码: //drawSmallCircle和drawBigCircle返回两个图像。

class MyFramePart2 extends JFrame

{ 

    String name;
    JPanel big_obj_panel,small_obj_panel;    
    JLabel bigLabel,smallLabel;BufferedImage imgRet,imgRetSmall;
    static double radians,angle,rev,fps,smallAngle,smallRadians;               
    int numLines,i=0;    

    MyFramePart2(String frameName,int numStrokes,double revolutions,double frameps)
    {       
        numLines=numStrokes;
        smallAngle=smallRadians=angle=radians=Math.toRadians(360/numLines);        
        rev=revolutions;
        fps=frameps; 

        setSize(1240,720);       
        setLocation(0,0);
        setLayout(null); 
        getContentPane().setBackground(Color.WHITE);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

        big_obj_panel=new JPanel();
        big_obj_panel.setLayout(null);
        big_obj_panel.setSize(512,512);
        big_obj_panel.setLocation(100,100); 
        big_obj_panel.setBackground(Color.white);
        add(big_obj_panel);   


        imgRet=drawBigCircle();
        bigLabel = new JLabel(new ImageIcon(imgRet));
        bigLabel.setLayout(null);        
        bigLabel.setLocation(0,0);
        bigLabel.setSize(512,512);
        bigLabel.setOpaque(true);
        bigLabel.setBackground(Color.white);  
        big_obj_panel.add(bigLabel);

        small_obj_panel=new JPanel();
        small_obj_panel.setLayout(null);
        small_obj_panel.setSize(512,512);
        small_obj_panel.setLocation(700,100); 
        small_obj_panel.setBackground(Color.white);
        add(small_obj_panel);   

        imgRetSmall=drawSmallCircle();

        smallLabel = new JLabel(new ImageIcon(imgRetSmall));
        smallLabel.setLayout(null);        
        smallLabel.setLocation(0,0);
        smallLabel.setSize(512,512);
        smallLabel.setOpaque(true);
        smallLabel.setBackground(Color.white);  
        small_obj_panel.add(smallLabel);

        setVisible(true);               

        while(i!=5) // suppose to be while true, just checking 
      {                 
        setVisible(true);          
        bigLabel.setIcon(new ImageIcon(imgRet));         
        smallLabel.setIcon(new ImageIcon(imgRetSmall));
        try{
        Thread.sleep(10);        
        }
        catch(Exception e)
        {}
        i++;               
     }                         
 }

    @Override
    public void paint(Graphics g)
    {        
        super.paint(g);
        Graphics2D g2d=(Graphics2D)g;           
        g2d.translate(256,256);
        g2d.rotate(Math.toRadians(20));                       
        g2d.translate(-256,-256); 
        g2d.drawImage(imgRet,0,0,null);
        g2d.dispose();        

        super.paint(g);
        g2d=(Graphics2D)g;
        g2d.translate(256,256);
        g2d.rotate(Math.toRadians(30));
        g2d.translate(-256,-256);        
        g2d.drawImage(imgRetSmall,0,0,null);        
        g2d.dispose();
    }

    public static BufferedImage drawBigCircle()
    {
        BufferedImage img=new BufferedImage(512,512,BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d=img.createGraphics();                
        g2d.setColor(Color.black);
        g2d.drawOval(0,0,511,511);

        Line2D l2d;
        while(angle <= 2*Math.PI)
        {
            l2d=new Line2D.Double(256,256,256+256*Math.cos(angle),256+256*Math.sin(angle));
            g2d.draw(l2d);
            angle=angle+radians;
        }               
        return img;
    }        
}

Swing 的第一条规则。不要阻塞事件调度线程。这样做会使您的应用程序看起来像是挂起的,并阻止 EDT 处理任何重绘请求。

这意味着,您需要某种方法来安排更新而不阻止 EDT

Swing 的第二条规则。不要从 EDT 之外的任何线程创建或修改任何 UI 组件。

一般来说,您应该避免覆盖paint顶级容器的方法,例如JFrame,除了其他一切之外,它们不是双缓冲的,这意味着您的绘画在更新时会闪烁。相反,您应该使用其中之一Swing容器,例如JPanel

有很多不同的方法可以实现这一目标。基本上,这里我使用了三个列表,但如果我认真的话,我会创建一个可以维护所有所需信息(图像、角度和增量)的对象

为了实现实际的动画,我使用了javax.swing.Timer。这将至少每隔一段时间触发一个事件n周期,但更重要的是,它是在事件调度线程的上下文中执行的。这确保了对角度所做的所有更改都以防止在我们更新值时发生任何绘画的可能性......

此示例以不同(随机)速度旋转三个图像......

enter image description here

public class TestRotation {

    public static void main(String[] args) {
        new TestRotation();
    }

    public TestRotation() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new AnimationPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }

        });
    }

    public class AnimationPane extends JPanel {

        private List<BufferedImage> images;
        private List<Double> angles;
        private List<Double> speed;

        public AnimationPane() {
            images = new ArrayList<>(5);
            images.add(createWheel(50, 4));
            images.add(createWheel(50, 3));
            images.add(createWheel(50, 6));
            angles = new ArrayList<>();
            speed = new ArrayList<>();
            for (int index = 0; index < images.size(); index++) {
                angles.add(0d);
                speed.add(Math.random() * 5d);
            }

            Timer timer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    for (int index = 0; index < angles.size(); index++) {
                        double angle = angles.get(index);
                        double delta = speed.get(index);
                        angle += delta;
                        angles.set(index, angle);
                    }
                    repaint();
                }
            });
            timer.setRepeats(true);
            timer.setCoalesce(true);
            timer.start();

        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            int x = 0;
            int y = 0;
            for (int index = 0; index < images.size(); index++) {
                BufferedImage image = images.get(index);
                double angle = angles.get(index);

                // This is important.  Basically we going to grab a isolated snap shot
                // of the current graphics context.  This means any changes we make
                // will not affect the original graphics context (other then painting)
                Graphics2D g2d = (Graphics2D) g.create();
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                AffineTransform at = new AffineTransform();
                at.translate(x, y);
                at.rotate(Math.toRadians(angle), image.getWidth() / 2, image.getHeight() / 2);
                g2d.setTransform(at);
                g2d.drawImage(image, 0, 0, this);
                g2d.dispose();

                x += image.getWidth();

            }
        }

    }

    protected Point2D calculateOutterPoint(int radius, double angel) {

        int x = Math.round(radius / 2);
        int y = Math.round(radius / 2);

        double rads = Math.toRadians((angel + 90));

        // This determins the length of tick as calculate from the center of
        // the circle.  The original code from which this derived allowed
        // for a varible length line from the center of the cirlce, we
        // actually want the opposite, so we calculate the outter limit first
        double fullLength = (radius / 2d);

        // Calculate the outter point of the line
        double xPosy = (x + Math.cos(rads) * fullLength);
        double yPosy = (y - Math.sin(rads) * fullLength);

        return new Point2D.Double(xPosy, yPosy);

    }

    public BufferedImage createWheel(int radius, int spokes) {
        BufferedImage img = new BufferedImage(radius, radius, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = img.createGraphics();
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setColor(Color.black);
        g2d.drawOval(0, 0, radius - 1, radius - 1);

        Point2D center = new Point2D.Double(radius / 2d, radius / 2d);
        double angle = 360d / spokes;
        for (int index = 0; index < spokes; index++) {
            Point2D p = calculateOutterPoint(radius, index * angle);
            g2d.draw(new Line2D.Double(center, p));
        }

        g2d.dispose();
        return img;

    }

}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

旋转后图像不在正确的位置(图形) 的相关文章

  • NoInitialContextException:heroku 战争部署

    我一直在开发一个 J2EE 项目 并且在其中使用连接池 也通过部署在 heroku 上的数据库进行访问 我使用以下代码来设置 Connection 对象 Context initContext new InitialContext Cont
  • “java.io.IOException:连接超时”和“SocketTimeoutException:读取超时”之间有什么区别

    如果我设置一个套接字 SoTimeout 并从中读取 当读取时间超过超时限制时 我会收到 SocketTimeoutException 读取超时 这是我的例子中的堆栈 java net SocketTimeoutException Read
  • Java 7 默认语言环境

    我刚刚安装了 jre7 我很惊讶地发现我的默认区域设置现在是 en US 对于jre6 它是de CH 与jre7有什么不同 默认区域设置不再是操作系统之一吗 顺便说一句 我使用的是Windows7 谢谢你的回答 编辑 我已经看到了语言环境
  • 当路径的点超出视野时,Android Canvas 不会绘制路径

    我在绘制路径时遇到了 Android Canvas 的一些问题 我的情况是 我有一个相对布局工作 如地图视图 不使用 google api 或类似的东西 我必须在该视图上绘制一条路径 canvas drawPath polyPath bor
  • Base36 编码字符串?

    我一直在网上查找 但找不到解决此问题的方法 在 Python Ruby 或 Java 中 如何对以下字符串进行 Base 36 编码 nOrG9Eh0uyeilM8Nnu5pTywj3935kW 5 Ruby 以 36 为基数 s unpa
  • (Java) App Engine 中的静态文件无法访问

    The 示例文档 http code google com appengine docs java gettingstarted staticfiles html表示您只需将文件放在 war 或子目录 中 并且应该可以从主机访问它们 只要它
  • 将SQL数据引入jquery availabletag

    我正在尝试制作自动完成文本框 但如何将 SQL 数据包含到 jquery 可用标记并循环它 我无法根据以下代码执行该功能 任何帮助 将不胜感激 谢谢 这是我的预期输出 预期结果演示 http jsfiddle net VvETA 71 jq
  • 删除优先级队列的尾部元素

    如何删除优先级队列的尾部元素 我正在尝试使用优先级队列实现波束搜索 一旦优先级队列已满 我想删除最后一个元素 优先级最低的元素 Thanks 没有简单的方法 将元素从原始元素复制到新元素 最后一个除外 PriorityQueue remov
  • 您建议使用哪种压缩(GZIP 是最流行的)servlet 过滤器?

    我正在寻找一个用于大容量网络应用程序的 GZIP servlet 过滤器 我不想使用容器特定的选项 要求 能够压缩响应负载 XML Faster 已在大批量应用的生产中得到验证 应适当设置适当内容编码 跨容器移植 可选择解压缩请求 谢谢 我
  • Java中的断点和逐步调试?

    抱歉我的问题名称很奇怪 我不知道如何寻找这个 因为我不知道这些东西是如何称呼的 Visual Studio 中至少有一个功能 您可以单击代码左侧并设置一个大红点的起点 然后运行程序 您可以通过按 f8 或 f5 实际上是不同的 f 来跟踪步
  • 从直方图计算平均值和百分位数?

    我编写了一个计时器 可以测量任何多线程应用程序中特定代码的性能 在下面的计时器中 它还会在地图中填充花费了 x 毫秒的调用次数 我将使用这张图作为我的直方图的一部分来进行进一步的分析 例如调用花费了这么多毫秒的百分比等等 public st
  • 添加到列表时有没有办法避免循环?

    我想知道这样的代码 List
  • 通过 appassembler-maven-plugin 生成的脚本无法在 Spring Boot 应用程序中找到主类

    我使用 appassembler maven plugin 生成的启动脚本有问题 我有一个基本的 spring boot 应用程序 只有一个类 SpringBootApplication public class ScriptDemoApp
  • 用于缓存的 Servlet 过滤器

    我正在创建一个用于缓存的 servlet 过滤器 这个想法是将响应主体缓存到memcached 响应正文由以下方式生成 结果是一个字符串 response getWriter print result 我的问题是 由于响应正文将不加修改地放
  • 如何停止执行的 Jar 文件

    这感觉像是一个愚蠢的问题 但我似乎无法弄清楚 当我在 Windows 上运行 jar 文件时 它不会出现在任务管理器进程中 我怎样才能终止它 我已经尝试过 TASKKILL 但它对我也不起作用 On Linux ps ef grep jav
  • 避免 Java 中的重复导入:继承导入?

    有没有办法 继承 导入 Example 常见枚举 public enum Constant ONE TWO THREE 使用此枚举的基类 public class Base protected void register Constant
  • 无需登录即可直接从 Alfresco 访问文件/内容

    我的场景是这样的 我有一个使用 ALFRESCO CMS 来显示文件或图像的 Web 应用程序 我正在做的是在 Java servlet 中使用用户名和密码登录 alfresco 并且我可以获得该登录的票证 但我无法使用该票证直接从浏览器访
  • Hadoop NoSuchMethodError apache.commons.cli

    我在用着hadoop 2 7 2我用 IntelliJ 做了一个 MapReduce 工作 在我的工作中 我正在使用apache commons cli 1 3 1我把库放在罐子里 当我在 Hadoop 集群上使用 MapReduceJob
  • ECDH使用Android KeyStore生成私钥

    我正在尝试使用 Android KeyStore Provider 生成的私有文件在 Android 中实现 ECDH public byte ecdh PublicKey otherPubKey throws Exception try
  • Java 的 PriorityQueue 与最小堆有何不同?

    他们为什么命名PriorityQueue如果你不能插入优先级 它看起来与堆非常相似 有什么区别吗 如果没有区别那为什么叫它PriorityQueue而不是堆 默认的PriorityQueue是用Min Heap实现的 即栈顶元素是堆中最小的

随机推荐

  • 二叉搜索树中的有序后继者

    给定 BST 中的一个节点 如何找到下一个更高的密钥 一般方法取决于节点中是否有父链接 如果您存储父链接 然后你选择 如果当前节点有右子节点 则为右子节点的最左子节点 如果右孩子没有左孩子 那么右孩子就是你的顺序继承人 向上导航父祖先节点
  • 如何将数据聚合到范围(分桶)?

    我有一张像这样的桌子 id value 1 118 0 2 109 0 3 113 0 4 82 0 5 60 0 6 111 0 7 107 0 8 84 0 9 91 0 10 118 0
  • 寻求以更干净/更有效的方式将字符串与整数相关联

    我该如何改进这个 这种关系是一对一的并且在 1 5 上连续 所以我正在考虑使用枚举 但我不确定如何将字符串值与枚举值进行比较 如果有更好的方法可以做到这一点 请建议 Thanks private int evaluateWord Strin
  • Firebase 功能部署失败

    每当我部署 firebase 函数时 我都会收到以下错误 错误 解析函数触发器时发生错误 Error ERR PACKAGE PATH NOT EXPORTED No exports main defined in D Proyectos
  • 为什么 for(;;) 而不是 while(1) ? [复制]

    这个问题在这里已经有答案了 可能的重复 for 比 while TRUE 快吗 如果没有 人们为什么要使用它 为什么要用丑的for 语法而不是看起来稍微好一点的while true loop 没有什么优势可以for over while 1
  • 正则表达式匹配长度超过 5 个字符且具有两个连续数字的密码

    这就是我所拥有的 有人可以告诉我哪里错了吗 let sampleWord bana12 let pwRegex w 5 d 2 Change this line let result pwRegex test sampleWord cons
  • DexArchiveMergerException:无法合并 dex

    昨天从 2 3 3 版本更新 Android studio 3 0 后 我遇到了与 DexMergerException 相关的问题 其他人也发布了相关问题this 但在这个问题中 我想分析堆栈跟踪以找到相关的解决方案 因为我是这里的新手
  • 使用 excel 插件注册带有参数描述的 UDF

    我有一个带有 UDF 的插件getRegExResult 我想向该函数添加函数描述和参数描述 因此当用户安装插件 关闭 打开 Excel 几次并进入 插入函数 对话框时 他将能够找到带有参数描述的函数 同样被问到here 我找到了一个ans
  • JSF:使用 Icefaces 组件上传文件的问题

    我想得到FileUpload与 Icefaces 配合使用的功能ace 文件条目 but my fileUploadListener服务器上未调用 代码如下 xhtml 片段
  • 在Python中循环压缩列表

    我正在研究 python 中的 zip 函数 并在使用 for 循环时发现了一个问题 这是我的代码 list1 monday tuesday wednesday thursday list2 1 2 3 4 zipped list zip
  • Excel VBA:批量重命名工作表

    有没有办法在VBA中批量重命名工作表 就像是 sheets array 1 2 3 name array hep hey heppa 将工作表 1 2 3 命名为 hep hey 和 heppa 显然它不能直接工作 和一些实验选定的表不要带
  • 发送 QUERY 数据包时出错

    我试图将一些数据插入数据库 但出现此错误 发送 QUERY 数据包时出错 insertDeta conPat gt prepare insert into table1 data VALUES data insertDeta gt bind
  • 如何使用 postgres 将时间间隔转换为小时数?

    假设我有一个像这样的间隔 4 days 10 00 00 在 postgres 中 我如何将其转换为小时数 在本例中为 106 是否有函数或者我应该硬着头皮做类似的事情 extract days my interval 24 extract
  • 使用 NHibernate ISqlExceptionConverter 自定义异常

    我需要为 NHibernate 方言注册自定义异常 我已经实施并 注册了 ISqlExceptionConverter 如 NHibernate 测试中所示 但 当代码中抛出异常时 它不会被转换 我的转换代码 甚至不打电话 我的代码非常简单
  • 如何演示 sigma(i/2^i)<=2(i=1 到 n)

    如何证明以下不等式 sigma i 2 i lt 2 i 1 to n 如果我们看一下series然后它看起来像 我们认为总和的最大值为 n 无穷大 S 1 2 2 4 3 8 4 16 5 32 0 1 清楚地 S 2 1 4 2 8 3
  • Bootstrap下拉菜单点击后消失

    div class container div class dropdown col xs 8 div div
  • Jquery 如何使用美元符号? [复制]

    这个问题在这里已经有答案了 可能的重复 javascript中 符号的含义是什么 如果 Jquery 只是外部 javascript 代码 那么它如何使用美元符号 这不是要添加新的语法吗 只是一个普通变量 你可以做var 42
  • Android 11 (R) 中捕获和裁剪图像

    根据 android R 隐私政策的变化 我想为 android R 设备执行捕获和裁剪图像功能 我尝试了下面的方法 但它保存了空文件 文件正在指定文件夹中创建 但大小为 0kb 我在用着Android 图像裁剪器库来裁剪图像 public
  • 如何在 Vuejs 渲染函数中复制插槽?

    我有一个通过插槽传递内容的组件 我正在使用渲染函数来输出内容 我使用渲染函数的原因是因为我想多次复制内容 当我使用这段代码时 一切正常 render createElement return createElement div this s
  • 旋转后图像不在正确的位置(图形)

    我试图以不同的速率显示两个直径为 512untis 的旋转轮 但我无法删除以前绘制的图像图形并将旋转的图形设置在正确的位置 现在我正在以任意角度进行旋转 我尝试了 affineTransform 并获得了旋转 但很奇怪 就像所有像素都散开一