package org.chesmapper.view.cluster;
import java.util.ArrayList;
import java.util.List;
import javax.vecmath.Vector3f;
import org.mg.javalib.util.Vector3fUtil;
public class ClusteringUtil
{
public static List<Vector3f> getClusterPositions(ClusteringImpl c)
{
List<Vector3f> list = new ArrayList<Vector3f>();
for (Cluster cc : c.getClusters())
if (cc.getNumCompounds() > 0)
list.add(cc.getCenter(true));
return list;
}
public static List<Vector3f> getCompoundPositions(ZoomableCompoundGroup c)
{
List<Vector3f> list = new ArrayList<Vector3f>();
for (Compound m : c.getCompounds())
list.add(m.getPosition());
return list;
}
public static Vector3f[] getCompoundPositions(ClusteringImpl c)
{
return getCompoundPositions(c, true);
}
private static Vector3f[] getCompoundPositions(ClusteringImpl c, boolean scale)
{
Vector3f list[] = new Vector3f[c.getNumCompounds(true)];
int i = 0;
for (Compound m : c.getCompounds(true))
list[i++] = m.getPosition(scale);
return list;
}
public static int COMPOUND_SIZE_MAX = 40;
public static int COMPOUND_SIZE = 20;
public static float SCALE = 0;
/**
* scale factor is used to scale the original 3d mapping values
*
* @param v
* @return
*/
public static void updateScaleFactor(ClusteringImpl c)
{
Vector3f[] v = ClusteringUtil.getCompoundPositions(c, false);
// the average min distance mean distance of each compound to its closest neighbor compound
float d = Vector3fUtil.avgMinDist(v);
if (d == 0)
d = 1;
// the smaller the distance, the higher the scale factor
// the neigbhor should be on average 30units away
float s = 1 / d * 30;
//Settings.LOGGER.debug("min avg distance: " + d + " -> scale: " + s);
// we want to limit the scale based on the max dist
float maxD = Vector3fUtil.maxDist(v);
float max_scale = 100 / maxD;
if (max_scale < s)
{
//Settings.LOGGER.debug("override scale\nmax distance: " + maxD + " -> scale: " + max_scale);
s = max_scale;
}
if (COMPOUND_SIZE < 0 || COMPOUND_SIZE > COMPOUND_SIZE_MAX)
throw new Error("illegal compound size");
// convert "int range 0 - COMPOUND_SIZE_MAX" to "float range 4.0 - 0.1"
float density = (float) (((1 - COMPOUND_SIZE / ((double) COMPOUND_SIZE_MAX)) * 3.9f) + 0.1f);
//Settings.LOGGER.debug("compound size: " + ClusteringUtil.COMPOUND_SIZE + " -> scale multiplier: " + density);
// scale is multiplied with the DENSITY, which is configurable by the user
SCALE = s * density;
}
}