Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 0 additions & 12 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -52,18 +52,6 @@
<version>1.0.1</version>
</dependency>

<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-graphics</artifactId>
<version>11.0.2</version>
</dependency>

<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-swing</artifactId>
<version>11.0.2</version>
</dependency>

<!-- Testing -->
<dependency>
<groupId>org.junit.jupiter</groupId>
Expand Down
19 changes: 9 additions & 10 deletions src/main/java/dev/brachtendorf/clustering/ClusterResult.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package dev.brachtendorf.clustering;

import java.awt.Graphics;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
Expand All @@ -19,7 +19,6 @@
import dev.brachtendorf.clustering.distance.EuclideanDistance;
import dev.brachtendorf.graphics.ColorUtil;
import dev.brachtendorf.mutable.MutableDouble;
import javafx.scene.paint.Color;

/**
* @author Kilian
Expand All @@ -45,11 +44,11 @@ public class ClusterResult {
private HashMap<Integer, MutableDouble> silhouetteCoef = new HashMap<>();

//Cohesion ...

//Radius ... diameter
//density volume/points


public ClusterResult(int[] clusterIndex, double[][] data) {

int dimensions = data[0].length;
Expand Down Expand Up @@ -163,7 +162,7 @@ public void printInformation() {

StringBuilder sb = new StringBuilder();
sb.append("Observations: ").append(clusterIndex.length).append("\n").append("Number of Clusters: ")
.append(numberOfClusters).append("\n");
.append(numberOfClusters).append("\n");

int clusterLength = StringUtil.charsNeeded(numberOfClusters);
int obsLength = StringUtil.charsNeeded(clusterIndex.length);
Expand All @@ -190,7 +189,7 @@ public void printInformation() {
}
silouetteCoeffificient += silhouetteCoef.get(i).getValue();
sb.append("] Silhouette Coef: ").append(df.format(silhouetteCoef.get(i).getValue())).append(" SSE:")
.append(sseDf.format(sse.get(i).doubleValue())).append("\n");
.append(sseDf.format(sse.get(i).doubleValue())).append("\n");
}

sb.append("SSE: " + df.format(sseSum)).append("\n");
Expand Down Expand Up @@ -221,7 +220,7 @@ public void toImage(File outputFile) {
}
}

javafx.scene.paint.Color[] c = ColorUtil.ColorPalette.getPaletteHue(numberOfClusters, Color.BLUE, Color.RED);
Color[] c = ColorUtil.ColorPalette.getPaletteHue(numberOfClusters, Color.BLUE, Color.RED);

// Scale data
g.fillRect(0, 0, 700, 700);
Expand Down Expand Up @@ -259,11 +258,11 @@ public HashMap<Integer, List<double[]>> getClusters() {
public List<double[]> getCluster(int cluster) {
return clusters.get(cluster);
}

public DoubleSummaryStatistics[] getStats(int cluster) {
return stats.get(cluster);
}


public int[] getClusterData() {
return clusterIndex;
Expand Down
138 changes: 46 additions & 92 deletions src/main/java/dev/brachtendorf/graphics/ColorUtil.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package dev.brachtendorf.graphics;

import dev.brachtendorf.MathUtil;
import javafx.scene.paint.Color;

import java.awt.*;

/**
* @author Kilian
Expand Down Expand Up @@ -36,10 +37,7 @@ public class ColorUtil {
* @since 1.0.0 com.github.kilianB
*/
public static java.awt.Color fxToAwtColor(Color fxColor){
return new java.awt.Color((float)fxColor.getRed(),
(float)fxColor.getGreen(),
(float)fxColor.getBlue(),
(float)fxColor.getOpacity());
return fxColor;
}
//@formatter:on

Expand All @@ -51,29 +49,26 @@ public static java.awt.Color fxToAwtColor(Color fxColor){
* @since 1.0.0 com.github.kilianB
*/
public static Color awtToFxColor(java.awt.Color awtColor) {
return new Color(awtColor.getRed()/255d,
awtColor.getGreen()/255d,
awtColor.getBlue()/255d,
awtColor.getAlpha()/255d);
return awtColor;
}
//@formatter:on

/**
* Convert an argb value to it's individual components in range of 0 - 255
*
*
* @param argb values as int
* @return [0] Alpha, [1] Red, [2] Green, [3] Blue
* @since 1.0.0 com.github.kilianB
*
*
*/
public static int[] argbToComponents(int argb) {
return new int[] { argb >> 24 & 0xFF, argb >> 16 & 0xFF, argb >> 8 & 0xFF, argb & 0xFF };
return new int[]{argb >> 24 & 0xFF, argb >> 16 & 0xFF, argb >> 8 & 0xFF, argb & 0xFF};
}

/**
* Converts the components to a single int argb representation. The individual
* values are not range checked
*
*
* @param alpha in range of 0 - 255
* @param red in range of 0 - 255
* @param green in range of 0 - 255
Expand All @@ -88,63 +83,38 @@ public static int componentsToARGB(int alpha, int red, int green, int blue) {
/**
* Convert an argb value (alpha 24,red 16, green 8, blue 0) into a java fx
* color.
*
*
* @param argb the argb color as an int
* @return The JavaFX Color
* @since 1.0.0 com.github.kilianB
*/
public static javafx.scene.paint.Color argbToFXColor(int argb) {
public static Color argbToFXColor(int argb) {
int[] components = argbToComponents(argb);
return new javafx.scene.paint.Color(components[1] / 255d, components[2] / 255d, components[3] / 255d,
components[0] / 255d);
return new Color(components[1], components[2], components[3], components[0]);
}

/**
* Return the hexcode of a color
*
*
* @param color the color to convert
* @return a hex representation of the color
* @since 1.0.0 com.github.kilianB
*/
public static String fxToHex(Color color) {
return String.format("#%02X%02X%02X", (int) (color.getRed() * 255), (int) (color.getGreen() * 255),
(int) (color.getBlue() * 255));
(int) (color.getBlue() * 255));
}

// https://stackoverflow.com/a/2103608/3244464
// https://www.compuphase.com/cmetric.htm
/**
* Compute a distance metric of 2 colors. The distance of a color is greater the
* further away two colors are.
* <p>
*
* Identical colors will return a distance of 0.
*
* @param c1 The first color
* @param c2 The second color
* @return a double value indicating the distance of two colors
* @since 1.0.0 com.github.kilianB
*/
public static double distance(Color c1, Color c2) {
double rmean = (c1.getRed() * 255 + c2.getRed() * 255) / 2;
int r = (int) (c1.getRed() * 255 - c2.getRed() * 255);
int g = (int) (c1.getGreen() * 255 - c2.getGreen() * 255);
int b = (int) (c1.getBlue() * 255 - c2.getBlue() * 255);
double weightR = 2 + rmean / 256;
double weightG = 4.0;
double weightB = 2 + (255 - rmean) / 256;
return Math.sqrt(weightR * r * r + weightG * g * g + weightB * b * b);
}

// https://stackoverflow.com/a/2103608/3244464
// https://www.compuphase.com/cmetric.htm
/**
* Compute a distance metric of 2 colors. The distance of a color is greater the
* further away two colors are.
* <p>
*
*
* Identical colors will return a distance of 0.
*
*
* @param c1 The first color
* @param c2 The second color
* @return a double value indicating the distance of two colors
Expand All @@ -163,18 +133,7 @@ public static double distance(java.awt.Color c1, java.awt.Color c2) {

/**
* Get the Y (luma component) of the YCrCb color model
*
* @param c an javaFX color
* @return the luma component in the tange [0-1]
* @since 1.3.2 com.github.kilianB
*/
public static double getLuma(Color c) {
return LUMA_RED * c.getRed() + LUMA_GREEN * c.getGreen() + LUMA_BLUE * c.getBlue();
}

/**
* Get the Y (luma component) of the YCrCb color model
*
*
* @param c an awt color
* @return the luma component in the tange [0-255]
* @since 1.3.2 com.github.kilianB
Expand All @@ -188,27 +147,7 @@ public static int getLuma(java.awt.Color c) {
* Return either white or black depending on the supplied color to guarantee
* readability. The contrast color is assumed to be used as text overlay on top
* of the input color.
*
* @param input the color of the background
* @return the color (white or black) of the foreground whichever guarantees
* more readability.
* @since 1.0.0 com.github.kilianB
*/
public static Color getContrastColor(Color input) {
// Luminascense
double y = getLuma(input);
if (y > 0.55) {
return Color.BLACK;
} else {
return Color.WHITE;
}
}

/**
* Return either white or black depending on the supplied color to guarantee
* readability. The contrast color is assumed to be used as text overlay on top
* of the input color.
*
*
* @param input the color of the background
* @return the color (white or black) of the foreground whichever guarantees
* more readability.
Expand All @@ -228,18 +167,18 @@ public static class ColorPalette {

/**
* Return a default palette from blue to orange using rgba interpolation
*
*
* @param numColors the number of colors present in the returned array
* @return A color array with
* @since 1.0.0 com.github.kilianB
*/
public static Color[] getPalette(int numColors) {
return getPalette(numColors, Color.web("#003f5c"), Color.web("#ffa600"));
return getPalette(numColors, Color.decode("#003f5c"), Color.decode("#ffa600"));
}

/**
* Create a color palette using rgba interpolation
*
*
* @param numColors The number of colors present in the returned array
* @param startColor The color of the first index
* @param endColor The color of the last index
Expand All @@ -251,27 +190,41 @@ public static Color[] getPalette(int numColors, Color startColor, Color endColor
Color[] cols = new Color[numColors];
for (int i = 0; i < numColors; i++) {
double factor = i / (double) numColors;
cols[i] = startColor.interpolate(endColor, factor);
cols[i] = interpolate(startColor, endColor, factor);
}
return cols;
}

private static Color interpolate(Color startColor, Color endColor, double factor) {
if (factor < 0) return startColor;
if (factor > 1) return endColor;
return new Color(
interpolate(startColor.getRed(), endColor.getRed(), factor),
interpolate(startColor.getGreen(), endColor.getGreen(), factor),
interpolate(startColor.getBlue(), endColor.getBlue(), factor)
);
}

private static int interpolate(int start, int end, double factor) {
return (int) (start + (end - start) * factor);
}

/**
* Create a color palette with the hue component being altered instead of the
* individual rgb components. {@link #getPalette(int)}.
*
*
* @param numColors The number of colors present in the returned array
* @return An array containing the interpolated colors
* @since 1.0.0 com.github.kilianB
*/
public static Color[] getPaletteHue(int numColors) {
return getPaletteHue(numColors, Color.web("#003f5c"), Color.web("#ffa600"));
return getPaletteHue(numColors, Color.decode("#003f5c"), Color.decode("#ffa600"));
}

/**
* Create a color palette with the hue component being altered instead of the
* individual rgb components. {@link #getPalette(int)}.
*
*
* @param numColors The number of colors present in the returned array
* @param startColor The color of the first index
* @param endColor The color of the last index
Expand All @@ -280,15 +233,17 @@ public static Color[] getPaletteHue(int numColors) {
*/
public static Color[] getPaletteHue(int numColors, Color startColor, Color endColor) {

double hDelta = (endColor.getHue() - startColor.getHue()) / numColors;
double sDelta = (endColor.getSaturation() - startColor.getSaturation()) / numColors;
double bDelta = (endColor.getBrightness() - startColor.getBrightness()) / numColors;
float[] startHsb = Color.RGBtoHSB(startColor.getRed(), startColor.getGreen(), startColor.getBlue(), null);
float[] endHsb = new float[3];
double hDelta = (endHsb[0] - startHsb[0]) / numColors;
double sDelta = (endHsb[1] - startHsb[1]) / numColors;
double bDelta = (endHsb[2] - startHsb[2]) / numColors;

Color[] cols = new Color[numColors];
for (int i = 0; i < numColors; i++) {

double newSat = startColor.getSaturation() + sDelta * i;
double newBrightness = startColor.getBrightness() + bDelta * i;
double newSat = startHsb[1] + sDelta * i;
double newBrightness = startHsb[2] + bDelta * i;

// Wrap around
if (newSat > 1) {
Expand All @@ -302,8 +257,7 @@ public static Color[] getPaletteHue(int numColors, Color startColor, Color endCo
} else if (newBrightness < 0) {
newBrightness = 1 - newBrightness;
}

cols[i] = Color.hsb(startColor.getHue() + hDelta * i, newSat, newBrightness);
cols[i] = new Color(Color.HSBtoRGB((float) (startHsb[0] + hDelta * i), (float) newSat, (float) newBrightness));
}
return cols;
}
Expand Down
Loading