1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.cosylab.gui.components.ledder;
21 import java.awt.Color;
22
23
24
25
26
27
28
29
30
31
32 public class LedRenderer {
33
34 private int centerX;
35 private int centerY;
36
37 private double radiusOffset;
38
39 private int radius;
40
41 private int red;
42 private int green;
43 private int blue;
44
45 private double highlightFactor = 0.85;
46 private double highlightFocus = 3;
47
48 private double shadowIntensity = 1.5;
49
50 private int ro1;
51 private int ro2;
52
53 private final float[] colorHSB = new float[3];
54
55 private double[] l = getLight(-0.2, -0.5);
56
57
58
59
60
61
62
63 public LedRenderer(int x, int y, int r, LedPaintParameters lpp) {
64 super();
65
66 centerX = x;
67 centerY = y;
68 radius = r;
69
70 l = getLight(lpp.lightX, lpp.lightY);
71
72 highlightFactor = lpp.highlightFactor;
73 highlightFocus = lpp.highlightFocus;
74 shadowIntensity = lpp.shadowIntensity;
75
76 radiusOffset = (1 - lpp.borderSize) * radius;
77 ro1 = (int) (radiusOffset * radiusOffset);
78 ro2 = radius * radius;
79
80 red = lpp.color.getRed();
81 green = lpp.color.getGreen();
82 blue = lpp.color.getBlue();
83
84 }
85
86
87
88
89
90
91 private final float getHighlight(double x, final double p) {
92
93 x = (x - highlightFactor) / (1 - highlightFactor);
94
95 return (float) ((x < 0) ? p : p * (1 - Math.pow(x, highlightFocus)));
96 }
97
98
99
100
101
102
103 private final float getIntensity(final double x, final double p) {
104 return (float) (p * Math.pow(x, shadowIntensity));
105
106 }
107
108
109
110
111
112 private final int getColor(final double angle) {
113 Color.RGBtoHSB(red, green, blue, colorHSB);
114
115 return Color.HSBtoRGB(
116 colorHSB[0],
117 getHighlight(angle, colorHSB[1]),
118 getIntensity(angle, colorHSB[2]));
119 }
120
121
122
123
124
125
126
127 public double[] getLight(double x, double y) {
128 double[] v = new double[3];
129 v[0] = x;
130 v[1] = y;
131 v[2] = Math.sqrt(1.0 - x * x - y * y);
132
133 return v;
134 }
135
136
137
138
139
140
141
142
143 public final int[] renderSection(
144 final int x,
145 final int y,
146 final int w,
147 final int h) {
148
149 final int[] data = new int[w * h * 4];
150
151 int col;
152 int base = 0;
153 double dot;
154 double angle;
155
156 for (int py = 0; py < h; py++) {
157
158 base = 4 * (py * w);
159 int dy = y + py - centerY;
160 int dx = x - centerX;
161
162 for (int px = 0; px < w; px++) {
163
164 int d = dx * dx + dy * dy;
165
166 if (d < ro1) {
167
168 dot = dx * l[0] + dy * l[1] + Math.sqrt(ro2 - d) * l[2];
169
170 angle = (1 + dot / radius) / 2;
171
172 col = getColor(angle);
173
174 } else {
175 col = (d <= ro2) ? 0xFF000000 : 0x0;
176 }
177
178 data[base + 0] = (col >> 0x10) & 0xFF;
179 data[base + 1] = (col >> 0x08) & 0xFF;
180 data[base + 2] = (col >> 0x00) & 0xFF;
181 data[base + 3] = (col >> 0x18) & 0xFF;
182
183 base += 4;
184 dx++;
185 }
186 }
187 return data;
188 }
189 }