package ij.util;
import java.awt.Color;
import java.util.*;
import java.io.*;
/** This class contains static utility methods. */
public class Tools {
/** This array contains the 16 hex digits '0'-'F'. */
public static final char[] hexDigits = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
/** Converts a Color to an 7 byte hex string starting with '#'. */
public static String c2hex(Color c) {
int i = c.getRGB();
char[] buf7 = new char[7];
buf7[0] = '#';
for (int pos=6; pos>=1; pos--) {
buf7[pos] = hexDigits[i&0xf];
i >>>= 4;
}
return new String(buf7);
}
/** Converts a float to an 9 byte hex string starting with '#'. */
public static String f2hex(float f) {
int i = Float.floatToIntBits(f);
char[] buf9 = new char[9];
buf9[0] = '#';
for (int pos=8; pos>=1; pos--) {
buf9[pos] = hexDigits[i&0xf];
i >>>= 4;
}
return new String(buf9);
}
public static double[] getMinMax(double[] a) {
double min = Double.MAX_VALUE;
double max = -Double.MAX_VALUE;
double value;
for (int i=0; i<a.length; i++) {
value = a[i];
if (value<min)
min = value;
if (value>max)
max = value;
}
double[] minAndMax = new double[2];
minAndMax[0] = min;
minAndMax[1] = max;
return minAndMax;
}
public static double[] getMinMax(float[] a) {
double min = Double.MAX_VALUE;
double max = -Double.MAX_VALUE;
double value;
for (int i=0; i<a.length; i++) {
value = a[i];
if (value<min)
min = value;
if (value>max)
max = value;
}
double[] minAndMax = new double[2];
minAndMax[0] = min;
minAndMax[1] = max;
return minAndMax;
}
/** Converts the float array 'a' to a double array. */
public static double[] toDouble(float[] a) {
int len = a.length;
double[] d = new double[len];
for (int i=0; i<len; i++)
d[i] = a[i];
return d;
}
/** Converts the double array 'a' to a float array. */
public static float[] toFloat(double[] a) {
int len = a.length;
float[] f = new float[len];
for (int i=0; i<len; i++)
f[i] = (float)a[i];
return f;
}
/** Converts carriage returns to line feeds. */
public static String fixNewLines(String s) {
char[] chars = s.toCharArray();
for (int i=0; i<chars.length; i++)
{if (chars[i]=='\r') chars[i] = '\n';}
return new String(chars);
}
/**
* Returns a double containg the value represented by the
* specified <code>String</code>.
*
* @param s the string to be parsed.
* @param defaultValue the value returned if <code>s</code>
* does not contain a parsable double
* @return The double value represented by the string argument or
* <code>defaultValue</code> if the string does not contain a parsable double
*/
public static double parseDouble(String s, double defaultValue) {
if (s==null) return defaultValue;
try {
defaultValue = Double.parseDouble(s);
} catch (NumberFormatException e) {}
return defaultValue;
}
/**
* Returns a double containg the value represented by the
* specified <code>String</code>.
*
* @param s the string to be parsed.
* @return The double value represented by the string argument or
* Double.NaN if the string does not contain a parsable double
*/
public static double parseDouble(String s) {
return parseDouble(s, Double.NaN);
}
/** Returns the number of decimal places need to display two numbers. */
public static int getDecimalPlaces(double n1, double n2) {
if (Math.round(n1)==n1 && Math.round(n2)==n2)
return 0;
else {
n1 = Math.abs(n1);
n2 = Math.abs(n2);
double n = n1<n2&&n1>0.0?n1:n2;
double diff = Math.abs(n2-n1);
if (diff>0.0 && diff<n) n = diff;
int digits = 2;
if (n<100.0) digits = 3;
if (n<0.1) digits = 4;
if (n<0.01) digits = 5;
if (n<0.001) digits = 6;
if (n<0.0001) digits = 7;
return digits;
}
}
/** Splits a string into substrings using the default delimiter set,
which is " \t\n\r" (space, tab, newline and carriage-return). */
public static String[] split(String str) {
return split(str, " \t\n\r");
}
/** Splits a string into substring using the characters
contained in the second argument as the delimiter set. */
public static String[] split(String str, String delim) {
if (delim.equals("\n"))
return splitLines(str);
StringTokenizer t = new StringTokenizer(str, delim);
int tokens = t.countTokens();
String[] strings;
if (tokens>0) {
strings = new String[tokens];
for(int i=0; i<tokens; i++)
strings[i] = t.nextToken();
} else {
strings = new String[1];
strings[0] = str;
tokens = 1;
}
return strings;
}
static String[] splitLines(String str) {
Vector v = new Vector();
try {
BufferedReader br = new BufferedReader(new StringReader(str));
String line;
while (true) {
line = br.readLine();
if (line == null) break;
v.addElement(line);
}
br.close();
} catch(Exception e) { }
String[] lines = new String[v.size()];
v.copyInto((String[])lines);
return lines;
}
//Modified from: http://stackoverflow.com/questions/951848 N.Vischer
// quicksort a[left] to a[right]
public static void quicksort(double[] a, int[] index) {
quicksort(a, index, 0, a.length-1);
}
public static void quicksort(double[] a, int[] index, int left, int right) {
if (right <= left) return;
int i = partition(a, index, left, right);
quicksort(a, index, left, i-1);
quicksort(a, index, i+1, right);
}
// partition a[left] to a[right], assumes left < right
private static int partition(double[] a, int[] index,
int left, int right) {
int i = left - 1;
int j = right;
while (true) {
while (a[++i] < a[right]) // find item on left to swap
; // a[right] acts as sentinel
while (!(a[right] >= a[--j])) // find item on right to swap (NAN TRICK)
if (j == left) break; // don't go out-of-bounds
if (i >= j) break; // check if pointers cross
exch(a, index, i, j); // swap two elements into place
}
exch(a, index, i, right); // swap with partition element
return i;
}
// exchange a[i] and a[j]
private static void exch(double[] a, int[] index, int i, int j) {
double swap = a[i];
a[i] = a[j];
a[j] = swap;
int b = index[i];
index[i] = index[j];
index[j] = b;
}
// quicksort a[left] to a[right]
public static void quicksort(String[] a, int[] index) {
quicksort(a, index, 0, a.length-1);
}
public static void quicksort(String[] a, int[] index, int left, int right) {
if (right <= left) return;
int i = partition(a, index, left, right);
quicksort(a, index, left, i-1);
quicksort(a, index, i+1, right);
}
// partition a[left] to a[right], assumes left < right
private static int partition(String[] a, int[] index,
int left, int right) {
int i = left - 1;
int j = right;
while (true) {
while (a[++i].compareToIgnoreCase( a[right])<0) // find item on left to swap
; // a[right] acts as sentinel
while (a[right].compareToIgnoreCase( a[--j])<0) // find item on right to swap
if (j == left) break; // don't go out-of-bounds
if (i >= j) break; // check if pointers cross
exch(a, index, i, j); // swap two elements into place
}
exch(a, index, i, right); // swap with partition element
return i;
}
// exchange a[i] and a[j]
private static void exch(String[] a, int[] index, int i, int j) {
String swap = a[i];
a[i] = a[j];
a[j] = swap;
int b = index[i];
index[i] = index[j];
index[j] = b;
}
}