Java 动态写轮眼 SharinganJPanel (整理)
生活随笔
收集整理的這篇文章主要介紹了
Java 动态写轮眼 SharinganJPanel (整理)
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
? 1 /**
2 * Java 動(dòng)態(tài)寫輪眼 SharingganJPanel (整理)
3 *
4 * 2016-1-2 深圳 南山平山村 曾劍鋒
5 * 設(shè)計(jì)聲明:
6 * 1、雖然岸本是日本人,而我個(gè)人作為其模仿者,依然想表示個(gè)人對(duì)其的敬意,希望作品
7 * 不會(huì)玷污寫輪眼的名聲。
8 * 2、由于本次設(shè)計(jì)包含過(guò)多數(shù)學(xué)計(jì)算,所以強(qiáng)烈建議您通過(guò)《注意事項(xiàng)》中的5查看圖是
9 * 如何設(shè)計(jì)的,先不要看源碼,然后自己試圖去設(shè)計(jì),而您僅需要知道:計(jì)算機(jī)計(jì)算
10 * 開(kāi)方、三角函數(shù)、反三角等會(huì)造成誤差,僅此而已。
11 * 3、由于我本人在《動(dòng)態(tài)中國(guó)太極圖——Java原創(chuàng)》中改了一個(gè)注釋錯(cuò)誤,導(dǎo)致《動(dòng)態(tài)中國(guó)
12 * 太極圖——Java原創(chuàng)》不能再次通過(guò)系統(tǒng)的審批,不知何故,所以導(dǎo)致大家可能看不
13 * 到《動(dòng)態(tài)中國(guó)太極圖——Java原創(chuàng)》里面詳細(xì)的注釋,深表遺憾。同時(shí)也對(duì)我自己沒(méi)
14 * 能認(rèn)真做好本質(zhì)工作表示深深的反思。
15 * 4、如果您對(duì)這個(gè)很好奇,那么請(qǐng)現(xiàn)查閱本人發(fā)表的《動(dòng)態(tài)中國(guó)太極圖——Java原創(chuàng)》(不
16 * 知道還能不能通過(guò)審批)、《動(dòng)態(tài)眨眼效果——Java原創(chuàng)》,因?yàn)槟莾蓚€(gè)是這個(gè)設(shè)計(jì)
17 * 的引導(dǎo)+鋪墊。
18 *
19 *
20 * 注意事項(xiàng):
21 * 1、本程序?yàn)閖ava程序,同時(shí)感謝您花費(fèi)寶貴的時(shí)間來(lái)閱讀本文檔;
22 * 2、請(qǐng)注意包名為:practice,文件名為:SharinganJFrame(Sharingan是寫輪眼的英文),
23 * 注意檢查,以防一些不必要的麻煩;
24 * 3、在完成確認(rèn)2中的內(nèi)容后,本程序可以直接運(yùn)行,因?yàn)楸拒浖f(shuō)明都在注釋中;
25 * 4、由于本設(shè)計(jì)是繼《動(dòng)態(tài)中國(guó)太極圖——Java原創(chuàng)》、《動(dòng)態(tài)眨眼效果——Java原創(chuàng)》后編
26 * 寫,所以在那里面已說(shuō)明的東西,不再詳述,同時(shí)由于個(gè)人能力、閱歷等原因,有
27 * 些細(xì)節(jié)可能并沒(méi)有詳細(xì)闡述,或者有疏漏,請(qǐng)諒解。
28 * 5、您可以注釋paint()方法中的一些代碼,因?yàn)樾Ч苤庇^,也許這樣您理解得更快,
29 建議如下:
30 * 5.1 先看paint()方法第1條語(yǔ)句效果,把paint()方法中的其它語(yǔ)句注釋掉;
31 * 5.2 再看paint()方法第1、2條語(yǔ)句效果,把paint()方法中的其它語(yǔ)句注釋掉;
32 * 5.3 再看paint()方法第1、2、3條語(yǔ)句效果,把paint()方法中的其它語(yǔ)句注釋掉;
33 * 5.4 以上面的方法類推,直到paint()方法中沒(méi)有語(yǔ)句被注釋,相信等您看完,您就
34 * 理解了。
35 *
36 * 設(shè)計(jì)目標(biāo):在一個(gè)JFrame中繪制一個(gè)動(dòng)態(tài)的寫輪眼(動(dòng)漫《火影》中的特殊眼睛)。
37 *
38 * 設(shè)計(jì)說(shuō)明:
39 * 相信很多人不喜歡看那些很長(zhǎng)文字的說(shuō)明,所以本人只簡(jiǎn)單介紹一下個(gè)人想法及遇到的一
40 * 些問(wèn)題:
41 * 1、設(shè)計(jì)的源頭來(lái)自我和同桌(程夢(mèng)真)無(wú)意中提到寫輪眼,所以打算把它用Java繪出來(lái),
42 * 而且要是動(dòng)態(tài)的;
43 * 2、目前的版本的寫輪眼和最初設(shè)計(jì)的寫輪眼有很大差別,很多單詞的定義已經(jīng)沒(méi)有了
44 * 當(dāng)初的味道。
45 * 3、繪制這個(gè)動(dòng)態(tài)的寫輪眼的時(shí)候遇到最嚴(yán)重的的問(wèn)題是計(jì)算誤差,就是蒼老師說(shuō)的
46 * 精確但不準(zhǔn)確,所以angleErr是用來(lái)做誤差補(bǔ)償?shù)?#xff0c;當(dāng)然這個(gè)還是不是很準(zhǔn)確,沒(méi)
47 * 有更深入的去探究,由于本來(lái)就是娛樂(lè),所以沒(méi)打算去深究,如果你感興趣,想去
48 * 琢磨,請(qǐng)注意一下angleErr所出現(xiàn)的地方,本人因?yàn)檫@個(gè)誤差,重畫(huà)了進(jìn)3遍才找
49 * 出根本原因。
50 *
51 * 2014-1-13 星期一 晴 8度 微風(fēng) 南昌
52 *
53 */
54 package demo;
55
56 import java.awt.Color;
57 import java.awt.Graphics;
58
59 import javax.swing.JFrame;
60 import javax.swing.JPanel;
61
62 public class SharinganJPanel extends JPanel {
63 //設(shè)置中心坐標(biāo),個(gè)人喜歡一種心點(diǎn)作為物體的坐標(biāo),物理里面成為質(zhì)點(diǎn)
64 static int centerX = 600/2;
65 static int centerY = 600/2;
66 //外圓半徑,寫輪眼轉(zhuǎn)動(dòng)所依賴的紅線
67 double extendCircleSemi = 25; // double extendCircleSemi = 200;
68 //寫輪眼的旋轉(zhuǎn)部分有一個(gè)固定的大小的圓,剛開(kāi)始設(shè)計(jì)的時(shí)候是定義為白色的,后來(lái)改為了紅色,好看 ^_^
69 double whiteOfSharingan = extendCircleSemi/3; // double whiteOfSharingan = extendCircleSemi/6;
70 //在上面的紅色的圓旁邊有一個(gè)隨著旋轉(zhuǎn)角度變大而變大的圓,其半徑為miniCircleSemi
71 double miniCircleSemi = 0;
72 //這里用到了繪制太極時(shí)的思路,這個(gè)圓和上面的兩個(gè)圓(whiteOfSharingan和miniCircleSemi)外切
73 double sharinganSemi = 0;
74 //旋轉(zhuǎn)度角范圍的變量,您可以通過(guò)觀察旋轉(zhuǎn)的循環(huán)角度是120*2
75 int angleCircle = 0;
76 //小圓(miniCircleSemi)和白圓(whiteOfSharingan)在外圓(extendCircleSemi)上的角度
77 double angleOfWhiteMini = 0;
78 //寫輪眼溝玉圓(sharinganSemi)和白圓(whiteOfSharingan)在外圓(extendCircleSemi)的角度
79 double angleOfwhiteShar = 0;
80 //用于判斷圓是否到達(dá)極限位置,還句話說(shuō)就是是否到達(dá)了正確的角度,進(jìn)行下一次循環(huán)
81 boolean flag = true;
82 //溝玉球心到弦(whiteOfSharingan圓中心和miniCircleSemi圓中心所連成的線)中心距離;
83 double distansOfWhiteShar =0;
84 //溝玉球心到中心點(diǎn)的距離,這一步主要是為了計(jì)算坐標(biāo)
85 double distansOfSharSemi = 0;
86 //在繪圖過(guò)程中,由于計(jì)算機(jī)計(jì)算開(kāi)方、三角函數(shù)、反三角等造成了誤差,這是一個(gè)補(bǔ)償值,但要注意真正補(bǔ)償?shù)? 87 //誤差為這個(gè)誤差的angleErr*2/3,因?yàn)檫@個(gè)值是本人通過(guò)理想設(shè)置臨界狀態(tài)得到的值。
88 double angleErr = 0.02500260489936114;
89 //溝玉球(whiteOfSharingan)中的黑球半徑,這個(gè)值是動(dòng)態(tài)的
90 int blackOfWhiteSemi = 0;
91 //中心眼睛所占的長(zhǎng)度
92 int eyeLength = 300;
93 //眼睛幅值
94 int amplitude = 50;
95
96 public SharinganJPanel() {
97
98 startRun();
99 }
100
101 @Override
102 public void paint(Graphics graphics) {
103 System.out.println();
104 super.paint(graphics);
105 this.setBackground(Color.black);
106 //繪制一個(gè)眼睛作為背景
107 graphics.setColor(Color.red);
108 for (int i = 0; i < eyeLength; i++) {
109 graphics.drawLine( centerX-eyeLength/2+i,
110 centerY-(int)(Math.sin(Math.PI*i/eyeLength)*amplitude),
111 centerX-eyeLength/2+i,
112 centerY+(int)(Math.sin(Math.PI*i/eyeLength)*amplitude));
113 }
114 //在眼睛的中心繪制一個(gè)黑色的圓
115 graphics.setColor(Color.black);
116 graphics.fillOval( centerX-90/2,
117 centerY-90/2,
118 90,
119 90);
120 //在眼睛的中心繪制一個(gè)白色的圓
121 graphics.setColor(Color.white);
122 graphics.fillOval( centerX-60/2/2/2,
123 centerY-60/2/2/2,
124 60/2/2,
125 60/2/2);
126 //用于繪制3個(gè)不同角度、在不斷變化、不同位置的太極圖,圖是有順序的
127 for (int i = 0; i < 3; i++) {
128 //繪制寫輪眼球(sharinganSemi)
129 graphics.setColor(Color.red);
130 graphics.fillArc( (int)(centerX-sharinganSemi+Math.cos(Math.PI*(angleCircle+90+(i*120))/180-angleOfWhiteMini/2+angleOfwhiteShar+angleErr*2/3)*distansOfSharSemi),
131 (int)(centerY-sharinganSemi-Math.sin(Math.PI*(angleCircle+90+(i*120))/180-angleOfWhiteMini/2+angleOfwhiteShar+angleErr*2/3)*distansOfSharSemi),
132 (int)(sharinganSemi*2),
133 (int)(sharinganSemi*2),angleCircle+i*120,180);
134 //繪制寫輪眼固定圓(whiteOfSharingan)
135 graphics.setColor(Color.red);
136 graphics.fillOval( (int)(centerX-whiteOfSharingan+Math.cos(Math.PI*(angleCircle+90+(i*120))/180)*extendCircleSemi),
137 (int)(centerY-whiteOfSharingan-Math.sin(Math.PI*(angleCircle+90+(i*120))/180)*extendCircleSemi),
138 (int)(whiteOfSharingan*2),
139 (int)(whiteOfSharingan*2));
140 //繪制寫輪眼黑球(miniCircleSemi)
141 graphics.setColor(Color.black);
142 graphics.fillOval( (int)(centerX-miniCircleSemi+Math.cos(Math.PI*(angleCircle+90+(i*120))/180-angleOfWhiteMini)*extendCircleSemi),
143 (int)(centerY-miniCircleSemi-Math.sin(Math.PI*(angleCircle+90+(i*120))/180-angleOfWhiteMini)*extendCircleSemi),
144 (int)(miniCircleSemi*2),
145 (int)(miniCircleSemi*2));
146 //繪制寫輪眼固定球內(nèi)黑球(blackOfWhiteSemi)
147 graphics.setColor(Color.black);
148 graphics.fillOval( (int)(centerX-(blackOfWhiteSemi+0.0)/120*whiteOfSharingan/2+Math.cos(Math.PI*(angleCircle+90+(i*120))/180)*extendCircleSemi),
149 (int)(centerY-(blackOfWhiteSemi+0.0)/120*whiteOfSharingan/2-Math.sin(Math.PI*(angleCircle+90+(i*120))/180)*extendCircleSemi),
150 (int)((blackOfWhiteSemi+0.0)/120*whiteOfSharingan),
151 (int)((blackOfWhiteSemi+0.0)/120*whiteOfSharingan));
152 }
153 //繪制外圓
154 graphics.setColor(Color.red);
155 graphics.drawOval( (int)(centerX-extendCircleSemi),
156 (int)(centerY-extendCircleSemi),
157 (int)(extendCircleSemi)*2,
158 (int)(extendCircleSemi)*2);
159 }
160 public void startRun() {
161 new Thread(){
162 public void run() {
163 while(true){
164 if (flag) {
165 angleCircle += 2 ;
166 //溝玉白球中的黑球半徑
167 blackOfWhiteSemi = angleCircle;
168 //System.out.println(angleCircle);
169 //根據(jù)目前寫輪眼溝玉球轉(zhuǎn)過(guò)角度來(lái)確定mini小球目前的對(duì)應(yīng)的半徑
170 miniCircleSemi = (angleCircle+0.0)/120*whiteOfSharingan;
171 //System.out.println(miniCircleSemi);
172 //溝玉球半徑
173 sharinganSemi = miniCircleSemi+whiteOfSharingan;
174 //System.out.println(sharinganSemi);
175 //由于白球和mini小球都是在外圓上,所以通過(guò)弦對(duì)應(yīng)的角度來(lái)求的小圓落后于白球的角度
176 angleOfWhiteMini = Math.asin(sharinganSemi/2/extendCircleSemi)*2;
177 //System.out.println(angleOfWhiteMini);
178 //溝玉球心到白球中心距離
179 distansOfWhiteShar = (whiteOfSharingan-miniCircleSemi)/2;
180 //溝玉球心到中心點(diǎn)的距離
181 distansOfSharSemi = Math.sqrt( extendCircleSemi*extendCircleSemi
182 -((whiteOfSharingan+miniCircleSemi)/2)*((whiteOfSharingan+miniCircleSemi)/2)
183 +((whiteOfSharingan-miniCircleSemi)/2)*((whiteOfSharingan-miniCircleSemi)/2));
184 //溝玉球心和白求在中心圓上所成的角度
185 //通過(guò)這里可以可以求出由于計(jì)算機(jī)計(jì)算產(chǎn)生的計(jì)算誤差為(0.02500260489936114)
186 //System.out.println(distansOfSharSemi);
187 angleOfwhiteShar = Math.asin(distansOfWhiteShar/2/distansOfSharSemi);
188 //System.out.println(angleOfwhiteShar);
189 if (angleCircle == 120) {
190 flag = false;
191 }
192 }else {
193 angleCircle += 2;
194 //溝玉白球中的黑球半徑
195 blackOfWhiteSemi = 240-angleCircle;
196 //根據(jù)目前寫輪眼溝玉球轉(zhuǎn)過(guò)角度來(lái)確定mini小球目前的對(duì)應(yīng)的半徑
197 miniCircleSemi = (240.0-angleCircle)/120*whiteOfSharingan;
198 //miniCircleSemi = (angleCircle+0.0)/120*whiteOfSharingan;
199 //溝玉球半徑
200 sharinganSemi = miniCircleSemi+whiteOfSharingan;
201 //由于白球和mini小球都是在外圓上,所以通過(guò)弦對(duì)應(yīng)的角度來(lái)求的小圓落后于白球的角度
202 angleOfWhiteMini = Math.asin(sharinganSemi/2/extendCircleSemi)*2;
203 //溝玉球心到白球中心距離
204 distansOfWhiteShar = (whiteOfSharingan-miniCircleSemi)/2;
205 //溝玉球心到中心點(diǎn)的距離
206 distansOfSharSemi = Math.sqrt( extendCircleSemi*extendCircleSemi
207 -((whiteOfSharingan+miniCircleSemi)/2)*((whiteOfSharingan+miniCircleSemi)/2)
208 +((whiteOfSharingan-miniCircleSemi)/2)*((whiteOfSharingan-miniCircleSemi)/2));
209 //溝玉球心和白求在中心圓上所成的角度
210 angleOfwhiteShar = Math.asin(distansOfWhiteShar/2/distansOfSharSemi);
211 if (angleCircle == 240) {
212 angleCircle = 0;
213 flag = true;
214 }
215 }
216 try {
217 Thread.sleep(20);
218 } catch (InterruptedException e) {
219 e.printStackTrace();
220 }
221 repaint();
222 }
223 };
224 }.start();
225 }
226 public static void main(String[] args) {
227 JFrame jFrame = new JFrame();
228 jFrame.setTitle("Sharingan");
229 jFrame.setSize(centerX*2, centerY*2);
230 jFrame.getContentPane().setBackground(Color.black);
231 jFrame.setLocationRelativeTo(null);
232 jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
233
234 JPanel jPanel = new SharinganJPanel();
235 jFrame.add(jPanel);
236 jFrame.setVisible(true);
237 }
238 }
?
?
效果如圖:
轉(zhuǎn)載于:https://www.cnblogs.com/zengjfgit/p/5094878.html
總結(jié)
以上是生活随笔為你收集整理的Java 动态写轮眼 SharinganJPanel (整理)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: IO 延迟与Queue Depth
- 下一篇: Ibatis学习总结1--ibatis简