From 3bc39be061e0826e5ba9e7be2d38b6db9dd133fd Mon Sep 17 00:00:00 2001 From: jannetty Date: Mon, 5 Aug 2024 11:44:00 +0200 Subject: [PATCH] added inverted division stem cell types --- ...InvertOneStemDaughterStemDaughterBasal.xml | 21 ++ ...woStemDaughtersStemDaughterBasalOrBoth.xml | 25 ++ ...pMUDmutOneStemDaughterStemDaughterLeft.xml | 2 +- ...UDmutOneStemDaughterStemDaughterRandom.xml | 2 +- ...dmutTwoStemDaughtersStemDaughterRandom.xml | 10 +- setup/setupWT.xml | 4 +- .../potts/agent/cell/PottsCellContainer.java | 24 +- .../PottsCellFlyStemInvert1StemBasal.java | 67 +++++ ...ottsCellFlyStemInvert2StemBasalOrBoth.java | 85 ++++++ .../PottsCellFlyStemMUDMut2StemRandom.java | 4 +- ...rationFlyStemOneThirdSplitBasalReturn.java | 246 ++++++++++++++++++ .../potts/env/location/PottsLocation.java | 54 +++- 12 files changed, 529 insertions(+), 15 deletions(-) create mode 100644 setup/setupInvertOneStemDaughterStemDaughterBasal.xml create mode 100644 setup/setupInvertTwoStemDaughtersStemDaughterBasalOrBoth.xml create mode 100644 src/arcade/potts/agent/cell/PottsCellFlyStemInvert1StemBasal.java create mode 100644 src/arcade/potts/agent/cell/PottsCellFlyStemInvert2StemBasalOrBoth.java create mode 100644 src/arcade/potts/agent/module/PottsModuleProliferationFlyStemOneThirdSplitBasalReturn.java diff --git a/setup/setupInvertOneStemDaughterStemDaughterBasal.xml b/setup/setupInvertOneStemDaughterStemDaughterBasal.xml new file mode 100644 index 00000000..55683c48 --- /dev/null +++ b/setup/setupInvertOneStemDaughterStemDaughterBasal.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/setup/setupInvertTwoStemDaughtersStemDaughterBasalOrBoth.xml b/setup/setupInvertTwoStemDaughtersStemDaughterBasalOrBoth.xml new file mode 100644 index 00000000..3b3460ea --- /dev/null +++ b/setup/setupInvertTwoStemDaughtersStemDaughterBasalOrBoth.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/setup/setupMUDmutOneStemDaughterStemDaughterLeft.xml b/setup/setupMUDmutOneStemDaughterStemDaughterLeft.xml index 0a898806..47957600 100644 --- a/setup/setupMUDmutOneStemDaughterStemDaughterLeft.xml +++ b/setup/setupMUDmutOneStemDaughterStemDaughterLeft.xml @@ -13,7 +13,7 @@ - + diff --git a/setup/setupMUDmutOneStemDaughterStemDaughterRandom.xml b/setup/setupMUDmutOneStemDaughterStemDaughterRandom.xml index f1fe70b3..97b40b8a 100644 --- a/setup/setupMUDmutOneStemDaughterStemDaughterRandom.xml +++ b/setup/setupMUDmutOneStemDaughterStemDaughterRandom.xml @@ -13,7 +13,7 @@ - + diff --git a/setup/setupMudmutTwoStemDaughtersStemDaughterRandom.xml b/setup/setupMudmutTwoStemDaughtersStemDaughterRandom.xml index f0cbae3e..dd92a265 100644 --- a/setup/setupMudmutTwoStemDaughtersStemDaughterRandom.xml +++ b/setup/setupMudmutTwoStemDaughtersStemDaughterRandom.xml @@ -5,15 +5,19 @@ - + - + - + + + + + diff --git a/setup/setupWT.xml b/setup/setupWT.xml index 3a371445..63eb1b03 100644 --- a/setup/setupWT.xml +++ b/setup/setupWT.xml @@ -9,11 +9,11 @@ - + - + diff --git a/src/arcade/potts/agent/cell/PottsCellContainer.java b/src/arcade/potts/agent/cell/PottsCellContainer.java index 056842d3..704b2b93 100644 --- a/src/arcade/potts/agent/cell/PottsCellContainer.java +++ b/src/arcade/potts/agent/cell/PottsCellContainer.java @@ -189,7 +189,29 @@ private Cell convert(PottsCellFactory factory, Location location) { null, null); } break; - case "flystemwt": + case "flystem-invert-onestemdaughter-stemdaughterbasal": + if (factory.popToRegions.get(pop)) { + cell = new PottsCellFlyStemInvert1StemBasal(id, parent, pop, state, age, divisions, + location, true, parameters, criticalVolume, criticalHeight, + criticalRegionVolumes, criticalRegionHeights); + } else { + cell = new PottsCellFlyStemInvert1StemBasal(id, parent, pop, state, age, divisions, + location, false, parameters, criticalVolume, criticalHeight, + null, null); + } + break; + case "flystem-invert-twostemdaughters-stemdaughterbasalorboth": + if (factory.popToRegions.get(pop)) { + cell = new PottsCellFlyStemInvert2StemBasalOrBoth(id, parent, pop, state, age, divisions, + location, true, parameters, criticalVolume, criticalHeight, + criticalRegionVolumes, criticalRegionHeights); + } else { + cell = new PottsCellFlyStemInvert2StemBasalOrBoth(id, parent, pop, state, age, divisions, + location, false, parameters, criticalVolume, criticalHeight, + null, null); + } + break; + case "flystem-wt": if (factory.popToRegions.get(pop)) { cell = new PottsCellFlyStemWT(id, parent, pop, state, age, divisions, location, true, parameters, criticalVolume, criticalHeight, diff --git a/src/arcade/potts/agent/cell/PottsCellFlyStemInvert1StemBasal.java b/src/arcade/potts/agent/cell/PottsCellFlyStemInvert1StemBasal.java new file mode 100644 index 00000000..b854f603 --- /dev/null +++ b/src/arcade/potts/agent/cell/PottsCellFlyStemInvert1StemBasal.java @@ -0,0 +1,67 @@ +package arcade.potts.agent.cell; + +import java.util.EnumMap; +import arcade.core.agent.cell.CellState; +import arcade.core.env.location.Location; +import arcade.core.util.MiniBox; +import arcade.potts.agent.module.PottsModuleApoptosisSimple; +import arcade.potts.agent.module.PottsModuleAutosis; +import arcade.potts.agent.module.PottsModuleNecrosis; +import arcade.potts.agent.module.PottsModuleProliferationFlyStemOneThirdSplitBasalReturn; +import arcade.potts.agent.module.PottsModuleQuiescence; +import arcade.potts.util.PottsEnums.Region; +import arcade.potts.util.PottsEnums.State; +import ec.util.MersenneTwisterFast; + +public final class PottsCellFlyStemInvert1StemBasal extends PottsCell{ + + public static final int POTTS_CELL_FLY_NEURON_WT_POP = 2; + + public PottsCellFlyStemInvert1StemBasal(int id, int parent, int pop, CellState state, int age, int divisions, + Location location, boolean hasRegions, MiniBox parameters, + double criticalVolume, double criticalHeight, + EnumMap criticalRegionVolumes, + EnumMap criticalRegionHeights) { + super(id, parent, pop, state, age, divisions, location, hasRegions, parameters, + criticalVolume, criticalHeight, criticalRegionVolumes, criticalRegionHeights); + } + + @Override + public PottsCell make(int newID, CellState newState, Location newLocation, + MersenneTwisterFast random) { + divisions++; + MiniBox newParameters = new MiniBox(); + for (String key : this.getParameters().getKeys()) { + newParameters.put(key, this.getParameters().get(key)); + } + newParameters.put("proliferation/CELL_GROWTH_RATE", "0"); + return new PottsCellFlyNeuronWT(newID, id, POTTS_CELL_FLY_NEURON_WT_POP, newState, age, divisions, newLocation, + hasRegions, newParameters, criticalVolume, criticalHeight, + criticalRegionVolumes, criticalRegionHeights); + } + + @Override + void setStateModule(CellState newState) { + switch ((State) newState) { + case QUIESCENT: + module = new PottsModuleQuiescence(this); + break; + case PROLIFERATIVE: + module = new PottsModuleProliferationFlyStemOneThirdSplitBasalReturn(this); + break; + case APOPTOTIC: + module = new PottsModuleApoptosisSimple(this); + break; + case NECROTIC: + module = new PottsModuleNecrosis(this); + break; + case AUTOTIC: + module = new PottsModuleAutosis(this); + break; + default: + // State must be one of the above cases. + module = null; + break; + } + } +} diff --git a/src/arcade/potts/agent/cell/PottsCellFlyStemInvert2StemBasalOrBoth.java b/src/arcade/potts/agent/cell/PottsCellFlyStemInvert2StemBasalOrBoth.java new file mode 100644 index 00000000..85f7b6ff --- /dev/null +++ b/src/arcade/potts/agent/cell/PottsCellFlyStemInvert2StemBasalOrBoth.java @@ -0,0 +1,85 @@ +package arcade.potts.agent.cell; + +import java.util.EnumMap; +import arcade.core.agent.cell.CellState; +import arcade.core.env.location.Location; +import arcade.core.util.MiniBox; +import arcade.potts.agent.module.PottsModuleApoptosisSimple; +import arcade.potts.agent.module.PottsModuleAutosis; +import arcade.potts.agent.module.PottsModuleNecrosis; +import arcade.potts.agent.module.PottsModuleProliferationFlyStemOneThirdSplitBasalReturn; +import arcade.potts.agent.module.PottsModuleQuiescence; +import arcade.potts.util.PottsEnums.Region; +import arcade.potts.util.PottsEnums.State; +import ec.util.MersenneTwisterFast; + +public final class PottsCellFlyStemInvert2StemBasalOrBoth extends PottsCell{ + + public static final int POTTS_STEM_INVERT_2_POP = 1; + public static final int POTTS_CELL_FLY_NEURON_WT_POP = 2; + public static final int POTTS_STEM_WT_POP = 3; + + public PottsCellFlyStemInvert2StemBasalOrBoth(int id, int parent, int pop, CellState state, int age, int divisions, + Location location, boolean hasRegions, MiniBox parameters, + double criticalVolume, double criticalHeight, + EnumMap criticalRegionVolumes, + EnumMap criticalRegionHeights) { + super(id, parent, pop, state, age, divisions, location, hasRegions, parameters, + criticalVolume, criticalHeight, criticalRegionVolumes, criticalRegionHeights); + } + + @Override + public PottsCell make(int newID, CellState newState, Location newLocation, + MersenneTwisterFast random) { + divisions++; + // 25% chance of making PottsCellFlyStemWT, 25% chance of making PottsCellFlyStemInvert2StemRandom 50% chance of making FlyNeuronWT + if (random.nextDouble() < 0.25) { + System.out.println("Making new PottsCellFlyStemWT"); + System.out.println("Inside make method, growth rate is " + this.getParameters().get("proliferation/CELL_GROWTH_RATE")); + return new PottsCellFlyStemWT(newID, id, POTTS_STEM_WT_POP, newState, age, divisions, newLocation, + hasRegions, this.getParameters(), criticalVolume, criticalHeight, + criticalRegionVolumes, criticalRegionHeights); + } else if (random.nextDouble() < 0.5) { + System.out.println("Making new PottsCellFlyStemInvert2StemRandom"); + System.out.println("Inside make method, growth rate is " + this.getParameters().get("proliferation/CELL_GROWTH_RATE")); + return new PottsCellFlyStemInvert2StemBasalOrBoth(newID, id, POTTS_STEM_INVERT_2_POP, newState, age, divisions, newLocation, + hasRegions, this.getParameters(), criticalVolume, criticalHeight, + criticalRegionVolumes, criticalRegionHeights); + } else { + System.out.println("Making new FlyNeuronWT"); + MiniBox newParameters = new MiniBox(); + for (String key : this.getParameters().getKeys()) { + newParameters.put(key, this.getParameters().get(key)); + } + newParameters.put("proliferation/CELL_GROWTH_RATE", "0"); + return new PottsCellFlyNeuronWT(newID, id, POTTS_CELL_FLY_NEURON_WT_POP, newState, age, divisions, newLocation, + hasRegions, newParameters, criticalVolume, criticalHeight, + criticalRegionVolumes, criticalRegionHeights); + } + } + + @Override + void setStateModule(CellState newState) { + switch ((State) newState) { + case QUIESCENT: + module = new PottsModuleQuiescence(this); + break; + case PROLIFERATIVE: + module = new PottsModuleProliferationFlyStemOneThirdSplitBasalReturn(this); + break; + case APOPTOTIC: + module = new PottsModuleApoptosisSimple(this); + break; + case NECROTIC: + module = new PottsModuleNecrosis(this); + break; + case AUTOTIC: + module = new PottsModuleAutosis(this); + break; + default: + // State must be one of the above cases. + module = null; + break; + } + } +} diff --git a/src/arcade/potts/agent/cell/PottsCellFlyStemMUDMut2StemRandom.java b/src/arcade/potts/agent/cell/PottsCellFlyStemMUDMut2StemRandom.java index 9a526654..2b70f757 100644 --- a/src/arcade/potts/agent/cell/PottsCellFlyStemMUDMut2StemRandom.java +++ b/src/arcade/potts/agent/cell/PottsCellFlyStemMUDMut2StemRandom.java @@ -16,7 +16,7 @@ public final class PottsCellFlyStemMUDMut2StemRandom extends PottsCell{ public static final int POTTS_CELL_FLY_NEURON_WT_POP = 2; - public static final int POTTS_STEM_POP = 1; + public static final int POTTS_STEM_1_POP = 3;; public PottsCellFlyStemMUDMut2StemRandom(int id, int parent, int pop, CellState state, int age, int divisions, Location location, boolean hasRegions, MiniBox parameters, @@ -42,7 +42,7 @@ public PottsCell make(int newID, CellState newState, Location newLocation, } else if (random.nextDouble() < 0.5) { System.out.println("Making new MUDMut1StemRandom"); System.out.println("Inside make method, growth rate is " + this.getParameters().get("proliferation/CELL_GROWTH_RATE")); - return new PottsCellFlyStemMUDMut1StemRandom(newID, id, pop, newState, age, divisions, newLocation, + return new PottsCellFlyStemMUDMut1StemRandom(newID, id, POTTS_STEM_1_POP, newState, age, divisions, newLocation, hasRegions, this.getParameters(), criticalVolume, criticalHeight, criticalRegionVolumes, criticalRegionHeights); } else { diff --git a/src/arcade/potts/agent/module/PottsModuleProliferationFlyStemOneThirdSplitBasalReturn.java b/src/arcade/potts/agent/module/PottsModuleProliferationFlyStemOneThirdSplitBasalReturn.java new file mode 100644 index 00000000..c65b42a9 --- /dev/null +++ b/src/arcade/potts/agent/module/PottsModuleProliferationFlyStemOneThirdSplitBasalReturn.java @@ -0,0 +1,246 @@ +package arcade.potts.agent.module; + +import sim.util.distribution.Poisson; +import ec.util.MersenneTwisterFast; +import arcade.core.env.location.Location; +import arcade.core.sim.Simulation; +import arcade.core.util.MiniBox; +import arcade.potts.agent.cell.PottsCell; +import arcade.potts.env.location.PottsLocation; +import arcade.potts.env.location.PottsLocations; +import arcade.potts.sim.Potts; +import arcade.potts.sim.PottsSimulation; +import static arcade.potts.util.PottsEnums.Phase; +import static arcade.potts.util.PottsEnums.Region; +import static arcade.potts.util.PottsEnums.State; + +/** + * Extension of {@link PottsModuleProliferation} with Poisson transitions. + */ + +public class PottsModuleProliferationFlyStemOneThirdSplitBasalReturn extends PottsModuleProliferation { + /** Threshold for critical volume size checkpoint. */ + static final double SIZE_CHECKPOINT = 0.95; + + /** Target ratio of critical volume for division size checkpoint. */ + static final double SIZE_TARGET = 2; + + /** Event rate for G1 phase (steps/tick). */ + final double rateG1; + + /** Event rate for S phase (steps/tick). */ + final double rateS; + + /** Event rate for G2 phase (steps/tick). */ + final double rateG2; + + /** Event rate for M phase (steps/tick). */ + final double rateM; + + /** Steps for G1 phase (steps). */ + final int stepsG1; + + /** Steps for S phase (steps). */ + final int stepsS; + + /** Steps for G2 phase (steps). */ + final int stepsG2; + + /** Steps for M phase (steps). */ + final int stepsM; + + /** Overall growth rate for cell (voxels/tick). */ + final double cellGrowthRate; + + /** Overall growth rate for nucleus (voxels/tick). */ + final double nucleusGrowthRate; + + /** Basal rate of apoptosis (ticks^-1). */ + final double basalApoptosisRate; + + /** Fraction of nuclear volume when condensed. */ + final double nucleusCondFraction; + + /** + * Creates a simple proliferation {@code Module} for the given + * {@link PottsCell}. + * + * @param cell the {@link PottsCell} the module is associated with + */ + public PottsModuleProliferationFlyStemOneThirdSplitBasalReturn(PottsCell cell) { + super(cell); + + MiniBox parameters = cell.getParameters(); + rateG1 = parameters.getDouble("proliferation/RATE_G1"); + rateS = parameters.getDouble("proliferation/RATE_S"); + rateG2 = parameters.getDouble("proliferation/RATE_G2"); + rateM = parameters.getDouble("proliferation/RATE_M"); + stepsG1 = parameters.getInt("proliferation/STEPS_G1"); + stepsS = parameters.getInt("proliferation/STEPS_S"); + stepsG2 = parameters.getInt("proliferation/STEPS_G2"); + stepsM = parameters.getInt("proliferation/STEPS_M"); + cellGrowthRate = parameters.getDouble("proliferation/CELL_GROWTH_RATE"); + nucleusGrowthRate = parameters.getDouble("proliferation/NUCLEUS_GROWTH_RATE"); + basalApoptosisRate = parameters.getDouble("proliferation/BASAL_APOPTOSIS_RATE"); + nucleusCondFraction = parameters.getDouble("proliferation/NUCLEUS_CONDENSATION_FRACTION"); + } + + /** + * {@inheritDoc} + *

+ * Cell increases in size toward a target of twice its critical size at a + * rate of {@code CELL_GROWTH_RATE}. Cell will transition to S phase after + * completing {@code STEPS_G1} steps at an average rate of {@code RATE_G1}. + * At each tick, cell may randomly apoptosis at a basal rate of + * {@code BASAL_APOPTOSIS_RATE}. + */ + @Override + void stepG1(MersenneTwisterFast random) { + // Random chance of apoptosis. + if (random.nextDouble() < basalApoptosisRate) { + cell.setState(State.APOPTOTIC); + return; + } + + // Increase size of cell. + cell.updateTarget(cellGrowthRate, SIZE_TARGET); + + // Increase size of nucleus (if cell has regions). + if (cell.hasRegions() + && cell.getVolume(Region.NUCLEUS) > cell.getCriticalVolume(Region.NUCLEUS)) { + cell.updateTarget(Region.NUCLEUS, nucleusGrowthRate, SIZE_TARGET); + } + + // Check for phase transition. + Poisson poisson = poissonFactory.createPoisson(rateG1, random); + currentSteps += poisson.nextInt(); + if (currentSteps >= stepsG1) { + setPhase(Phase.PROLIFERATIVE_S); + } + } + + /** + * {@inheritDoc} + *

+ * Cell increases in size toward a target of twice its critical size at a + * rate of {@code CELL_GROWTH_RATE}. Cell will transition to G2 phase after + * completing {@code STEPS_S} steps at an average rate of {@code RATE_S}. + */ + @Override + void stepS(MersenneTwisterFast random) { + // Increase size of cell. + cell.updateTarget(cellGrowthRate, SIZE_TARGET); + + // Increase size of nucleus (if cell has regions). + if (cell.hasRegions()) { + cell.updateTarget(Region.NUCLEUS, nucleusGrowthRate, SIZE_TARGET); + } + + // Check for phase transition. + Poisson poisson = poissonFactory.createPoisson(rateS, random); + currentSteps += poisson.nextInt(); + if (currentSteps >= stepsS) { + setPhase(Phase.PROLIFERATIVE_G2); + } + } + + /** + * {@inheritDoc} + *

+ * Cell increases in size toward a target of twice its critical size at a + * rate of {@code CELL_GROWTH_RATE}. Cell will transition to M phase after + * completing {@code STEPS_G2} steps at an average rate of {@code RATE_G2}. + * At each tick, cell may randomly apoptosis at a basal rate of + * {@code BASAL_APOPTOSIS_RATE}. + */ + @Override + void stepG2(MersenneTwisterFast random) { + // Random chance of apoptosis. + if (random.nextDouble() < basalApoptosisRate) { + cell.setState(State.APOPTOTIC); + return; + } + + // Increase size of cell. + cell.updateTarget(cellGrowthRate, SIZE_TARGET); + boolean sizeCheck = cell.getVolume() >= SIZE_CHECKPOINT + * SIZE_TARGET * cell.getCriticalVolume(); + + // Increase size of nucleus (if cell has regions). + boolean sizeRegionCheck = true; + if (cell.hasRegions()) { + cell.updateTarget(Region.NUCLEUS, nucleusGrowthRate, SIZE_TARGET); + sizeRegionCheck = cell.getVolume(Region.NUCLEUS) >= SIZE_CHECKPOINT + * SIZE_TARGET * cell.getCriticalVolume(Region.NUCLEUS); + } + + // Check for phase transition. + Poisson poisson = poissonFactory.createPoisson(rateG2, random); + currentSteps += poisson.nextInt(); + if (currentSteps >= stepsG2 && sizeCheck && sizeRegionCheck) { + setPhase(Phase.PROLIFERATIVE_M); + } + } + + /** + * {@inheritDoc} + *

+ * Cell increases in size toward a target of twice its critical size at a + * rate of {@code CELL_GROWTH_RATE}. Cell will complete cell division after + * completing {@code STEPS_M} steps at an average rate of {@code RATE_M}. + * Cell must be greater than {@code SIZE_CHECKPOINT} times the critical + * size. + */ + @Override + void stepM(MersenneTwisterFast random, Simulation sim) { + // Increase size of cell. + cell.updateTarget(cellGrowthRate, SIZE_TARGET); + + // Update size of nucleus (if cell has regions). + if (cell.hasRegions()) { + double regionVolume = cell.getVolume(Region.NUCLEUS); + double criticalVolume = cell.getCriticalVolume(Region.NUCLEUS); + + if (regionVolume > criticalVolume) { + int target = (int) (nucleusCondFraction * criticalVolume); + + Potts potts = ((PottsSimulation) sim).getPotts(); + PottsLocations location = (PottsLocations) cell.getLocation(); + location.distribute(Region.NUCLEUS, target, random); + location.update(cell.getID(), potts.ids, potts.regions); + + cell.setTargets(Region.DEFAULT, cell.getVolume(Region.DEFAULT), + cell.getSurface(Region.DEFAULT)); + cell.setTargets(Region.NUCLEUS, cell.getVolume(Region.NUCLEUS), + cell.getSurface(Region.NUCLEUS)); + } + } + + // Check for phase transition. + Poisson poisson = poissonFactory.createPoisson(rateM, random); + currentSteps += poisson.nextInt(); + if (currentSteps >= stepsM) { + addCell(random, sim); + setPhase(Phase.PROLIFERATIVE_G1); + } + } + + @Override + void addCell(MersenneTwisterFast random, Simulation sim) { + Potts potts = ((PottsSimulation) sim).getPotts(); + + // Split current location. + Location newLocation = ((PottsLocation) cell.getLocation()).splitOneThirdTwoThirdsKeepBottomTwoThirds(random); //TODO: SOPHIA CHANGE THIS + + // Reset current cell. + cell.reset(potts.ids, potts.regions); + + // Create and schedule new cell. + int newID = sim.getID(); + PottsCell newCell = (PottsCell) cell.make(newID, State.PROLIFERATIVE, newLocation, random); + sim.getGrid().addObject(newCell, null); + potts.register(newCell); + newCell.reset(potts.ids, potts.regions); + newCell.schedule(sim.getSchedule()); + } +} diff --git a/src/arcade/potts/env/location/PottsLocation.java b/src/arcade/potts/env/location/PottsLocation.java index 04e1ea76..17d30f13 100644 --- a/src/arcade/potts/env/location/PottsLocation.java +++ b/src/arcade/potts/env/location/PottsLocation.java @@ -333,9 +333,6 @@ public Location splitHalvesVerticallyReturnLeftHalf(MersenneTwisterFast random) connectVoxels(voxelsA, voxelsB, this, random); balanceVoxels(voxelsA, voxelsB, this, random); - // Print that we are in this function - System.out.println("Splitting vertically and returning left half"); - // Return left half return separateVoxels(voxelsA, voxelsB, random); } @@ -343,7 +340,7 @@ public Location splitHalvesVerticallyReturnLeftHalf(MersenneTwisterFast random) public Location splitTwoThirdsOneThirdKeepTopTwoThirds(MersenneTwisterFast random) { //TODO: SOPHIA MOVE THIS OUT OF POTTSLOCATION // Get voxel x centered y 2/3 down. - Voxel splitPoint = getTopThird(); + Voxel splitPoint = getTopTwoThirds(); // Initialize lists of split voxels. ArrayList voxelsA = new ArrayList<>(); @@ -360,7 +357,7 @@ public Location splitTwoThirdsOneThirdKeepTopTwoThirds(MersenneTwisterFast rando return separateVoxels(voxelsA, voxelsB, random); } - public Voxel getTopThird() { + public Voxel getTopTwoThirds() { if (voxels.size() == 0) { return null; } @@ -387,6 +384,53 @@ public Voxel getTopThird() { return new Voxel(x, y, z); } + + public Voxel getTopOneThird(){ + if (voxels.size() == 0) { + return null; + } + + // get min y voxel + //get max y voxel + int minVoxelY = Integer.MAX_VALUE; + int maxVoxelY = Integer.MIN_VALUE; + + for (Voxel voxel : voxels) { + if (voxel.y < minVoxelY) { + minVoxelY = voxel.y; + } + if (voxel.y > maxVoxelY) { + maxVoxelY = voxel.y; + } + } + + double oneThirdDownY = minVoxelY + (maxVoxelY - minVoxelY) * 1.0 / 3.0; + + int x = (int) Math.round(cx); + int y = (int) Math.round(oneThirdDownY); + int z = (int) Math.round(cz); + + return new Voxel(x, y, z); + } + + public Location splitOneThirdTwoThirdsKeepBottomTwoThirds(MersenneTwisterFast random) { //TODO: SOPHIA MOVE THIS OUT OF POTTSLOCATION + // Get voxel x centered y 2/3 down. + Voxel splitPoint = getTopOneThird(); + + // Initialize lists of split voxels. + ArrayList voxelsA = new ArrayList<>(); + ArrayList voxelsB = new ArrayList<>(); + + // Get split direction. + Direction direction = Direction.ZX_PLANE; + splitVoxels(direction, voxels, voxelsA, voxelsB, splitPoint, random); + + // Ensure that voxel split is connected and balanced. + connectVoxels(voxelsA, voxelsB, this, random); + + // Keep the 2/3 region for this location, return other. + return separateVoxels(voxelsB, voxelsA, random); + } /** * Gets the voxel at the center of the location.