using System; using System.Collections.Generic; using System.Text; namespace PointCloudGalaxy { // based on: https://itinerantgames.tumblr.com/post/78592276402/a-2d-procedural-galaxy-with-c class Galaxy { public int numArms = 5; public float armSeparationDistance => 2 * (float)Math.PI / numArms; public float armOffsetMax = 0.5f; public float rotationFactor = 5; public float randomJitter = 0.02f; public float scaleOverPlane = 0.15f; public IEnumerable CreateStarts(int count) { var randomizer = new Random(); float RndFloat(double min, double max) { return (float)(randomizer.NextDouble() * (max-min) + min); } for (int i = 0; i < count; i++) { var p = CreateRandomStar(RndFloat); yield return p; } } private System.Numerics.Vector3 CreateRandomStar(Func rndFloat) { // Choose a distance from the center of the galaxy. float distance = rndFloat(0,1); distance = (float)Math.Pow(distance, 2); // Choose an angle between 0 and 2 * PI. float angle = rndFloat(0, 2 * Math.PI); float armOffset = rndFloat(0, armOffsetMax); armOffset = armOffset - armOffsetMax / 2; armOffset = armOffset * (1 / distance); float squaredArmOffset = (float)Math.Pow(armOffset, 2); if (armOffset < 0) squaredArmOffset = squaredArmOffset * -1; armOffset = squaredArmOffset; float rotation = distance * rotationFactor; angle = (int)(angle / armSeparationDistance) * armSeparationDistance + armOffset + rotation; // Convert polar coordinates to 2D cartesian coordinates. var starX = (float)Math.Cos(angle) * distance; var starY = (float)Math.Sin(angle) * distance; // calculate height over galaxy plane var starH = rndFloat(-1,1); starH *= 1.0f - distance; starH *= scaleOverPlane; starX += rndFloat(-1, 1) * 0.5f * randomJitter; starY += rndFloat(-1, 1) * 0.5f * randomJitter; starH += rndFloat(-1, 1) * 0.5f * randomJitter; return new System.Numerics.Vector3(starX, starH, starY); } } }