private double getDiameterFromCell(final Optional<? extends CellWithCircularArea> biggest) { return biggest .transform(n -> n instanceof CircularDeformableCell ? ((CircularDeformableCell) n).getMaxDiameter() : n.getDiameter()) .or(0d); } }
/** * Initialize an Action that move the cell of a given space delta, which can be expressed in percent of the cell's diameter or in absolute. * If the cell has diameter 0, the only way to express delta is absolute. * There's no way to decide the direction of the cell by this {@link Action}. This is inferred by the polarization vector contained in the cell. * * @param environment the {@link Environment} * @param node the {@link Node} in which the {@link Action} is contained. This can be only a CellNode. * @param inPercent a boolean parameter which set the way of expressing delta: if is true the cell movement will be (delta * cellDiameter), otherwise will be simply delta. If cellDiameter is zero, this {@link Action} will in both cases behave like inPercent == false. * @param delta the distance at which the cell will be moved. */ public CellMove(final Environment<Double> environment, final Node<Double> node, final boolean inPercent, final double delta) { super(environment, node); this.inPer = inPercent; if (node instanceof CellNode) { if (inPercent) { if (node instanceof CellWithCircularArea && ((CellWithCircularArea) node).getRadius() != 0) { this.delta = ((CellWithCircularArea) node).getDiameter() * delta; } else { throw new IllegalArgumentException("Can't set distance in percent of the cell's diameter if cell has not a diameter"); } } else { this.delta = delta; } } else { throw new UnsupportedOperationException("CellMove can be setted only in cells."); } }
@Override protected void nodeAdded(final Node<Double> node, final Position position, final Neighborhood<Double> neighborhood) { super.nodeAdded(node, position, neighborhood); if (node instanceof CellWithCircularArea) { final CellWithCircularArea cell = (CellWithCircularArea) node; if (cell.getDiameter() > getMaxDiameterAmongCellWithCircularShape()) { biggestCellWithCircularArea = Optional.of(cell); } } if (node instanceof CircularDeformableCell) { final CircularDeformableCell cell = (CircularDeformableCell) node; if (cell.getMaxDiameter() > getMaxDiameterAmongCircularDeformableCells()) { biggestCircularDeformableCell = Optional.of(cell); } } }
@Override protected boolean nodeShouldBeAdded(final Node<Double> node, final Position p) { final boolean isWithinLimits = super.nodeShouldBeAdded(node, p); if (isWithinLimits) { if (node instanceof CellWithCircularArea) { final CellWithCircularArea thisNode = (CellWithCircularArea) node; double range = getMaxDiameterAmongCellWithCircularShape(); if (thisNode.getDiameter() > range) { range = thisNode.getDiameter(); } final double nodeRadius = thisNode.getRadius(); return isWithinLimits && (range <= 0 || !getNodesWithinRange(p, range).stream() .filter(n -> n instanceof CellWithCircularArea) .map(n -> (CellWithCircularArea) n) .filter(n -> getPosition(n).getDistanceTo(p) < nodeRadius + n.getRadius()) .findFirst() .isPresent()); } else { return true; } } else { return false; } }
.parallel() .filter(n -> n instanceof CellWithCircularArea) .mapToDouble(n -> ((CellWithCircularArea) n).getDiameter()) .max() .orElse(0);