From 8c423bdf4f698abf90e5b107e6d0fc4fa688d637 Mon Sep 17 00:00:00 2001 From: Daniel Bergman Date: Mon, 8 Sep 2025 05:53:41 -0400 Subject: [PATCH] fix division displacement - division vector was not normalized after orthogonal projection onto orientation-defined plane - this would lead to inconsistent displacements - e.g. in 2D, a rand_vec of (0,0,1) would lead to 0 displacement - the daughter cell was displaced by the full radius and the parent cell by half the radius in the opposite direction - this led to a center of mass shift (in the rand_vec direction) of radius/4 - now, both are displaced by half the radius in opposite directions, preserving center of mass - by using 1/2 the radius, the cells will remain overlapping, which the mechanics module will resolve over time --- core/PhysiCell_cell.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/core/PhysiCell_cell.cpp b/core/PhysiCell_cell.cpp index a14c70b99..ca6e30d8d 100644 --- a/core/PhysiCell_cell.cpp +++ b/core/PhysiCell_cell.cpp @@ -609,10 +609,15 @@ Cell* Cell::divide( ) rand_vec *= radius; // multiply direction times the displacement */ + // direction to displace daughter cell std::vector rand_vec = cell_division_orientation(); + // make it orthogonal to the cell's orientation rand_vec = rand_vec- phenotype.geometry.polarity*(rand_vec[0]*state.orientation[0]+ rand_vec[1]*state.orientation[1]+rand_vec[2]*state.orientation[2])*state.orientation; - rand_vec *= phenotype.geometry.radius; + // make sure it is a unit vector + normalize( &rand_vec ); + // push the cells far enough apart to avoid strong overlap, but still maintain some overlap + rand_vec *= 0.5 * phenotype.geometry.radius; child->assign_position(position[0] + rand_vec[0], position[1] + rand_vec[1], @@ -620,8 +625,8 @@ Cell* Cell::divide( ) //change my position to keep the center of mass intact // and then see if I need to update my voxel index - static double negative_one_half = -0.5; - axpy( &position, negative_one_half , rand_vec ); // position = position - 0.5*rand_vec; + static double negative_one = -1.0; + axpy( &position, negative_one , rand_vec ); // position = position - rand_vec; //If this cell has been moved outside of the boundaries, mark it as such. //(If the child cell is outside of the boundaries, that has been taken care of in the assign_position function.)