// Uses a circle based on the closest blob to the cell center as an approximation // for cell area. public void UpdateAreaSprings(BlobArrays blobs) { foreach (int startIndex in BlobIndices) { Vector2d averagePos = new Vector2d(); for (int i = 0; i < BoundaryElementsInCell; i++) { averagePos += blobs.Positions[startIndex + i]; } averagePos /= CellDataArrays.BoundaryElementsInCell; float area = 0.0f; for (int i = 1; i < BoundaryElementsInCell; i++) { Vector2d A = blobs.Positions[startIndex + i] - blobs.Positions[startIndex + i - 1]; Vector2d B = blobs.Positions[startIndex + i] - averagePos; Vector2d C = blobs.Positions[startIndex + i - 1] - averagePos; float a = A.Length(); float b = B.Length(); float c = C.Length(); float s = (a + b + c) / 2.0f; float traingleAreaSquared = (s - a) * (s - b) * (s - c) * s; area += (float)Math.Sqrt(traingleAreaSquared); } { // Account for the triangle formed by the first and last blobs; Vector2d A = blobs.Positions[startIndex] - blobs.Positions[startIndex + BoundaryElementsInCell - 1]; Vector2d B = blobs.Positions[startIndex] - averagePos; Vector2d C = blobs.Positions[startIndex + BoundaryElementsInCell - 1] - averagePos; float a = A.Length(); float b = B.Length(); float c = C.Length(); float s = (a + b + c) / 2.0f; float traingleAreaSquared = (s - a) * (s - b) * (s - c) * s; area += (float)Math.Sqrt(traingleAreaSquared); } float compression = CellTargetArea - area; compression = Math.Max(compression, 0.0f); for (int i = 0; i < BoundaryElementsInCell; i++) { Vector2d localPos = averagePos - blobs.Positions[startIndex + i]; Vector2d force = localPos / localPos.Length(); force *= AreaSpringStrength * compression; blobs.Velocities[startIndex + i] -= force; } } }
public World(IRenderer renderer) { m_baseColours = new Colour[12]; m_baseColours[00] = new Colour() { R = 1.0f, G = 0.0f, B = 0.0f, A = 0.0f }; m_baseColours[01] = new Colour() { R = 0.0f, G = 1.0f, B = 0.0f, A = 0.0f }; m_baseColours[02] = new Colour() { R = 0.0f, G = 0.0f, B = 1.0f, A = 0.0f }; m_baseColours[03] = new Colour() { R = 1.0f, G = 1.0f, B = 0.0f, A = 0.0f }; m_baseColours[04] = new Colour() { R = 0.0f, G = 1.0f, B = 1.0f, A = 0.0f }; m_baseColours[05] = new Colour() { R = 1.0f, G = 0.0f, B = 1.0f, A = 0.0f }; m_baseColours[06] = new Colour() { R = 1.0f, G = 0.5f, B = 0.5f, A = 0.0f }; m_baseColours[07] = new Colour() { R = 0.5f, G = 1.0f, B = 0.5f, A = 0.0f }; m_baseColours[08] = new Colour() { R = 0.5f, G = 0.5f, B = 1.0f, A = 0.0f }; m_baseColours[09] = new Colour() { R = 1.0f, G = 1.0f, B = 0.5f, A = 0.0f }; m_baseColours[10] = new Colour() { R = 0.5f, G = 1.0f, B = 1.0f, A = 0.0f }; m_baseColours[11] = new Colour() { R = 1.0f, G = 0.5f, B = 1.0f, A = 0.0f }; m_random = new Random(); m_renderer = renderer; m_scene = m_renderer.GetNewScene(); m_scene.CreateCamera(); m_scene.SetCurrentCamera(0); m_basisRenderArrays = new RenderArrays(); m_springRenderArrays = new RenderArrays(); m_bBoxRenderArrays = new RenderArrays(); m_renderArrays = new RenderArrays(); m_blobs = new BlobArrays(); m_directionalSprings = new DirectionalSpringArray(); m_collisions = new List <Tuple <int, int> >(); m_cellData = new CellDataArrays(); m_BBoxTree = new BBoxTree(); m_springs = new SpringArray(); m_renderArrays.Positions = m_blobs.Positions; m_renderArrays.Colours = m_blobs.Colours; m_bBoxRenderArrays.Colours.Add(m_baseColours[0]); m_bBoxRenderArrays.Positions.Add(new Vector2d()); //InitVisualisationTest(); for (int i = -0; i < 1; i++) { bool grow = i == 0 ? true : false; InitCell(new Vector2d() { X = (float)(250.0f * i + 150.0f), Y = 0 }, i + 4, grow); } //InitCell(new Vector2d() { X = -100.0f, Y = 0.0f }, 0, true); m_scene.RenderArrays.Add(m_renderArrays); //m_scene.RenderArrays.Add(m_bBoxRenderArrays); m_scene.RenderArrays.Add(m_springRenderArrays); m_scene.RenderArrays.Add(m_basisRenderArrays); m_basisRenderArrays.Positions.Add(new Vector2d()); m_basisRenderArrays.Colours.Add(m_baseColours[5]); m_basisRenderArrays.Positions.Add(new Vector2d()); m_basisRenderArrays.Colours.Add(m_baseColours[5]); }