예제 #1
0
        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);
        }
예제 #2
0
 public static MSPoint max(MSPoint p1, MSPoint p2)
 {
     return(new MSPoint(Math.Max(p1.X, p2.X), Math.Max(p1.Y, p2.Y)));
 }
예제 #3
0
 public MSPoint(MSPoint point)
 {
     X = point.X;
     Y = point.Y;
 }
예제 #4
0
 public MSLine(MSPoint start, MSPoint end)
 {
     Start = start;
     End   = end;
 }
예제 #5
0
 public MSLine()
 {
     Start = new MSPoint(0.0f);
     End   = new MSPoint(0.0f);
 }
예제 #6
0
        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]));
                        }
                    }
                }
            }
        }