Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 333|回复: 0

[Swing学习]java Swing动态轮眼

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-11-12 23:57:14 | 显示全部楼层 |阅读模式
    效果图:

    /**
    * 设计声明:
    * 1、轮眼。
    * 2、由于本次设计包含过多数学计算,所以强烈建议您通过《注意事项》中的5查看图是如何设计的,先不要看源码,
    * 然后自己试图去设计,而您仅需要知道:计算机计算开方、三角函数、反三角等会造成误差,仅此而已。
    * 3、由于我本人在《动态中国太极图――java原创》中改了一个注释错误,导致《动态中国太极图――Java原创》
    * 不能再次通过系统的审批,不知何故,所以导致大家可能看不到《动态中国太极图――Java原创》里面详细
    * 的注释,深表遗憾。同时也对我自己没能认真做好本质工作表示深深的反思。
    * 4、如果您对这个很好奇,那么请现查阅本人发表的《动态中国太极图――Java原创》
    * 《动态眨眼效果――Java原创》,因为那两个是这个设计的引导+铺垫。
    *
    *
    * 注意事项:
    * 1、本程序为java程序,同时感谢您花费宝贵的时间来阅读本文档;
    * 2、请注意包名为:practice,文件名为:SharinganJFrame(Sharingan是写轮眼的英文),注意检查,
    * 以防一些不必要的麻烦;
    * 3、在完成确认2中的内容后,本程序可以直接运行,因为本软件说明都在注释中;
    * 4、由于本设计是继《动态中国太极图――Java原创》、《动态眨眼效果――Java原创》后编写,所以在那里
    * 面已说明的东西,不再详述,同时由于个人能力、阅历等原因,有些细节可能并没有详细阐述,或者
    * 有疏漏,请谅解。
    * 5、您可以注释paint()方法中的一些代码,因为效果很直观,也许这样您理解得更快,建议如下:
    * 5.1 先看paint()方法第1条语句效果,把paint()方法中的其它语句注释掉;
    * 5.2 再看paint()方法第1、2条语句效果,把paint()方法中的其它语句注释掉;
    * 5.3 再看paint()方法第1、2、3条语句效果,把paint()方法中的其它语句注释掉;
    * 5.4 以上面的方法类推,直到paint()方法中没有语句被注释,相信等您看完,您就理解了。
    *
    * 设计目标:在一个JFrame中绘制一个动态的写轮眼(动漫《火影》中的特殊眼睛)。
    *
    * 设计说明:
    * 相信很多人不喜欢看那些很长文字的说明,所以本人只简单介绍一下个人想法及遇到的一些问题:
    * 1、设计的源头来自我和同桌(程梦真)无意中提到写轮眼,所以打算把它用Java绘出来,而且要是动态的;
    * 2、目前的版本的写轮眼和最初设计的写轮眼有很大差别,很多单词的定义已经没有了当初的味道。
    * 3、绘制这个动态的写轮眼的时候遇到最严重的的问题是计算误差,就是苍老师说的精确但不准确,所以
    * angleErr是用来做误差补偿的,当然这个还是不是很准确,没有更深入的去探究,由于本来就是娱
    * 乐,所以没打算去深究,如果你感兴趣,想去琢磨,请注意一下angleErr所出现的地方,本人因为
    * 这个误差,重画了近3遍才找出根本原因。
    */

    1. import java.awt.Color;
    2. import java.awt.Graphics;
    3. import javax.swing.JFrame;
    4. public class SharinganJFrame extends JFrame {
    5.     //设置中心坐标,个人喜欢一种心点作为物体的坐标,物理里面成为质点
    6.     int centerX = 1024/2;
    7.     int centerY = 768/2;
    8.     //外圆半径,写轮眼转动所依赖的红线
    9.     double extendCircleSemi = 25;
    10.     //写轮眼的旋转部分有一个固定的大小的圆,刚开始设计的时候是定义为白色的,后来改为了红色,好看 ^_^
    11.     double whiteOfSharingan = extendCircleSemi/3;
    12.     //在上面的红色的圆旁边有一个随着旋转角度变大而变大的圆,其半径为miniCircleSemi
    13.     double miniCircleSemi = 0;
    14.     //这里用到了绘制太极时的思路,这个圆和上面的两个圆(whiteOfSharingan和miniCircleSemi)外切
    15.     double sharinganSemi = 0;
    16.     //旋转度角范围的变量,您可以通过观察旋转的循环角度是120*2
    17.     int angleCircle = 0;
    18.     //小圆(miniCircleSemi)和白圆(whiteOfSharingan)在外圆(extendCircleSemi)上的角度
    19.     double angleOfWhiteMini = 0;
    20.     //写轮眼沟玉圆(sharinganSemi)和白圆(whiteOfSharingan)在外圆(extendCircleSemi)的角度
    21.     double angleOfwhiteShar = 0;
    22.     //用于判断圆是否到达极限位置,还句话说就是是否到达了正确的角度,进行下一次循环
    23.     boolean flag = true;
    24.     //沟玉球心到弦(whiteOfSharingan圆中心和miniCircleSemi圆中心所连成的线)中心距离;
    25.     double distansOfWhiteShar =0;
    26.     //沟玉球心到中心点的距离,这一步主要是为了计算坐标
    27.     double distansOfSharSemi = 0;
    28.     //在绘图过程中,由于计算机计算开方、三角函数、反三角等造成了误差,这是一个补偿值,但要注意真正补偿的
    29.     //误差为这个误差的angleErr*2/3,因为这个值是本人通过理想设置临界状态得到的值。
    30.     double angleErr = 0.02500260489936114;
    31.     //沟玉球(whiteOfSharingan)中的黑球半径,这个值是动态的
    32.     int blackOfWhiteSemi = 0;
    33.     //中心眼睛所占的长度
    34.     int eyeLength = 300;
    35.     //眼睛幅值
    36.     int amplitude = 50;
    37.                                     
    38.     public SharinganJFrame() {
    39.         this.setTitle("Sharingan");
    40.         this.setSize(centerX*2, centerY*2);
    41.         this.getContentPane().setBackground(Color.black);
    42.         startRun();
    43.         this.setVisible(true);
    44.     }
    45.                                     
    46.     @Override
    47.     public void paint(Graphics graphics) {
    48.         super.paint(graphics);
    49.         //绘制一个眼睛作为背景
    50.         graphics.setColor(Color.red);
    51.         for (int i = 0; i < eyeLength; i++) {
    52.             graphics.drawLine(centerX-eyeLength/2+i,
    53.                 centerY-(int)(Math.sin(Math.PI*i/eyeLength)*amplitude),
    54.                 centerX-eyeLength/2+i,
    55.                 centerY+(int)(Math.sin(Math.PI*i/eyeLength)*amplitude));
    56.         }
    57.         //在眼睛的中心绘制一个黑色的圆
    58.         graphics.setColor(Color.black);
    59.         graphics.fillOval(centerX-90/2,centerY-90/2,90,90);
    60.         //在眼睛的中心绘制一个白色的圆
    61.         graphics.setColor(Color.white);
    62.         graphics.fillOval(centerX-60/2/2/2,centerY-60/2/2/2,60/2/2,60/2/2);
    63.         //用于绘制3个不同角度、在不断变化、不同位置的太极图,图是有顺序的
    64.         for (int i = 0; i < 3; i++) {
    65.          //绘制写轮眼球(sharinganSemi)
    66.          graphics.setColor(Color.red);
    67.    graphics.fillArc((int)(centerX-sharinganSemi+Math.cos(Math.PI*(angleCircle+90+(i*120))/180-angleOfWhiteMini/2+
    68.                angleOfwhiteShar+angleErr*2/3)*distansOfSharSemi),
    69.                (int)(centerY-sharinganSemi-Math.sin(Math.PI*(angleCircle+90+(i*120))/180-angleOfWhiteMini/2+
    70.                  angleOfwhiteShar+angleErr*2/3)*distansOfSharSemi),
    71.                (int)(sharinganSemi*2),
    72.                (int)(sharinganSemi*2),angleCircle+i*120,180);
    73.             //绘制写轮眼固定圆(whiteOfSharingan)
    74.             graphics.setColor(Color.red);
    75.             graphics.fillOval((int)(centerX-whiteOfSharingan+Math.cos(Math.PI*(angleCircle+90+
    76.                 (i*120))/180)*extendCircleSemi),
    77.               (int)(centerY-whiteOfSharingan-Math.sin(Math.PI*(angleCircle+90+(i*120))/180)*extendCircleSemi),
    78.               (int)(whiteOfSharingan*2),
    79.               (int)(whiteOfSharingan*2));
    80.             //绘制写轮眼黑球(miniCircleSemi)
    81.             graphics.setColor(Color.black);
    82.             graphics.fillOval((int)(centerX-miniCircleSemi+Math.cos(Math.PI*(angleCircle+90+
    83.                 (i*120))/180-angleOfWhiteMini)*extendCircleSemi),
    84.              (int)(centerY-miniCircleSemi-Math.sin(Math.PI*(angleCircle+90+
    85.                (i*120))/180-angleOfWhiteMini)*extendCircleSemi),
    86.              (int)(miniCircleSemi*2),
    87.              (int)(miniCircleSemi*2));
    88.             //绘制写轮眼固定球内黑球(blackOfWhiteSemi)
    89.             graphics.setColor(Color.black);
    90.             graphics.fillOval((int)(centerX-(blackOfWhiteSemi+0.0)/120*whiteOfSharingan/2+
    91.                  Math.cos(Math.PI*(angleCircle+90+(i*120))/180)*extendCircleSemi),
    92.              (int)(centerY-(blackOfWhiteSemi+0.0)/120*whiteOfSharingan/2-Math.sin(Math.PI*(angleCircle+90+
    93.                 (i*120))/180)*extendCircleSemi),
    94.              (int)((blackOfWhiteSemi+0.0)/120*whiteOfSharingan),
    95.              (int)((blackOfWhiteSemi+0.0)/120*whiteOfSharingan));
    96.         }
    97.         //绘制外圆
    98.             graphics.setColor(Color.red);
    99.             graphics.drawOval(    (int)(centerX-extendCircleSemi),
    100.                                 (int)(centerY-extendCircleSemi),
    101.                                 (int)(extendCircleSemi)*2,
    102.                                 (int)(extendCircleSemi)*2);
    103.     }
    104.     public void startRun() {
    105.       new Thread(){
    106.         public void run() {
    107.           while(true){
    108.            if (flag) {
    109.             angleCircle += 2 ;
    110.             //沟玉白球中的黑球半径
    111.             blackOfWhiteSemi = angleCircle;
    112.             //System.out.println(angleCircle);
    113.            //根据目前写轮眼沟玉球转过角度来确定mini小球目前的对应的半径
    114.             miniCircleSemi = (angleCircle+0.0)/120*whiteOfSharingan;
    115.             //System.out.println(miniCircleSemi);
    116.            //沟玉球半径
    117.            sharinganSemi = miniCircleSemi+whiteOfSharingan;
    118.            //System.out.println(sharinganSemi);
    119.            //由于白球和mini小球都是在外圆上,所以通过弦对应的角度来求的小圆落后于白球的角度
    120.             angleOfWhiteMini = Math.asin(sharinganSemi/2/extendCircleSemi)*2;
    121.            //System.out.println(angleOfWhiteMini);
    122.            //沟玉球心到白球中心距离
    123.            distansOfWhiteShar = (whiteOfSharingan-miniCircleSemi)/2;
    124.            //沟玉球心到中心点的距离
    125.            distansOfSharSemi = Math.sqrt(extendCircleSemi*extendCircleSemi
    126.              -((whiteOfSharingan+miniCircleSemi)/2)*((whiteOfSharingan+miniCircleSemi)/2)
    127.             +((whiteOfSharingan-miniCircleSemi)/2)*((whiteOfSharingan-miniCircleSemi)/2));
    128.           //沟玉球心和白求在中心圆上所成的角度
    129.           //通过这里可以可以求出由于计算机计算产生的计算误差为(0.02500260489936114)
    130.           //System.out.println(distansOfSharSemi);
    131.           angleOfwhiteShar = Math.asin(distansOfWhiteShar/2/distansOfSharSemi);
    132.           //System.out.println(angleOfwhiteShar);
    133.           if (angleCircle == 120) {
    134.             flag = false;
    135.           }
    136.           }else {
    137.             angleCircle += 2;
    138.             //沟玉白球中的黑球半径
    139.             blackOfWhiteSemi = 240-angleCircle;
    140.            //根据目前写轮眼沟玉球转过角度来确定mini小球目前的对应的半径
    141.            miniCircleSemi = (240.0-angleCircle)/120*whiteOfSharingan;
    142.           //miniCircleSemi = (angleCircle+0.0)/120*whiteOfSharingan;
    143.           //沟玉球半径
    144.           sharinganSemi = miniCircleSemi+whiteOfSharingan;
    145.           //由于白球和mini小球都是在外圆上,所以通过弦对应的角度来求的小圆落后于白球的角度
    146.           angleOfWhiteMini = Math.asin(sharinganSemi/2/extendCircleSemi)*2;
    147.           //沟玉球心到白球中心距离
    148.           distansOfWhiteShar = (whiteOfSharingan-miniCircleSemi)/2;
    149.           //沟玉球心到中心点的距离
    150.           distansOfSharSemi = Math.sqrt(extendCircleSemi*extendCircleSemi
    151.             -((whiteOfSharingan+miniCircleSemi)/2)*((whiteOfSharingan+miniCircleSemi)/2)
    152.            +((whiteOfSharingan-miniCircleSemi)/2)*((whiteOfSharingan-miniCircleSemi)/2));
    153.         //沟玉球心和白求在中心圆上所成的角度
    154.         angleOfwhiteShar = Math.asin(distansOfWhiteShar/2/distansOfSharSemi);
    155.         if (angleCircle == 240) {
    156.           angleCircle = 0;
    157.           flag = true;
    158.         }
    159.       }
    160.       try {
    161.          Thread.sleep(20);
    162.       } catch (InterruptedException e) {
    163.          e.printStackTrace();
    164.      }
    165.         repaint();      
    166.      }
    167.    };
    168.     }.start();
    169.    }
    170.    public static void main(String[] args) {
    171.         new SharinganJFrame();
    172.     }
    173. }
    复制代码

       
         
         
          
          

            
          

            
          
         
       

      


    源码下载:http://file.javaxxz.com/2014/11/12/235713890.zip
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-25 08:30 , Processed in 0.299181 second(s), 36 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表