Galaxy.cs 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. namespace PointCloudGalaxy
  5. {
  6. // based on: https://itinerantgames.tumblr.com/post/78592276402/a-2d-procedural-galaxy-with-c
  7. class Galaxy
  8. {
  9. public int numArms = 5;
  10. public float armSeparationDistance => 2 * (float)Math.PI / numArms;
  11. public float armOffsetMax = 0.5f;
  12. public float rotationFactor = 5;
  13. public float randomJitter = 0.02f;
  14. public float scaleOverPlane = 0.15f;
  15. public IEnumerable<System.Numerics.Vector3> CreateStarts(int count)
  16. {
  17. var randomizer = new Random();
  18. float RndFloat(double min, double max) { return (float)(randomizer.NextDouble() * (max-min) + min); }
  19. for (int i = 0; i < count; i++)
  20. {
  21. var p = CreateRandomStar(RndFloat);
  22. yield return p;
  23. }
  24. }
  25. private System.Numerics.Vector3 CreateRandomStar(Func<double, double, float> rndFloat)
  26. {
  27. // Choose a distance from the center of the galaxy.
  28. float distance = rndFloat(0,1);
  29. distance = (float)Math.Pow(distance, 2);
  30. // Choose an angle between 0 and 2 * PI.
  31. float angle = rndFloat(0, 2 * Math.PI);
  32. float armOffset = rndFloat(0, armOffsetMax);
  33. armOffset = armOffset - armOffsetMax / 2;
  34. armOffset = armOffset * (1 / distance);
  35. float squaredArmOffset = (float)Math.Pow(armOffset, 2);
  36. if (armOffset < 0) squaredArmOffset = squaredArmOffset * -1;
  37. armOffset = squaredArmOffset;
  38. float rotation = distance * rotationFactor;
  39. angle = (int)(angle / armSeparationDistance) * armSeparationDistance + armOffset + rotation;
  40. // Convert polar coordinates to 2D cartesian coordinates.
  41. var starX = (float)Math.Cos(angle) * distance;
  42. var starY = (float)Math.Sin(angle) * distance;
  43. // calculate height over galaxy plane
  44. var starH = rndFloat(-1,1);
  45. starH *= 1.0f - distance;
  46. starH *= scaleOverPlane;
  47. starX += rndFloat(-1, 1) * 0.5f * randomJitter;
  48. starY += rndFloat(-1, 1) * 0.5f * randomJitter;
  49. starH += rndFloat(-1, 1) * 0.5f * randomJitter;
  50. return new System.Numerics.Vector3(starX, starH, starY);
  51. }
  52. }
  53. }