/* * Create a lower-resolution uniform grid based on another * src - Source uniform grid upon which to base dimensions of this one * iDecimation - amount by which to reduce the number of grid cells in each dimension. Typically this would be 2. * * The number of cells is decimated. The number of points is different. */ public virtual void Decimate(UniformGridGeometry src, int iDecimation) { mGridExtent = src.mGridExtent; mMinCorner = src.mMinCorner; mNumPoints[0] = (int)(src.GetNumCells(0) / iDecimation + 1); mNumPoints[1] = (int)(src.GetNumCells(1) / iDecimation + 1); mNumPoints[2] = (int)(src.GetNumCells(2) / iDecimation + 1); if (iDecimation > 1) { // Decimation could reduce dimension and integer arithmetic could make value be 0, which is useless if src contained any data. mNumPoints[0] = Mathf.Max(2, mNumPoints[0]); mNumPoints[1] = Mathf.Max(2, mNumPoints[1]); mNumPoints[2] = Mathf.Max(2, mNumPoints[2]); } PrecomputeSpacing(); }
void CreateTracers() { Vector3 numCells = new Vector3(grid.GetNumCells(0), grid.GetNumCells(1), grid.GetNumCells(2)); Vector3 relativeCenterOfGrid = new Vector3(grid.GetCellExtent().x / 2, grid.GetCellExtent().y / 2, grid.GetCellExtent().z / 2); for (uint i = 0; i < numCells.x; ++i) { for (uint j = 0; j < numCells.y; ++j) { for (uint k = 0; k < numCells.z; ++k) { ParticleSystem.Particle newTracer = new ParticleSystem.Particle(); uint[] indices = { i, j, k }; newTracer.position = (grid.PositionFromIndices(indices) + relativeCenterOfGrid); newTracer.startColor = new Color32(255, 255, 255, 50); newTracer.startSize = 0.2f; newTracer.lifetime = 9999; tracers.Add(newTracer); } } } }
void AssignVorticity(float fMagnitude, uint numVortonsMax, IVorticityDistribution vorticityDistribution) { Vector3 vDimensions = vorticityDistribution.GetDomainSize(); // length of each side of grid box Vector3 vCenter = (vorticityDistribution).GetCenter(); // Center of vorticity distribution Vector3 vMin = (vCenter - 0.5f * vDimensions); // Minimum corner of box containing vortons Vector3 vMax = (vMin + vDimensions); // Maximum corner of box containing vortons UniformGridGeometry skeleton = new UniformGridGeometry(numVortonsMax, vMin, vMax, true); // number of grid cells in each direction of virtual uniform grid int[] numCells = { (int)Mathf.Max(1, skeleton.GetNumCells(0)) , (int)Mathf.Max(1, skeleton.GetNumCells(1)) , (int)Mathf.Max(1, skeleton.GetNumCells(2)) }; // Total number of cells should be as close to numVortonsMax as possible without going over. // Worst case allowable difference would be numVortonsMax=7 and numCells in each direction is 1 which yields a ratio of 1/7. // But in typical situations, the user would like expect total number of virtual cells to be closer to numVortonsMax than that. // E.g. if numVortonsMax=8^3=512 somehow yielded numCells[0]=numCells[1]=numCells[2]=7 then the ratio would be 343/512~=0.67. while (numCells[0] * numCells[1] * numCells[2] > numVortonsMax) { // Number of cells is excessive. // This can happen when the trial number of cells in any direction is less than 1 -- then the other two will likely be too large. numCells[0] = (int)Mathf.Max(1, numCells[0] / 2); numCells[1] = (int)Mathf.Max(1, numCells[1] / 2); numCells[2] = (int)Mathf.Max(1, numCells[2] / 2); } float[] oneOverN = { 1.0f / (float)(numCells[0]), 1.0f / (float)(numCells[1]), 1.0f / (float)(numCells[2]) }; Vector3 gridCellSize = new Vector3(vDimensions.x * oneOverN[0], vDimensions.y * oneOverN[1], vDimensions.z * oneOverN[2]); float vortonRadius = Mathf.Pow(gridCellSize.x * gridCellSize.y * gridCellSize.z, 1.0f / 3.0f) * 0.5f; if (0.0f == vDimensions.z) { // z size is zero, so domain is 2D. vortonRadius = Mathf.Pow(gridCellSize.x * gridCellSize.y, 0.5f) * 0.5f; } Vector3 vNoise = (0.0f * gridCellSize); //----------------------------------------------------------------------- // Iterate through each point in a uniform grid. // If probe position is inside vortex core, add a vorton there. // This loop could be rewritten such that it only visits points inside the core, // but this loop structure can readily be reused for a wide variety of configurations. Vector3 position = new Vector3(0.0f, 0.0f, 0.0f); // vorton position int[] index = new int[3]; // index of each position visited for (index[2] = 0; index[2] < numCells[2]; ++index[2]) { // For each z-coordinate... position.z = ((float)(index[2]) + 0.25f) * gridCellSize.z + vMin.z; for (index[1] = 0; index[1] < numCells[1]; ++index[1]) { // For each y-coordinate... position.y = ((float)(index[1]) + 0.25f) * gridCellSize.y + vMin.y; for (index[0] = 0; index[0] < numCells[0]; ++index[0]) { // For each x-coordinate... position.x = ((float)(index[0]) + 0.25f) * gridCellSize.x + vMin.x; position += Random.Range(-1, 1) * (vNoise); Vector3 vorticity = Vector3.zero; vorticityDistribution.AssignVorticity(ref vorticity, position, vCenter); Vorton vorton = new Vorton(position, vorticity * fMagnitude, vortonRadius); if (vorticity.sqrMagnitude > global.GlobalVar.sTiny) { // Vorticity is significantly non-zero. mVortonSim.AddVorton(vorton); } } } } //----------------------------------------------------------------------- }
/* Create a lower-resolution uniform grid based on another src - Source uniform grid upon which to base dimensions of this one iDecimation - amount by which to reduce the number of grid cells in each dimension. Typically this would be 2. The number of cells is decimated. The number of points is different. */ public virtual void Decimate(UniformGridGeometry src, int iDecimation) { mGridExtent = src.mGridExtent; mMinCorner = src.mMinCorner; mNumPoints[0] = (int)(src.GetNumCells(0) / iDecimation + 1); mNumPoints[1] = (int)(src.GetNumCells(1) / iDecimation + 1); mNumPoints[2] = (int)(src.GetNumCells(2) / iDecimation + 1); if (iDecimation > 1) { // Decimation could reduce dimension and integer arithmetic could make value be 0, which is useless if src contained any data. mNumPoints[0] = Mathf.Max(2, mNumPoints[0]); mNumPoints[1] = Mathf.Max(2, mNumPoints[1]); mNumPoints[2] = Mathf.Max(2, mNumPoints[2]); } PrecomputeSpacing(); }
void AssignVorticity(float fMagnitude, uint numVortonsMax, IVorticityDistribution vorticityDistribution) { Vector3 vDimensions = vorticityDistribution.GetDomainSize(); // length of each side of grid box Vector3 vCenter = (vorticityDistribution).GetCenter(); // Center of vorticity distribution Vector3 vMin = (vCenter - 0.5f * vDimensions) ; // Minimum corner of box containing vortons Vector3 vMax = (vMin + vDimensions) ; // Maximum corner of box containing vortons UniformGridGeometry skeleton = new UniformGridGeometry(numVortonsMax, vMin, vMax, true ) ; // number of grid cells in each direction of virtual uniform grid int[] numCells = { (int)Mathf.Max( 1 , skeleton.GetNumCells(0)) , (int)Mathf.Max( 1 , skeleton.GetNumCells(1)) , (int)Mathf.Max( 1 , skeleton.GetNumCells(2)) }; // Total number of cells should be as close to numVortonsMax as possible without going over. // Worst case allowable difference would be numVortonsMax=7 and numCells in each direction is 1 which yields a ratio of 1/7. // But in typical situations, the user would like expect total number of virtual cells to be closer to numVortonsMax than that. // E.g. if numVortonsMax=8^3=512 somehow yielded numCells[0]=numCells[1]=numCells[2]=7 then the ratio would be 343/512~=0.67. while (numCells[0] * numCells[1] * numCells[2] > numVortonsMax) { // Number of cells is excessive. // This can happen when the trial number of cells in any direction is less than 1 -- then the other two will likely be too large. numCells[0] = (int)Mathf.Max(1, numCells[0] / 2); numCells[1] = (int)Mathf.Max(1, numCells[1] / 2); numCells[2] = (int)Mathf.Max(1, numCells[2] / 2); } float[] oneOverN = { 1.0f / (float)(numCells[0]), 1.0f / (float)(numCells[1]), 1.0f / (float)(numCells[2]) }; Vector3 gridCellSize = new Vector3(vDimensions.x * oneOverN[0] , vDimensions.y * oneOverN[1], vDimensions.z * oneOverN[2] ) ; float vortonRadius = Mathf.Pow(gridCellSize.x * gridCellSize.y * gridCellSize.z, 1.0f / 3.0f) * 0.5f; if (0.0f == vDimensions.z) { // z size is zero, so domain is 2D. vortonRadius = Mathf.Pow(gridCellSize.x * gridCellSize.y, 0.5f) * 0.5f; } Vector3 vNoise = (0.0f * gridCellSize) ; //----------------------------------------------------------------------- // Iterate through each point in a uniform grid. // If probe position is inside vortex core, add a vorton there. // This loop could be rewritten such that it only visits points inside the core, // but this loop structure can readily be reused for a wide variety of configurations. Vector3 position = new Vector3(0.0f, 0.0f, 0.0f); // vorton position int[] index = new int[3]; // index of each position visited for (index[2] = 0; index[2] < numCells[2]; ++index[2]) { // For each z-coordinate... position.z = ((float)(index[2]) + 0.25f) * gridCellSize.z + vMin.z; for (index[1] = 0; index[1] < numCells[1]; ++index[1]) { // For each y-coordinate... position.y = ((float)(index[1]) + 0.25f) * gridCellSize.y + vMin.y; for (index[0] = 0; index[0] < numCells[0]; ++index[0]) { // For each x-coordinate... position.x = ((float)(index[0]) + 0.25f) * gridCellSize.x + vMin.x; position += Random.Range(-1, 1) * (vNoise); Vector3 vorticity = Vector3.zero; vorticityDistribution.AssignVorticity(ref vorticity, position, vCenter); Vorton vorton = new Vorton(position, vorticity * fMagnitude, vortonRadius); if (vorticity.sqrMagnitude > global.GlobalVar.sTiny) { // Vorticity is significantly non-zero. mVortonSim.AddVorton(vorton); } } } } //----------------------------------------------------------------------- }