/**
*
*/
package cz.cuni.mff.peckam.java.origamist.unused.utils;
import static cz.cuni.mff.peckam.java.origamist.math.MathHelper.EPSILON;
import java.util.Map;
import java.util.SortedMap;
import javax.vecmath.Tuple3d;
import cz.cuni.mff.peckam.java.origamist.math.Line3d;
import cz.cuni.mff.peckam.java.origamist.unused.math.CanonicLine3d;
/**
* A map that has lines as keys, and can be accessed in epsilon-equals way.
*
* @author Martin Pecka
*/
public class Line3dMap<V> extends EpsilonRedBlackTree<CanonicLine3d, V, Double>
{
/** */
private static final long serialVersionUID = 1989427767196076752L;
/**
* Create a new map with lines as keys.
*/
public Line3dMap()
{
super(getEpsilonComparator(0d), getEpsilonComparator(EPSILON));
}
/**
* Create a new Line3dMap with entries from the given map. Use the default comparator to compare the keys. The keys
* must implement {@link Comparable}<K>.
*
* @param m The map to take entries from.
*
* @throws ClassCastException If a key from the given map doesn't implement the {@link Comparable}<K>
* interface.
* @throws NullPointerException If <code>m == null</code> or if the map contains a <code>null</code> key and the
* comparator doesn't support it.
*/
public Line3dMap(Map<? extends CanonicLine3d, ? extends V> m)
{
super(m, getEpsilonComparator(EPSILON));
}
/**
* Create a new Line3dMap with entries from the given sorted map. The map's comparator is used. This is an effective
* (linear time) algorithm.
*
* @param m The sorted map to take entries from.
*/
public Line3dMap(SortedMap<CanonicLine3d, ? extends V> m)
{
super(m, getEpsilonComparator(EPSILON));
}
/**
* Return a comparator comparing two epsilon-equal values as equal.
*
* @param epsilon The epsilon to use.
* @return A comparator comparing two epsilon-equal values as equal.
*/
protected static EpsilonComparator<? super CanonicLine3d, Double> getEpsilonComparator(final double epsilon)
{
return new EpsilonComparator<CanonicLine3d, Double>() {
@Override
public int compare(CanonicLine3d o1, CanonicLine3d o2)
{
return compare(o1, o2, epsilon);
}
@Override
public int compare(CanonicLine3d o1, CanonicLine3d o2, Double eps)
{
int cmp1 = compare(o1.getVector(), o2.getVector(), eps);
if (cmp1 != 0)
return cmp1;
return compare(o1.getPoint(), o2.getPoint(), eps);
}
protected int compare(Tuple3d t1, Tuple3d t2, Double eps)
{
int cmp1 = compare(t1.x, t2.x, eps);
if (cmp1 != 0)
return cmp1;
int cmp2 = compare(t1.y, t2.y, eps);
if (cmp2 != 0)
return cmp2;
return compare(t1.z, t2.z, eps);
}
protected int compare(Double d1, Double d2, Double eps)
{
double diff = d1 - d2;
if (diff < -eps)
return -1;
else if (diff > eps)
return 1;
else
return 0;
}
};
}
/**
* If the given line is not canonic, canonicalize it. Otherwise works the same way as
* {@link EpsilonMap#epsilonGet(Object)} does.
*
* @see EpsilonMap#epsilonGet(Object)
*/
public V epsilonGet(Line3d key)
{
return epsilonGet(new CanonicLine3d(key));
}
/**
* @see EpsilonRedBlackTree#epsilonGet(Object, boolean)
*/
public V epsilonGet(Line3d key, boolean surelyContains)
{
return super.epsilonGet(new CanonicLine3d(key), surelyContains);
}
/**
* If the given line is not canonic, canonicalize it. Otherwise works the same way as
* {@link EpsilonMap#epsilonPut(Object, Object)} does.
*
* @see EpsilonMap#epsilonPut(Object, Object)
*/
public V epsilonPut(Line3d key, V value)
{
return super.epsilonPut(new CanonicLine3d(key), value);
}
/**
* If the given line is not canonic, canonicalize it. Otherwise works the same way as
* {@link EpsilonMap#epsilonRemove(Object)} does.
*
* @see EpsilonMap#epsilonRemove(Object)
*/
public V epsilonRemove(Line3d key)
{
return super.epsilonRemove(new CanonicLine3d(key));
}
/**
* @see EpsilonRedBlackTree#epsilonRemove(Object, boolean)
*/
public V epsilonRemove(Line3d key, boolean surelyContains)
{
return super.epsilonRemove(new CanonicLine3d(key), surelyContains);
}
/**
* If the given line is not canonic, canonicalize it. Otherwise works the same way as
* {@link EpsilonMap#epsilonContainsKey(Object)} does.
*
* @see EpsilonMap#epsilonContainsKey(Object)
*/
public boolean epsilonContainsKey(Line3d key)
{
return super.epsilonContainsKey(new CanonicLine3d(key));
}
@Override
protected RedBlackTree<CanonicLine3d, V>.TreePath epsilonGetPathSequentially(CanonicLine3d key)
{
if (root == null)
return new TreePath();
TreePath path = epsilonGetPath(firstKey());
while (path.size() > 0) {
if (epsilonComparator.compare(path.getLast().key, key, 2 * EPSILON) == 0)
return path;
path.moveToSuccesor();
}
return path;
}
}