/**
*
*/
package fr.unistra.pelican.util.connectivityTrees.attributes;
import fr.unistra.pelican.util.Tools;
import fr.unistra.pelican.util.connectivityTrees.ComponentNode;
import fr.unistra.pelican.util.connectivityTrees.ComponentTree;
/**
* Compute volume of the node.
* Can work with double or double [] component tree
* In the first case definition of the volume is the traditional one.
* In the other case see my report for the definition of the vectorial volume
*
* @author Benjamin Perret
*
*/
public class AttributeVolume extends ComponentAttribute<Double> {
public AttributeVolume() {
super();
}
public AttributeVolume(Double value) {
super(value);
}
/* (non-Javadoc)
* @see fr.unistra.pelican.algorithms.experimental.perret.CC.Attributes.ComponentAttribute#computeAttribute(fr.unistra.pelican.algorithms.experimental.perret.CC.ComponentNode)
*/
@Override
public <T> void computeAttribute(ComponentTree<T> c) throws UnsupportedDataTypeException{
value = 0.0; // n.getArea();
/*for (ComponentNode<T> child : c.getChildren()) {
AttributeVolume a = new AttributeVolume();
child.add(a);
value += a.computeAttribute(child);// +
// child.getArea()*(child.getLevel()-n.getLevel());
}
ComponentNode<T> parent = c.getParent();
T val = c.getLevel();
if (val instanceof Double) {
if (parent != null) {
value += c.getArea()
* ((Double) val - (Double) parent.getLevel());
} else {
value += c.getArea() * ((Double) val);
}
} else {throw new UnsupportedDataTypeException("Cannot compute attribute volume over datatype " + val.getClass());}
*/ boolean arrayFlag=false;
for( ComponentNode<T> n:c.iterateFromLeafToRoot())
{
value=0.0;
ComponentNode<T> parent = n.getParent();
T val = n.getLevel();
if (val instanceof Double) {
for (ComponentNode<T> child : n.getChildren()) {
value += child.getAttributeValue(this.getClass());// +
// child.getArea()*(child.getLevel()-n.getLevel());
}
if (parent != null) {
value += n.getArea()
* ((Double) val - (Double) parent.getLevel());
} else {
value += n.getArea() * ((Double) val);
}
n.add(new AttributeVolume(value));
} else if (val instanceof double []) {
arrayFlag=true;
//System.out.println("node " +n.location );
double area= n.getArea();
double [] minlvl;
if (parent != null) {
minlvl=Tools.VectorDifference((double [])val, (double [])parent.getLevel());
} else {
minlvl=(double [])val;
}
//System.out.println("val " +ArrayToolbox.printString(val) +"l2-l1 " + ArrayToolbox.printString(minlvl) );
double basePixelVolume=Tools.DotProduct(minlvl, minlvl);
value+=basePixelVolume*area;
for (ComponentNode<T> child : n.getChildren()) {
//System.out.println("->child " + child.location );
value += child.getAttributeValue(this.getClass());
//double [] clevel = (double [])child.getLevel();
double cArea=child.getArea();// +
double [] sum=child.getAttributeValue(AttributeSum.class);
double a = Tools.DotProduct(sum, minlvl);
double b=cArea*Tools.DotProduct((double [])val, minlvl);
//System.out.println("->area " + cArea + " sum " + ArrayToolbox.printString(sum) );
value +=2.0*(a-b);
// child.getArea()*(child.getLevel()-n.getLevel());
}
n.add(new AttributeVolume(value));
} else {throw new UnsupportedDataTypeException("Cannot compute attribute volume over datatype " + val.getClass());}
}
if(arrayFlag)
for( ComponentNode<T> n:c.iterateFromLeafToRoot())
{
ComponentAttribute<Double> v=(ComponentAttribute<Double>)n.getAttribute(AttributeVolume.class);
v.value=Math.sqrt(v.value);
}
return ;
}
/* (non-Javadoc)
* @see fr.unistra.pelican.algorithms.experimental.perret.CC.Attributes.ComponentAttribute#mergeNodes(fr.unistra.pelican.algorithms.experimental.perret.CC.ComponentNode, fr.unistra.pelican.algorithms.experimental.perret.CC.ComponentNode)
*/
@Override
public <T> void mergeWithNode(ComponentNode<T> c) throws UnsupportedDataTypeException{
T val = c.getLevel();
if (val instanceof Double) {
value += (Double)val;
} else {throw new UnsupportedDataTypeException("Cannot compute attribute volume over datatype " + val.getClass());}
return ;
}
}