protected IPlantCell GetClosestCellTowards(IFluidCarrier <TFluid> carrier, IEnumerable <IPlantCell> neighbors)
        {
            var currentPoint = new Vector2(carrier.Current.Geometry.TopCenter.X, carrier.Current.Geometry.TopCenter.Z);

            float lowestDistance = float.MaxValue;

            IPlantCell closestCell = null;

            foreach (var neighbor in neighbors)
            {
                if (neighbor.Equals(carrier.ClosestTransportCell))
                {
                    return(neighbor);
                }

                var neighboringPoint = new Vector2(neighbor.Geometry.TopCenter.X, neighbor.Geometry.TopCenter.Z);

                float dist = Vector2.Distance(currentPoint, neighboringPoint);

                if (dist < lowestDistance)
                {
                    lowestDistance = dist;
                    closestCell    = neighbor;
                }
            }

            return(closestCell);
        }
Esempio n. 2
0
        private IPlantCell ClosestTransporterCell(PlantCellType type, IPlantCell current, IEnumerable <IPlantCell> cells)
        {
            float closestDistance = float.MaxValue;

            IPlantCell closestCell = null;

            foreach (var cell in cells)
            {
                if (cell.CellType != type)
                {
                    continue;
                }

                float distance = Vector3.Distance(cell.Geometry.TopCenter, current.Geometry.TopCenter);

                if (distance < closestDistance)
                {
                    closestDistance = distance;
                    closestCell     = cell;
                }
            }

            if (closestCell == null)
            {
                logger.LogFatal("Could not find closest cell of type {CellType} for cell at {Cell}", type, current.Geometry.TopCenter);
            }

            return(closestCell);
        }
        private void ResizeFace(IPlantCell aCell, IPlantCell bCell)
        {
            var aGeo  = aCell.Geometry;
            var aFace = aGeo.Face.Points;

            var bGeo  = bCell.Geometry;
            var bFace = bGeo.Face.Points;

            var pairs = geometryHelper.CreateFacePairs(bFace);

            for (int i = 0; i < aFace.Length; i++)
            {
                if (!geometryHelper.IsInsidePolygon(aFace[i], bFace))
                {
                    continue;
                }

                Vector2 nearest = FindNearestPoint(aFace[i], pairs);

                Vector2 direction = (aFace[i] - nearest) * aCell.Turgidity;

                aFace[i] = nearest;

                ChangeFace(aGeo, aFace[i], direction);
            }
        }
 public void Delete(IPlantCell cell)
 {
     if (carriers.ContainsKey(cell))
     {
         carriers.Remove(cell);
     }
 }
Esempio n. 5
0
        public void CreateCell_WhenCreatingCornPlant_ShouldHaveCorrectStructure()
        {
            foreach (var a in plant)
            {
                foreach (var b in plant)
                {
                    if (a.Equals(b))
                    {
                        continue;
                    }
                    var collide = collisionDetection.Colliding(a, b, true);
                    Assert.False(collide);
                }
            }

            var length = plant.Count();

            Assert.AreEqual(247, length);

            IPlantCell xylem = null;

            foreach (var c in plant)
            {
                if (c.CellType == PlantCellType.Xylem)
                {
                    xylem = c;
                    break;
                }
            }

            Assert.NotNull(xylem);
            Assert.AreEqual(PlantCellType.Xylem, xylem.CellType);
        }
        protected virtual Vector3 DetermineGrowthFactor(IPlantCell cell, SimulationStateSnapshot snapshot)
        {
            float y = Options.Plant.GrowthRange.RandomNumberBetween();

            y += snapshot.CurrentTime / 25f * 0.0013f;

            return(new Vector3(y, y, 1));
        }
Esempio n. 7
0
 public FluidCarrier(IPlantCell destination, IPlantCell current, IPlantCell closestTransportCell, PlantCellType transportType, TFluid fluid)
 {
     Destination          = destination;
     Current              = current;
     ClosestTransportCell = closestTransportCell;
     this.transportType   = transportType;
     Fluid = fluid;
 }
        private IPlantCell FindInConnection(bool up, IPlantCell cell, IPlantPart part)
        {
            foreach (var conn in part.Connections)
            {
                FindUpOrDown(up, cell, conn);
            }

            return(null);
        }
        public IFluidCarrier <TFluid> Get(IPlantCell cell)
        {
            if (carriers.TryGetValue(cell, out var fc))
            {
                return(fc);
            }

            return(null);
        }
        protected override Vector3 DetermineGrowthFactor(IPlantCell cell, SimulationStateSnapshot snapshot)
        {
            float range = Options.Plant.GrowthRange.RandomNumberBetween();

            float energy = cell.StarchStorage.Amount;

            // We use all the energy so reduce it to 0 so that it does not accumulate
            cell.StarchStorage.Amount = 0;

            float y = range * energy;

            return(new Vector3(y, y, 1));
        }
        private IEnumerable <IPlantCell> GetNeighboringCells(IPlantCell cell, IEnumerable <IPlantCell> cells)
        {
            var neighbors = new List <IPlantCell>();

            foreach (var c in cells)
            {
                if (CollisionDetection.Neighbors(cell, c, true))
                {
                    neighbors.Add(c);
                }
            }

            return(neighbors);
        }
Esempio n. 12
0
        public IPlantCell[] Divide(IPlantCell cell, IPlantPart plantPart)
        {
            ICellGeometry geo = cell.Geometry;

            Vector3 halfPoint = GetCellHalfWay(geo);

            ICellGeometry topCellGeometry    = new CellGeometry(geo.TopCenter, halfPoint, geo.Face);
            ICellGeometry bottomCellGeometry = new CellGeometry(halfPoint, geo.BottomCenter, geo.Face);

            IPlantCell[] cells = new IPlantCell[2];

            cells[0] = CreatePlantCell(cell.CellType, topCellGeometry, cell.Vacuole, cell.CellWall);
            cells[1] = CreatePlantCell(cell.CellType, bottomCellGeometry, cell.Vacuole, cell.CellWall);

            return(cells);
        }
        public bool Neighbors(IPlantCell a, IPlantCell b, bool allowInside)
        {
            var aGeo = a.Geometry;
            var bGeo = b.Geometry;

            if (!IsWithinHeight(aGeo, bGeo))
            {
                return(false);
            }

            var aFace = aGeo.Face.Points;
            var bFace = bGeo.Face.Points;

            if (allowInside)
            {
                return(IsInsidePolygon(aFace, bFace));
            }

            return(IsOnPolygonLine(aFace, helper.CreateFacePairs(bFace)));
        }
        protected IPlantCell FindUpOrDown(bool up, IPlantCell cell, IPlantPart part)
        {
            foreach (var c in part.Cells)
            {
                if (c.CellType == cell.CellType && CollisionDetection.Neighbors(cell, c, true))
                {
                    if (up && cell.Geometry.TopCenter.Y <= c.Geometry.BottomCenter.Y)
                    {
                        return(c);
                    }
                    if (!up && cell.Geometry.BottomCenter.Y >= c.Geometry.TopCenter.Y)
                    {
                        return(c);
                    }
                }
            }

            // If we end up here, that means that there are no cells above or below the current cell
            // which could mean that it must go to next plant part connection
            return(FindInConnection(up, cell, part));
        }
        public bool Colliding(IPlantCell a, IPlantCell b, bool allowOnLine)
        {
            if (!IsWithinHeight(a.Geometry, b.Geometry))
            {
                return(false);
            }

            var aFace = a.Geometry.Face.Points;
            var bFace = b.Geometry.Face.Points;

            var inside = IsInsidePolygon(aFace, bFace);

            if (inside && allowOnLine)
            {
                var isOnLine = IsOnPolygonLine(aFace, helper.CreateFacePairs(bFace));

                return(!isOnLine);
            }

            return(inside);
        }
        protected virtual Vector3 DetermineGrowthDirection(IPlantCell cell, IPlantPart part)
        {
            var geo = cell.Geometry;

            var direction = new Vector3(0, 1, 0);

            var outwards = Vector3.Zero;

            if (part.BranchCount > 0)
            {
                if (geo.BottomCenter.X > 0)
                {
                    outwards += new Vector3(2, 0, 0);
                }
                else if (geo.BottomCenter.X < 0)
                {
                    outwards += new Vector3(-2, 0, 0);
                }
            }

            return(direction + outwards);
        }
        protected IPlantCell MoveTowardsDestination(IFluidCarrier <TFluid> carrier, IEnumerable <IPlantCell> cells)
        {
            IPlantCell next = null;

            float lowestDistance = float.MaxValue;

            foreach (var c in cells)
            {
                if (c.Equals(carrier.Destination))
                {
                    return(c);
                }

                float dist = Vector3.Distance(carrier.Current.Geometry.TopCenter, c.Geometry.TopCenter);

                if (dist < lowestDistance)
                {
                    next = c;
                }
            }

            return(next);
        }
 public void GrowRootCell(IPlantCell cell, IPlantPart part, SimulationStateSnapshot state)
 {
     MoveBottomPointDownwards(cell, part, state);
 }
 protected abstract IFluidCarrier <TFluid> CreateCarrier(IPlantCell from, IPlantCell to,
                                                         IEnumerable <IPlantCell> cells, float amount);
 public void ResizeHeight(IPlantCell a, IPlantCell b)
 {
     ResizeHeight(a.Geometry, b.Geometry);
 }
 public void ResizeWidth(IPlantCell a, IPlantCell b)
 {
     ResizeFace(a, b);
 }
Esempio n. 22
0
        private void SolveCell(IPlantCell a, IPlantCell b)
        {
            cellSizer.ResizeHeight(a, b);

            cellSizer.ResizeWidth(a, b);
        }
Esempio n. 23
0
        protected override IFluidCarrier <Sucrose> CreateCarrier(IPlantCell from, IPlantCell to, IEnumerable <IPlantCell> cells, float amount)
        {
            var closest = ClosestTransporterCell(PlantCellType.Phloem, from, cells);

            return(new FluidCarrier <Sucrose>(from, to, closest, PlantCellType.Phloem, new Sucrose(amount)));
        }
 public void GrowShootCell(IPlantCell cell, IPlantPart part, SimulationStateSnapshot state)
 {
     MoveTopPointUpwards(cell, part, state);
 }
        protected virtual Vector3 DetermineGrowth(IPlantCell cell, IPlantPart part, SimulationStateSnapshot state)
        {
            var growth = DetermineGrowthDirection(cell, part) * DetermineGrowthFactor(cell, state);

            return(growth);
        }
 public bool Has(IPlantCell cell)
 {
     return(carriers.ContainsKey(cell));
 }
Esempio n. 27
0
 public bool ShouldDivide(IPlantCell cell, IPlantPart plantPart, SimulationStateSnapshot state)
 {
     return(false);
 }
        private void MoveTopPointUpwards(IPlantCell cell, IPlantPart part, SimulationStateSnapshot state)
        {
            var geo = cell.Geometry;

            geo.TopCenter += DetermineGrowth(cell, part, state);
        }
        private void MoveBottomPointDownwards(IPlantCell cell, IPlantPart part, SimulationStateSnapshot state)
        {
            var geo = cell.Geometry;

            geo.BottomCenter -= DetermineGrowth(cell, part, state);
        }
 public bool TryGet(IPlantCell cell, out IFluidCarrier <TFluid> carrier)
 {
     return(carriers.TryGetValue(cell, out carrier));
 }