import java.util.Comparator; import java.util.Iterator; import java.util.Map; import java.util.TreeMap; import java.util.Vector; import java.util.Stack; /** *

* Allows an IInitializer to generate a specification of a * target configuration suitable for formation morphing algorithms. *

* @author Michael Schuresko * @version %I%, %G% * @since 1.1 */ public class MorphTargetAdapter { IInitializer m_init; double m_lfConnectRad; public MorphTargetAdapter() { m_init = null; m_lfConnectRad = 1.0; } public MorphTargetAdapter(IInitializer init) { m_init = init; } public MorphTargetAdapter(IInitializer init, double lfConnectRad) { m_init = init; m_lfConnectRad = lfConnectRad; } public void setConnectRad(double lfConnectRad) { m_lfConnectRad = lfConnectRad; } public void setInitializer(IInitializer init) { m_init = init; } public class VecComp implements Comparator> { public int compare(Vector v1, Vector v2) { if(v1.get(0) < v2.get(0)) { return -1; } if(v1.get(0) == v2.get(0)) { return 0; } return 1; } public boolean equals(Vector v1, Vector v2) { return (v1.get(0) == v2.get(0)); } } public class VecFromArray { double [] m_arrLfLoc; int m_nDim; public VecFromArray(double [] arrLfLoc, int nDim) { m_arrLfLoc = arrLfLoc; m_nDim = nDim; } public Vector getByOffset(int nIdxOff) { Vector vecOut = new Vector(m_nDim); for(int i = 0; i < m_nDim; ++i) { vecOut.add(i,m_arrLfLoc[nIdxOff+i]); } return vecOut; } public Vector getByAgent(int nIdxAgent) { return getByOffset(nIdxAgent*m_nDim); } } public IMorphSpec generate() { MorphSpecStoredVals specOut = new MorphSpecStoredVals(); double arrLfLocs[] = m_init.getInitContState(); int nDim = m_init.getEnv().getDimensionality(); int nNumAgents = arrLfLocs.length/nDim; double arrLfTmpLoc[] = new double[nDim]; TreeMap, Integer> mapPos = new TreeMap, Integer>(new VecComp()); Stack, Integer> > stackAgents = new Stack, Integer> >(); VecFromArray vecFac = new VecFromArray(arrLfLocs, nDim); boolean arrBFound[] = new boolean[nNumAgents]; int i = 0; int nAxis = 0; for(i = 0; i < nNumAgents; ++i) { Vector vecKey = vecFac.getByAgent(i); mapPos.put(vecKey, i); arrBFound[i] = false; } int nParent = 0; Iterator, Integer> > iMapIter = mapPos.entrySet().iterator(); stackAgents.push(iMapIter.next()); while(! stackAgents.isEmpty()) { Map.Entry, Integer> popped = stackAgents.pop(); arrBFound[popped.getValue()] = true; if(popped.getValue() == 0) { for(nAxis = 0; nAxis < nDim; ++nAxis) { arrLfTmpLoc[nAxis] = popped.getKey().get(nAxis); } specOut.addAgent(arrLfTmpLoc, nParent); } Vector vecMinRange = new Vector(popped.getKey()); Vector vecMaxRange = new Vector(popped.getKey()); Vector vecCurrPos = popped.getKey(); vecMinRange.set(0, vecMinRange.get(0) - m_lfConnectRad); vecMaxRange.set(0, vecMaxRange.get(0) + m_lfConnectRad); Iterator, Integer> > iPosPairs = mapPos.subMap(vecMinRange, vecMaxRange).entrySet().iterator(); while(iPosPairs.hasNext()) { Map.Entry, Integer> currEntry = iPosPairs.next(); Integer nObjRep = currEntry.getValue(); Vector vecPosCmp = currEntry.getKey(); double lfDistSum = 0.0; for( nAxis = 0; nAxis < nDim; ++nAxis) { double lfAxisDist = vecCurrPos.get(nAxis) - vecPosCmp.get(nAxis); lfDistSum += lfAxisDist*lfAxisDist; } if(lfDistSum < m_lfConnectRad*m_lfConnectRad && nObjRep.intValue() != i) { if(arrBFound[nObjRep.intValue()] != true) { for(nAxis = 0; nAxis < nDim; ++nAxis) { arrLfTmpLoc[nAxis] = vecPosCmp.get(nAxis); } specOut.addAgent(arrLfTmpLoc, nParent); stackAgents.push(currEntry); arrBFound[nObjRep.intValue()] = true; } } } ++nParent; } specOut.convertVals(); return specOut; } }