1:
46:
47: package ;
48:
49: import ;
50: import ;
51: import ;
52: import ;
53:
54: import ;
55: import ;
56:
57:
64: public abstract class ColorPalette implements Cloneable, Serializable {
65:
66:
67: private static final long serialVersionUID = -9029901853079622051L;
68:
69:
70: protected double minZ = -1;
71:
72:
73: protected double maxZ = -1;
74:
75:
76: protected int[] r;
77:
78:
79: protected int[] g;
80:
81:
82: protected int[] b;
83:
84:
85: protected double[] tickValues = null;
86:
87:
88: protected boolean logscale = false;
89:
90:
91: protected boolean inverse = false;
92:
93:
94: protected String paletteName = null;
95:
96:
97: protected boolean stepped = false;
98:
99:
100: protected static final double log10 = Math.log(10);
101:
102:
105: public ColorPalette() {
106: super();
107: }
108:
109:
116: public Paint getColor(double value) {
117: int izV = (int) (253 * (value - this.minZ)
118: / (this.maxZ - this.minZ)) + 2;
119: return new Color(this.r[izV], this.g[izV], this.b[izV]);
120: }
121:
122:
129: public Color getColor(int izV) {
130: return new Color(this.r[izV], this.g[izV], this.b[izV]);
131: }
132:
133:
140: public Color getColorLinear(double value) {
141: int izV = 0;
142: if (this.stepped) {
143: int index = Arrays.binarySearch(this.tickValues, value);
144: if (index < 0) {
145: index = -1 * index - 2;
146: }
147:
148: if (index < 0) {
149:
150: value = this.minZ;
151: }
152: else {
153: value = this.tickValues[index];
154: }
155: }
156: izV = (int) (253 * (value - this.minZ) / (this.maxZ - this.minZ)) + 2;
157: izV = Math.min(izV, 255);
158: izV = Math.max(izV, 2);
159: return getColor(izV);
160: }
161:
162:
169: public Color getColorLog(double value) {
170: int izV = 0;
171: double minZtmp = this.minZ;
172: double maxZtmp = this.maxZ;
173: if (this.minZ <= 0.0) {
174:
175: this.maxZ = maxZtmp - minZtmp + 1;
176: this.minZ = 1;
177: value = value - minZtmp + 1;
178: }
179: double minZlog = Math.log(this.minZ) / log10;
180: double maxZlog = Math.log(this.maxZ) / log10;
181: value = Math.log(value) / log10;
182:
183: if (this.stepped) {
184: int numSteps = this.tickValues.length;
185: int steps = 256 / (numSteps - 1);
186: izV = steps * (int) (numSteps * (value - minZlog)
187: / (maxZlog - minZlog)) + 2;
188:
189: }
190: else {
191: izV = (int) (253 * (value - minZlog) / (maxZlog - minZlog)) + 2;
192: }
193: izV = Math.min(izV, 255);
194: izV = Math.max(izV, 2);
195:
196: this.minZ = minZtmp;
197: this.maxZ = maxZtmp;
198:
199: return getColor(izV);
200: }
201:
202:
207: public double getMaxZ() {
208: return this.maxZ;
209: }
210:
211:
216: public double getMinZ() {
217: return this.minZ;
218: }
219:
220:
228: public Paint getPaint(double value) {
229: if (isLogscale()) {
230: return getColorLog(value);
231: }
232: else {
233: return getColorLinear(value);
234: }
235: }
236:
237:
242: public String getPaletteName () {
243: return this.paletteName;
244: }
245:
246:
251: public double[] getTickValues() {
252: return this.tickValues;
253: }
254:
255:
258: public abstract void initialize();
259:
260:
263: public void invertPalette() {
264:
265: int[] red = new int[256];
266: int[] green = new int[256];
267: int[] blue = new int[256];
268: for (int i = 0; i < 256; i++) {
269: red[i] = this.r[i];
270: green[i] = this.g[i];
271: blue[i] = this.b[i];
272: }
273:
274: for (int i = 2; i < 256; i++) {
275: this.r[i] = red[257 - i];
276: this.g[i] = green[257 - i];
277: this.b[i] = blue[257 - i];
278: }
279: }
280:
281:
286: public boolean isInverse () {
287: return this.inverse;
288: }
289:
290:
295: public boolean isLogscale() {
296: return this.logscale;
297: }
298:
299:
304: public boolean isStepped () {
305: return this.stepped;
306: }
307:
308:
313: public void setInverse (boolean inverse) {
314: this.inverse = inverse;
315: initialize();
316: if (inverse) {
317: invertPalette();
318: }
319: return;
320: }
321:
322:
327: public void setLogscale(boolean logscale) {
328: this.logscale = logscale;
329: }
330:
331:
336: public void setMaxZ(double newMaxZ) {
337: this.maxZ = newMaxZ;
338: }
339:
340:
345: public void setMinZ(double newMinZ) {
346: this.minZ = newMinZ;
347: }
348:
349:
354: public void setPaletteName (String paletteName) {
355:
356: this.paletteName = paletteName;
357: return;
358: }
359:
360:
365: public void setStepped (boolean stepped) {
366: this.stepped = stepped;
367: return;
368: }
369:
370:
375: public void setTickValues(double[] newTickValues) {
376: this.tickValues = newTickValues;
377: }
378:
379:
384: public void setTickValues(java.util.List ticks) {
385: this.tickValues = new double[ticks.size()];
386: for (int i = 0; i < this.tickValues.length; i++) {
387: this.tickValues[i] = ((ValueTick) ticks.get(i)).getValue();
388: }
389: }
390:
391:
398: public boolean equals(Object o) {
399: if (this == o) {
400: return true;
401: }
402: if (!(o instanceof ColorPalette)) {
403: return false;
404: }
405:
406: ColorPalette colorPalette = (ColorPalette) o;
407:
408: if (this.inverse != colorPalette.inverse) {
409: return false;
410: }
411: if (this.logscale != colorPalette.logscale) {
412: return false;
413: }
414: if (this.maxZ != colorPalette.maxZ) {
415: return false;
416: }
417: if (this.minZ != colorPalette.minZ) {
418: return false;
419: }
420: if (this.stepped != colorPalette.stepped) {
421: return false;
422: }
423: if (!Arrays.equals(this.b, colorPalette.b)) {
424: return false;
425: }
426: if (!Arrays.equals(this.g, colorPalette.g)) {
427: return false;
428: }
429: if (this.paletteName != null
430: ? !this.paletteName.equals(colorPalette.paletteName)
431: : colorPalette.paletteName != null) {
432: return false;
433: }
434: if (!Arrays.equals(this.r, colorPalette.r)) {
435: return false;
436: }
437: if (!Arrays.equals(this.tickValues, colorPalette.tickValues)) {
438: return false;
439: }
440:
441: return true;
442: }
443:
444:
449: public int hashCode() {
450: int result;
451: long temp;
452: temp = Double.doubleToLongBits(this.minZ);
453: result = (int) (temp ^ (temp >>> 32));
454: temp = Double.doubleToLongBits(this.maxZ);
455: result = 29 * result + (int) (temp ^ (temp >>> 32));
456: result = 29 * result + (this.logscale ? 1 : 0);
457: result = 29 * result + (this.inverse ? 1 : 0);
458: result = 29 * result
459: + (this.paletteName != null ? this.paletteName.hashCode() : 0);
460: result = 29 * result + (this.stepped ? 1 : 0);
461: return result;
462: }
463:
464:
471: public Object clone() throws CloneNotSupportedException {
472:
473: ColorPalette clone = (ColorPalette) super.clone();
474: return clone;
475:
476: }
477:
478: }