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); }
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); } }
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)); }
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); }
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); }
private void SolveCell(IPlantCell a, IPlantCell b) { cellSizer.ResizeHeight(a, b); cellSizer.ResizeWidth(a, b); }
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)); }
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)); }