public SpringGrid( Rectangle gridSize, Vector2 spacing )
{
_gridSize = gridSize;
var springList = new List<Spring>();
// we offset the gridSize location by half-spacing so the padding is applied evenly all around
gridSize.Location -= spacing.ToPoint();
gridSize.Width += (int)spacing.X;
gridSize.Height += (int)spacing.Y;
var numColumns = (int)( gridSize.Width / spacing.X ) + 1;
var numRows = (int)( gridSize.Height / spacing.Y ) + 1;
_points = new PointMass[numColumns, numRows];
// these fixed points will be used to anchor the grid to fixed positions on the screen
var fixedPoints = new PointMass[numColumns, numRows];
// create the point masses
int column = 0, row = 0;
for( float y = gridSize.Top; y <= gridSize.Bottom; y += spacing.Y )
{
for( float x = gridSize.Left; x <= gridSize.Right; x += spacing.X )
{
_points[column, row] = new PointMass( new Vector3( x, y, 0 ), 1 );
fixedPoints[column, row] = new PointMass( new Vector3( x, y, 0 ), 0 );
column++;
}
row++;
column = 0;
}
// link the point masses with springs
for( var y = 0; y < numRows; y++ )
{
for( var x = 0; x < numColumns; x++ )
{
if( x == 0 || y == 0 || x == numColumns - 1 || y == numRows - 1 ) // anchor the border of the grid
springList.Add( new Spring( fixedPoints[x, y], _points[x, y], 0.1f, 0.1f ) );
else if( x % 3 == 0 && y % 3 == 0 ) // loosely anchor 1/9th of the point masses
springList.Add( new Spring( fixedPoints[x, y], _points[x, y], 0.002f, 0.02f ) );
const float stiffness = 0.28f;
const float damping = 0.06f;
if( x > 0 )
springList.Add( new Spring( _points[x - 1, y], _points[x, y], stiffness, damping ) );
if( y > 0 )
springList.Add( new Spring( _points[x, y - 1], _points[x, y], stiffness, damping ) );
}
}
_springs = springList.ToArray();
}