// Returns starting position for a body in simulation space coordinates public SimPoint GetStartingPosition(GravitySim.BodyStartPosition startPos) { const double stagePosition = 0.5; // For the "stage" positions - proportion of the way from the center of the stage to the edge // in all directions double simBoxMaxXY = simSpace.SimBoxHeightAndWidth / 2.0; double stageXY = simBoxMaxXY * stagePosition; double screenMaxX = screenSimulationDimensions.X / 2.0; double screenMaxY = screenSimulationDimensions.Y / 2.0; switch (startPos) { case GravitySim.BodyStartPosition.StageLeft: return(new SimPoint(-stageXY, 0.0)); case GravitySim.BodyStartPosition.StageRight: return(new SimPoint(stageXY, 0.0)); case GravitySim.BodyStartPosition.StageTop: return(new SimPoint(0.0, stageXY)); case GravitySim.BodyStartPosition.StageBottom: return(new SimPoint(0.0, -stageXY)); case GravitySim.BodyStartPosition.StageTopLeft: return(new SimPoint(-stageXY, stageXY)); case GravitySim.BodyStartPosition.StageTopRight: return(new SimPoint(stageXY, stageXY)); case GravitySim.BodyStartPosition.StageBottomLeft: return(new SimPoint(-stageXY, -stageXY)); case GravitySim.BodyStartPosition.StageBottomRight: return(new SimPoint(stageXY, -stageXY)); case GravitySim.BodyStartPosition.ScreenLeft: return(new SimPoint(-screenMaxX, 0.0)); case GravitySim.BodyStartPosition.ScreenRight: return(new SimPoint(screenMaxX, 0.0)); case GravitySim.BodyStartPosition.ScreenTop: return(new SimPoint(0.0, screenMaxY)); case GravitySim.BodyStartPosition.ScreenBottom: return(new SimPoint(0.0, -screenMaxY)); case GravitySim.BodyStartPosition.CenterOfTheUniverse: return(new SimPoint(0.0, 0.0)); case GravitySim.BodyStartPosition.RandomStagePosition: return(new SimPoint(rand.Next((int)-simBoxMaxXY, (int)simBoxMaxXY), rand.Next((int)-simBoxMaxXY, (int)simBoxMaxXY))); case GravitySim.BodyStartPosition.RandomScreenPosition: return(new SimPoint(rand.Next((int)-screenMaxX, (int)screenMaxX), rand.Next((int)-screenMaxY, (int)screenMaxY))); // This approach gives us higher density toward the center of the circle case GravitySim.BodyStartPosition.RandomDenseCenterCircularCluster: double length = rand.NextDouble() * simBoxMaxXY * 0.9; double angle = rand.NextDouble() * Math.PI * 2.0; // radians return(new SimPoint(length * Math.Cos(angle), length * Math.Sin(angle))); // This approach gives us uniform density throughout the circle case GravitySim.BodyStartPosition.RandomUniformDensityCircularCluster: SimPoint newBodyPosition; double limitXY = 0.9 * simBoxMaxXY; do { newBodyPosition = new SimPoint(rand.Next((int)-limitXY, (int)limitXY), rand.Next((int)-limitXY, (int)limitXY)); }while (newBodyPosition.Magnitude() > limitXY); return(newBodyPosition); default: return(new SimPoint(0.0, 0.0)); } }
// Use GravitySim.BodyStartPosition.RandomDenseCenterCircularCluster OR GravitySim.BodyStartPosition.RandomUniformDensityCircularCluster // sizeFactor 1.0 = tiny, sizeFactor 5.0 = "normal" public static void LoadXBodiesCircularCluster(GravitySim sim, int numBodies, double sizeFactor, Renderer.ColorScheme colorScheme, GravitySim.BodyStartPosition bodyStartPosition) { const double baseMass = 100000.0; SetScenarioName(sim, String.Format("{0} Bodies Circular Cluster Scenario ({1})", numBodies, colorScheme)); Random rand = new Random(); sim.ClearSim(); sim.SetSimSpace(new SimulationSpace(SimulationSpace.Space.Toy)); for (int i = 0; i < numBodies; i++) { double size = rand.NextDouble() * 3.0 + 1.0; // Mass as square of size sim.AddBody(size * size * baseMass, size * sizeFactor, RandomColor(colorScheme, rand), bodyStartPosition); } sim.SetMonitoredBody(numBodies - 1); sim.SetMonitoredValues(); sim.SetAccelerationLimits(true, toySpaceScenariosDefaultAccelerationLimit, toySpaceScenariosDeaultMinimumSeparation); }