-
Notifications
You must be signed in to change notification settings - Fork 21
Expand file tree
/
Copy pathAnimationECC.java
More file actions
291 lines (237 loc) · 9.08 KB
/
AnimationECC.java
File metadata and controls
291 lines (237 loc) · 9.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.util.ArrayList;
import javax.swing.JLabel;
import javax.swing.JPanel;
/***************************************************************************************************************
* V1.1 vom 07.12.2024 *
* Info: Dieses Dokument enthält zwei Klassen! *
* *
* Diese AnimationECC Klasse erstellt ein animiertes Bild der Kurve Secp256k1. *
* Zu erst muss mit dem Konstruktor ein AnimationECC Object erzeugt werden! *
* Dem Konstruktor muss das Panel übergeben werden, auf welches gezeichnet wird. *
* *
* Die SetBounds-Methode skaliert die Position und die Größe des Animationsfensters *
* und speichert alle Punktkoordinaten der Kurve in einem großem Array der Klasse PunktJLabel *
* Sollte nur einmal bei Programmstart ausgeführt werden, nicht in Schleife! *
* *
* Die start() Methode startet in einem eigenem Thread die Animation. *
* Die close() Methode beendet die Animation und den Thread. *
* Achtung: close() Muss am ende ausgeführt werden, sonnst läuft der Thread weiter! *
* close() sollte daher immer in den addShutdownHook() Bereich des Programmes eingefügt werden! *
****************************************************************************************************************/
public class AnimationECC
{
JPanel panelHaupt; // Ist das Panel welches vom Konstruktor übergeben wurde und auf Das gezeichnet wird.
static boolean run = false; // damit wird der Thread beendet (muss static sein!!!)
static boolean antialiasing; // Schaltet Antialiasing ein oder aus.
int sleepTime = 20; // Die ZyklusZeit der Animation woraus sich die FPS ergibt.
int maxRounds = 100; // Maximale Wiederholungen der Animation bevor der Thread beendet wird.
int[] bounds = new int[4]; // Die Position und die Größe der Animation
static int diameter = 2; // Durchmesser des Punktest
int pointCount = 8000; // Anzahl der Animierten Punkte auf der Kurve (wird zur Laufzeit reduziert)
Color color0 = Color.white; // Default Hintergrundfarbe
Color color1 = Color.red; // Default Animationsfarbe
PointJLabel[] point = new PointJLabel[pointCount]; // Das Array der animierten Punkte
/** Dem Konstruktor wird das Panel übergeben auf das die Grafig gezeichnet werden soll. **/
public AnimationECC(JPanel panelHaupt)
{
this.panelHaupt = panelHaupt;
for(int i=0;i<pointCount; i++)
{
point[i] = new PointJLabel();
}
}
//Setzt die Hintergrundfarbe der Animation
public void setBackground(Color c)
{
color0 = c;
}
// Setzt die Hauptfarbe der Amination
public void setForeground(Color c)
{
color1 = c;
}
/** Skalliert die Position und die Größe des Animationsfensters
und speichert alle Punktkoordinaten der Kurve in einem großem Array der Klasse PunktJLabel
Sollte nur einmal bei Programmstart ausgeführt werden, nicht in Schleife! **/
public void setBounds(int x, int y, double b, double h)
{
bounds[0]= x;
bounds[1]= y;
bounds[2]= (int)b;
bounds[3]= (int)h;
int i=0;
for(double dx=-1.91293; dx<20 && i<pointCount; dx=dx+0.00225)
{
point[i].setBounds(bounds[0], bounds[1], bounds[2], bounds[3]);
if(i==4000) dx=-1.91293;
double y1 = -(Math.sqrt(dx*dx*dx +7.0))*2.0;
if(i<4000) point[3999-i].setBoundsPoint((int)((dx+2.5)*20.0 * b/220.0) , (int)(((y1*10.0)+378.0) *h/800.0) , diameter);
else point[i].setBoundsPoint((int)((dx+2.5)*20.0 * b/220.0) , (int)(((-y1*10.0)+378.0)*h/800.0) , diameter);
i++;
}
point = PointsDilutiong(point);
for(int j=0;j<pointCount; j++) // Fügt schon mal alle Punkte den Panel zu
{
panelHaupt.add(point[j]);
point[j].setForeground(color0);
}
}
/** Startet die Animation und den Thread.
Achtung: Der Thread muss mit der Methode "close()" immer beendet werden!*/
public void start()
{
Thread t1 = new Thread(new Runnable()
{
public void run()
{
run=true;
double dr = 1 * (color1.getRed() - color0.getRed()); // delta rot
double dg = 1 * (color1.getGreen() - color0.getGreen()); // delta grün
double db = 1 * (color1.getBlue() - color0.getBlue()); // delta blau
double ir = dr/108; // ingrement rot
double ig = dg/108; // ingrement grün
double ib = db/108; // ingrement blau
// System.out.println("ingremente: "+ir+" "+ig+" "+ib); // Zum Debuggen
for(int rounds=0; rounds<maxRounds;rounds++) // Wiederholung der gesamten Animation bis maxRounds
{
for(int i=0;i<pointCount && run; i++) // pointCount = 200
{
for(int k=0;k<108 && run;k++)
{
int rot = (int) (color1.getRed()-k*ir);
int gruen = (int) (color1.getGreen()-k*ig);
int blau = (int) (color1.getBlue()-k*ib);
if(rot<0) rot = 0;
if(rot>255) rot = 255;
if(gruen<0) gruen = 0;
if(gruen>255) gruen = 255;
if(blau<0) blau = 0;
if(blau>255) blau = 255;
if(i-k<0)
{
point[(i-k)+pointCount].setForeground(new Color(rot,gruen,blau));
point[(i-k)+pointCount].setDiameter((pointCount-k)/25);
}
else
{
point[i-k].setForeground(new Color(rot,gruen,blau));
point[(i-k)].setDiameter((pointCount-k)/25);
}
}
try {Thread.sleep(sleepTime);} catch (InterruptedException e) {e.printStackTrace();}
}
}
run = false;
System.out.println("Thread AnimationECC beendet.");
}
});
if(run==false) t1.start();
}
// Löscht zu nah aneinander liegende Punkte in der Kurve und verteilt damit die Punkte gleichmäßiger.
// Das zurückgegebene Array ist dann natürlich kürzer.
private PointJLabel[] PointsDilutiong(PointJLabel[] point)
{
ArrayList<PointJLabel> list = new ArrayList<PointJLabel>();
list.add(point[0]);
for(int i=1;i<pointCount; i++)
{
double x1 = (double)list.get(list.size() - 1).x;
double y1 = (double)list.get(list.size() - 1).y;
double x2 = (double)point[i].x;
double y2 = (double)point[i].y;
double dx = Math.sqrt(Math.pow(x1-x2, 2.0) + Math.pow(y1-y2, 2.0)); // Abstand zwischen zwei Punkten
if(dx>2)list.add(point[i]);
}
pointCount = list.size();
point = new PointJLabel[list.size()];
for(int i=0;i<list.size(); i++)
{
point[i] = list.get(i);
}
return point;
}
/** Setzt den Durchmesser des Punktest
Muss vor setBounds gesetzt werden! **/
public void setDiameter(int d)
{
diameter = d;
}
/** Antialiasing an oder aus **/
public void setAntialiasing(boolean a)
{
antialiasing = a;
}
/** Setzt die Sleep Time des Threades in ms.
Damit wird die Geschwindigkeit der Animation verändert.
Default ist 20ms **/
public void setSleepTime(int ms)
{
this.sleepTime = ms;
}
/** Setzt die maximalen Wiederholungen der Animation bevor der Thread beendet wird.
Wirkt als zusätzliche Sicherheit zum beenden des Threads.
Default ist 100 Wiederholungen **/
public void setMaxRound(int count)
{
this.maxRounds = count;
}
/** Zeichnet die Kurve für Testzwecke **/
public void printCurv()
{
for(int i=0;i<pointCount; i++)
{
point[i].setForeground(Color.CYAN);
}
}
/** Beendet die Animation und den Thread.
Muss am ende ausgefÜhrt werden sonnst läuft der Thread weiter! */
public void close()
{
run = false;
for(int i=0;i<pointCount; i++)
{
point[i].setForeground(color0);
}
}
}
//----------------------------------- Ende Class AnimationECC -----------------------------------//
/****************************************************************************************************************
* Diese PointJLabel Klasse ist eine Subklasse von JLabel. *
* Sie wird genau wie JLabel verwendet, enthält jedoch die unteren zusätzlichen Atribute und Methoden. *
* PointJLabel wird verwendet um einen einzelnen Punkt auf der Kurve zu speichern und zu zeichnen. *
* Dazu wird ein Array aus PointJLabel Objekten erzeugt welches dann das Bild darstellt. *
****************************************************************************************************************/
class PointJLabel extends JLabel
{
int x = 0;
int y = 0;
int d = 12;
/** Zeichnet den Punkt auf das JLabel */
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
if(AnimationECC.antialiasing) // Antialiasing
{
Graphics2D graphics2D = (Graphics2D) g;
graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
graphics2D.fillOval(x,y, d, d);
}
else g.fillOval(x,y, d, d);
}
public void setBoundsPoint(int x, int y, int d)
{
this.x = x;
this.y = y;
this.d = d;
}
public void setDiameter(int d)
{
if(d>AnimationECC.diameter) this.d = d;
else this.d = AnimationECC.diameter;
}
}