/// <summary> /// Calculates charges of all tiles in a cTAM and re-colors tiles accordingly /// TODO generalize for 2D when formulas are available /// </summary> /// <param name="mSystem">M system which simulates a cTAM</param> public static void CalculateCharges(MSystem mSystem) { foreach (var tile in mSystem.SeedTiles) { CalculateLadder(tile, mSystem); } }
/// <summary> /// Simulation constructor. /// </summary> /// <param name="mSystemObjects">Deserialized M System objects.</param> /// <exception cref="ArgumentException"> /// If M System objects objecst list is null. /// </exception> protected SimulationWorld(DeserializedObjects mSystemObjects) { if (mSystemObjects == null) { throw new ArgumentException("M System objects can't be null"); } SimulationMSystem = new MSystem(mSystemObjects); TilesWorld = new TilesWorld(SimulationMSystem); FltObjectsWorld = new FloatingObjectsWorld(SimulationMSystem, TilesWorld); // The TilesWorld and FltObjectsWorld need to crossref. TilesWorld.FltObjectsWorld = FltObjectsWorld; }
/// <summary> /// Constructor initializing the world with a collection of seed tiles. /// DO NOT USE outside the class SimulationWorld. /// </summary> public TilesWorld(MSystem mSystem) { if (mSystem == null) { throw new ArgumentNullException($"Parameter \'mSystem\' cannot be null."); } v_MSystem = mSystem; foreach (var seedTile in mSystem.SeedTiles) { _Add(seedTile); } }
/// <summary> /// For a cTAM 1D electric ladder, calculates charges of all tiles and re-colors tiles accordingly /// </summary> /// <param name="tile">Starting tile of the ladder</param> /// <param name="mSystem">M system which simulates a cTAM</param> private static void CalculateLadder(TileInSpace tile, MSystem mSystem) { var ladder = new List <TileInSpace>() { null }; // Element ladder[0] is unused, to agree with paper formulas // The cycle must terminate as the tiles are passed in increasing X-coordinate order while (tile != null) { ladder.Add(tile); // Next tile to the east from the current one tile = tile.EastConnector?.ConnectedTo?.OnTile; } var t = ladder.Count - 1; if (t <= 0) { return; } var coefR = new double[t + 1]; coefR[t] = 1; var coefV = new double[t + 1]; coefV[0] = 1; for (int k = t - 1; k >= 1; k--) { coefR[k] = 1 - 1 / (coefR[k + 1] + ladder[k + 1].AlphaRatio + 1); } for (int k = 1; k <= t; k++) { tile = ladder[k]; coefV[k] = coefV[k - 1] * coefR[k] / (coefR[k] + tile.AlphaRatio); tile.EastConnector.Voltage = mSystem.Nu0 * coefV[k]; // Color change: lower voltage -> darker, but no less than 1/3 of the original light var coef = 0.75 / Math.Max(1 - mSystem.Tau / mSystem.Nu0, 0.01); var darkRatio = Math.Max((coefV[k] - 1) * coef + 1, 0); var origColor = ((Tile)tile).Color; tile.SetNewColor(origColor.A, (int)(origColor.R * darkRatio), (int)(origColor.G * darkRatio), (int)(origColor.B * darkRatio)); } }
/// <summary> /// Constructor of the floating objects world. /// DO NOT USE outside the class SimulationWorld. /// </summary> /// <param name="mSystem">Simulated M system.</param> /// <param name="tilesWorld">World of tiles present initially in the P system</param>ra public FloatingObjectsWorld(MSystem mSystem, TilesWorld tilesWorld) { v_MSystem = mSystem; v_tilesWorld = tilesWorld; // Degree of granularity of the simulation space - objects are collected in these cubes // The constant 2.02 guarantees that each "floating object mobility" ball in space fits in // at most 2x2x2 grid cubes, plus 1% reserve. var cubeSize = mSystem.Mobility * 2.02; v_BoundaryVector = new Vector3D(cubeSize, cubeSize, cubeSize); v_Grid = new Dictionary <ulong, FloatingObjectsBar>(); // Calculate a bounding box around the seed tiles // THESE THREE COMMANDS MUST BE IN THIS ORDER!!! v_WorldBox = new Box3D(v_tilesWorld.SelectMany(tile => tile.Vertices)); v_GridKeys = new FloatingObjectsWorldKeys(cubeSize); ExpandWith(v_WorldBox); }