class GridCell { int [] m_ColorSquares; int m_NumSquares; void Initialize() { m_NumSquares = 0; m_ColorSquares = new int[SQUARES_PER_GRID_CELL]; int i; for( i = 0; i < SQUARES_PER_GRID_CELL; ++i ) { m_ColorSquares[i] = -1; } } void Clear() { m_NumSquares = 0; int i; for( i = 0; i < SQUARES_PER_GRID_CELL; ++i ) { m_ColorSquares[i] = -1; } } boolean AddShadowBitToCell( int Index ) { int i; for( i = 0; i < SQUARES_PER_GRID_CELL; ++i ) { if( m_ColorSquares[i] == -1 || m_ColorSquares[i] == Index ) { if( m_ColorSquares[i] == -1 ) { ++m_NumSquares; } m_ColorSquares[i] = Index; return true; } } return false; } void CalculateForcesOnEachBit() { int i, j; for( i = 0; i < SQUARES_PER_GRID_CELL; ++i ) { if( m_ColorSquares[i] == -1 ) { continue; } for( j = i + 1; j < SQUARES_PER_GRID_CELL; ++j ) { if( m_ColorSquares[j] == -1 ) { continue; } //compute distance squared Vector2D i_to_j = new Vector2D(); i_to_j.x = COLORS[ m_ColorSquares[j] ].m_Position.x - COLORS[ m_ColorSquares[i] ].m_Position.x; i_to_j.y = COLORS[ m_ColorSquares[j] ].m_Position.y - COLORS[ m_ColorSquares[i] ].m_Position.y; float distance = i_to_j.MagnitudeSquared(); float maxAffectDist = COLORS[ m_ColorSquares[j] ].m_Width + COLORS[ m_ColorSquares[i] ].m_Width + AFFECT_BUFFER; maxAffectDist *= maxAffectDist; if( distance < maxAffectDist ) { if( distance == 0.f ) { i_to_j.x = 1.f; } else { i_to_j.Normalize(); } float distRatio = (maxAffectDist - distance) / maxAffectDist; distRatio *= distRatio; float baseForce = 0.5f + (distRatio * 1.f); i_to_j.Multiply( baseForce ); COLORS[ m_ColorSquares[i] ].AddToForces( -i_to_j.x, -i_to_j.y ); COLORS[ m_ColorSquares[j] ].AddToForces( i_to_j.x, i_to_j.y ); } } } } }; class Grid { int m_ExtentX; int m_ExtentY; int m_NumCellsX; int m_NumCellsY; int m_NumCellsTotal; int m_CellWidth; int m_CellHeight; GridCell [] m_Cells; void Initialize() { m_ExtentX = SCREEN_WIDTH; m_ExtentY = SCREEN_HEIGHT; m_NumCellsX = 5; m_NumCellsY = 5; m_NumCellsTotal = m_NumCellsX * m_NumCellsY; m_CellWidth = m_ExtentX / m_NumCellsX; m_CellHeight = m_ExtentY / m_NumCellsY; m_Cells = new GridCell[m_NumCellsTotal]; int i; for( i = 0; i < m_NumCellsTotal; ++i ) { m_Cells[i] = new GridCell(); m_Cells[i].Initialize(); } } void Draw() { int i, j; for( i = 0; i < m_NumCellsX; ++i ) { for( j = 0; j < m_NumCellsY; ++j ) { noFill(); stroke(255); rect( i * m_CellWidth, j * m_CellHeight, m_CellWidth, m_CellHeight ); } } } void AddBitsToGrid() { int i; for( i = 0; i < m_NumCellsTotal; ++i ) { m_Cells[i].Clear(); } for( i = 0; i < NUM_COLORS; ++i ) { if( COLORS[i].m_Used == true ) { int TLCellIndexX = (int)((COLORS[i].m_Position.x - COLORS[i].m_HalfWidth) / m_CellWidth); int TLCellIndexY = (int)((COLORS[i].m_Position.y - COLORS[i].m_HalfHeight) / m_CellWidth); TLCellIndexX = CapInt( TLCellIndexX, 0, m_NumCellsX - 1 ); TLCellIndexY = CapInt( TLCellIndexY, 0, m_NumCellsY - 1 ); int TLCellIndex = TLCellIndexY * m_NumCellsX + TLCellIndexX; int TRCellIndexX = (int)((COLORS[i].m_Position.x + COLORS[i].m_HalfWidth) / m_CellWidth); int TRCellIndexY = (int)((COLORS[i].m_Position.y - COLORS[i].m_HalfHeight) / m_CellWidth); TRCellIndexX = CapInt( TRCellIndexX, 0, m_NumCellsX - 1 ); TRCellIndexY = CapInt( TRCellIndexY, 0, m_NumCellsY - 1 ); int TRCellIndex = TRCellIndexY * m_NumCellsX + TRCellIndexX; int BLCellIndexX = (int)((COLORS[i].m_Position.x - COLORS[i].m_HalfWidth) / m_CellWidth); int BLCellIndexY = (int)((COLORS[i].m_Position.y + COLORS[i].m_HalfHeight) / m_CellWidth); BLCellIndexX = CapInt( BLCellIndexX, 0, m_NumCellsX - 1 ); BLCellIndexY = CapInt( BLCellIndexY, 0, m_NumCellsY - 1 ); int BLCellIndex = BLCellIndexY * m_NumCellsX + BLCellIndexX; int BRCellIndexX = (int)((COLORS[i].m_Position.x + COLORS[i].m_HalfWidth) / m_CellWidth); int BRCellIndexY = (int)((COLORS[i].m_Position.y + COLORS[i].m_HalfHeight) / m_CellWidth); BRCellIndexX = CapInt( BRCellIndexX, 0, m_NumCellsX - 1 ); BRCellIndexY = CapInt( BRCellIndexY, 0, m_NumCellsY - 1 ); int BRCellIndex = BRCellIndexY * m_NumCellsX + BRCellIndexX; m_Cells[TLCellIndex].AddShadowBitToCell( COLORS[i].m_UniqueID ); m_Cells[TRCellIndex].AddShadowBitToCell( COLORS[i].m_UniqueID ); m_Cells[BLCellIndex].AddShadowBitToCell( COLORS[i].m_UniqueID ); m_Cells[BRCellIndex].AddShadowBitToCell( COLORS[i].m_UniqueID ); } } } void ComputeForcesOnBits() { int i, j; for( i = 0; i < m_NumCellsX; ++i ) { for( j = 0; j < m_NumCellsY; ++j ) { m_Cells[j * m_NumCellsX + i].CalculateForcesOnEachBit(); } } } };