public float DensityAtLocation(MSPoint point) { float density = 0.0f; foreach (MSParticle particle in ParticleList) { float distanceToParticleSqr = (particle.Position - point).LengthSqr(); if (distanceToParticleSqr <= particle.RadiusSqr) { density += 1.0f; } } return(density); }
public static MSPoint max(MSPoint p1, MSPoint p2) { return(new MSPoint(Math.Max(p1.X, p2.X), Math.Max(p1.Y, p2.Y))); }
public MSPoint(MSPoint point) { X = point.X; Y = point.Y; }
public MSLine(MSPoint start, MSPoint end) { Start = start; End = end; }
public MSLine() { Start = new MSPoint(0.0f); End = new MSPoint(0.0f); }
public void GenerateLines(MSParticleField particleField) { ResetData(); if (particleField.ParticleList.Count <= 0) { return; } min = new MSPoint(float.MaxValue); max = new MSPoint(float.MinValue); MSPoint particleRadius = new MSPoint(0.0f); // find the extents of the area we need to surround with lines (include the particle radius) foreach (MSParticle particle in particleField.ParticleList) { particleRadius.X = particle.Radius; particleRadius.Y = particle.Radius; min = MSPoint.min(particle.Position - particleRadius, min); max = MSPoint.max(particle.Position + particleRadius, max); } // round up/down to the nearest cell size, then expand out another cell - incase the min/max is already aligned to the grid min.X = min.X - (min.X % cellSize) - cellSize; min.Y = min.Y - (min.Y % cellSize) - cellSize; max.X = max.X + (cellSize - (max.X % cellSize)) + cellSize; max.Y = max.Y + (cellSize - (max.Y % cellSize)) + cellSize; int xSteps = (int)((max.X - min.X) / cellSize); int ySteps = (int)((max.Y - min.Y) / cellSize); // sample the field density at each square's corner densityArray = new float[xSteps, ySteps]; MSPoint testPoint = new MSPoint(0.0f); for (int x = 0; x < xSteps; ++x) { for (int y = 0; y < ySteps; ++y) { testPoint.X = min.X + (float)x * cellSize; testPoint.Y = min.Y + (float)y * cellSize; densityArray[x, y] = particleField.DensityAtLocation(testPoint); } } // for each square - look up in the connections table what lines to generate and add them for (int x = 0; x < xSteps - 1; ++x) { for (int y = 0; y < ySteps - 1; ++y) { float upperLeft = densityArray[x, y]; float upperRight = densityArray[x + 1, y]; float lowerLeft = densityArray[x, y + 1]; float lowerRight = densityArray[x + 1, y + 1]; int tableIndex = 0; tableIndex |= upperLeft >= DensityThreshold ? 8 : 0; tableIndex |= upperRight >= DensityThreshold ? 4 : 0; tableIndex |= lowerLeft >= DensityThreshold ? 1 : 0; tableIndex |= lowerRight >= DensityThreshold ? 2 : 0; List <SquareSide> edges = edgeTable[tableIndex]; foreach (SquareSide edge in edges) { int index = 0; MSPoint[] line = new MSPoint[2]; if ((edge & SquareSide.eTop) > 0) { float interpolationFactor = (DensityThreshold - upperLeft) / (upperRight - upperLeft); line[index] = new MSPoint( min.X + (float)x * cellSize + cellSize * interpolationFactor , min.Y + (float)y * cellSize); ++index; } if ((edge & SquareSide.eBottom) > 0) { float interpolationFactor = (DensityThreshold - lowerLeft) / (lowerRight - lowerLeft); line[index] = new MSPoint( min.X + (float)x * cellSize + cellSize * interpolationFactor , min.Y + (float)(y + 1) * cellSize); ++index; } if ((edge & SquareSide.eLeft) > 0) { float interpolationFactor = (DensityThreshold - upperLeft) / (lowerLeft - upperLeft); line[index] = new MSPoint( min.X + (float)x * cellSize , min.Y + (float)y * cellSize + cellSize * interpolationFactor); ++index; } if ((edge & SquareSide.eRight) > 0) { float interpolationFactor = (DensityThreshold - upperRight) / (lowerRight - upperRight); line[index] = new MSPoint( min.X + (float)(x + 1) * cellSize , min.Y + (float)y * cellSize + cellSize * interpolationFactor); ++index; } if (index == 2) { generatedLines.Add(new MSLine(line[0], line[1])); } } } } }