Join 136,542 C# Programmers for FREE! Get instant access to thousands of C# experts, tutorials, code snippets, and more! There are 1,849 people online right now. Registration is fast and FREE... Join Now!
OK, I'm ready to kill myself (well not quite!) but I have an issue where I'm trying to place a certain number of stars in random X,Y locations where each one will be no more than 'minimumDistance' away from eachother. That way you don't get dumb placement of stars on top of eachother, etc. Man, I've just been hacking away at it for like a week or so not making much progress. I'm DYIN' ovah heah. Can anyone give me a hand? The whole 'iteration' thing is tying my brain in knots. I'd appreciate any help.
Here's what I have so far:
CODE
using System; using System.Collections.Generic;
namespace StarmapDistanceCheck { class Program { // I'm after creating a star object and adding it to an array only after // we've checked that it is no closer than 'minimumDistance' to any other star.
public static List<Star> starList;
static void Main() { int numberOfStars = 40; starList = new List<Star>(numberOfStars); float minimumDistance = 7.0f; for (int i = 0; i < numberOfStars; i++) { Console.Out.WriteLine("i = " + i); int success = 0; Star tempStar = new Star(); tempStar.starID = i; Console.Out.WriteLine("Created new star"); if (i > 1) { foreach (Star tempStar2 in starList) { double tempDistance = Distance2D(tempStar.x, tempStar.y, tempStar2.x, tempStar2.y); if (tempDistance >= minimumDistance) { Console.Out.WriteLine("Success. Distance from tempStar to star tempStar2 = " + tempDistance + "starList count is:" + starList.Count); success = 1; } else { Console.Out.WriteLine("Failed! Distance: " + tempDistance); while ((tempDistance <= minimumDistance)) { tempStar = new Star(); tempStar.starID = i; tempDistance = Distance2D(tempStar.x, tempStar.y, tempStar2.x, tempStar2.y); } } } }
if (i == 0) { success = 1; Console.Out.WriteLine("Star 0="); }
if (i == 1) { Star tempStar2 = starList[0]; double testDistance = Distance2D(tempStar.x, tempStar.y, tempStar2.x, tempStar2.y); while (testDistance <= minimumDistance) { testDistance = Distance2D(tempStar.x, tempStar.y, tempStar2.x, tempStar2.y); tempStar.x = RandomHelper.GetRandomFloat(-80.0f, 80.0f); tempStar.y = RandomHelper.GetRandomFloat(-80.0f, 80.0f); //Console.Out.WriteLine("I'm in me loop!"); //Console.Out.WriteLine("Distance = " + testDistance); } success = 1; //Console.Out.WriteLine("Star 1="); }
if (success == 1) { starList.Add(tempStar); //Console.Out.WriteLine("Success!"); } else { starList.RemoveAt(i - 1); i = -1; if (i < 0) { i = 0; starList.RemoveAt(0); } } Console.Out.WriteLine("Finished iteration of star:" + tempStar.starID); //Console.ReadLine(); } }
public class Star { public float x = RandomHelper.GetRandomFloat(-80.0f, 80.0f); public float y = RandomHelper.GetRandomFloat(-80.0f, 80.0f); public int starID; }
// Helper stuff public static class RandomHelper { #region Variables /// <summary> /// Global random generator /// </summary> public static Random globalRandomGenerator = GenerateNewRandomGenerator(); #endregion
#region Generate a new random generator /// <summary> /// Generate a new random generator with help of /// WindowsHelper.GetPerformanceCounter. /// Also used for all GetRandom methods here. /// </summary> /// <returns>Random</returns> public static Random GenerateNewRandomGenerator() { globalRandomGenerator = new Random((int)DateTime.Now.Ticks); //needs Interop: (int)WindowsHelper.GetPerformanceCounter()); return globalRandomGenerator; } #endregion
#region Get random float and byte methods /// <summary> /// Get random int /// </summary> /// <param name="max">Maximum</param> /// <returns>Int</returns> public static int GetRandomInt(int max) { return globalRandomGenerator.Next(max); } public static int GetRandomInt(int min, int max) { return globalRandomGenerator.Next(min, max); }
/// <summary> /// Get random float between min and max /// </summary> /// <param name="min">Min</param> /// <param name="max">Max</param> /// <returns>Float</returns> public static float GetRandomFloat(float min, float max) { return (float)globalRandomGenerator.NextDouble() * (max - min) + min; }
First I would separate some of the stuff in main into functions. Instead of doing the distance check iterations in main, maybe make a function that checks the passed star against the starlist. Then in main have a while loop like this.
CODE
bool success = false; while(!success) { Star tempStar = new Star(); success = GoodDistance(tempStar); }
namespace StrarmapDistanceCheck { class Program { // I'm after creating a star object and adding it to an array only after // we've checked that it is no closer than 'minimumDistance' to any other star.
public static List<Star> starList;
static void Main() { int numberOfStars = 40; starList = new List<Star>(numberOfStars); float minimumDistance = 7.0f; Star tempStar = new Star();
for (int i = 0; i < numberOfStars; i++) { Console.Out.WriteLine("i = " + i); bool success = false; while (!success) { tempStar = new Star(); tempStar.starID = i; success = GoodDistance(tempStar, minimumDistance); } starList.Add(tempStar); //Print Star Location for each star added to starList Console.WriteLine("Star Location: " + tempStar.x + ", " + tempStar.y); }
public class Star { public float x = RandomHelper.GetRandomFloat(-80.0f, 80.0f); public float y = RandomHelper.GetRandomFloat(-80.0f, 80.0f); public int starID; }
// Helper stuff public static class RandomHelper { #region Variables /// <summary> /// Global random generator /// </summary> public static Random globalRandomGenerator = GenerateNewRandomGenerator(); #endregion
#region Generate a new random generator /// <summary> /// Generate a new random generator with help of /// WindowsHelper.GetPerformanceCounter. /// Also used for all GetRandom methods here. /// </summary> /// <returns>Random</returns> public static Random GenerateNewRandomGenerator() { globalRandomGenerator = new Random((int)DateTime.Now.Ticks); //needs Interop: (int)WindowsHelper.GetPerformanceCounter()); return globalRandomGenerator; } #endregion
#region Get random float and byte methods /// <summary> /// Get random int /// </summary> /// <param name="max">Maximum</param> /// <returns>Int</returns> public static int GetRandomInt(int max) { return globalRandomGenerator.Next(max); } public static int GetRandomInt(int min, int max) { return globalRandomGenerator.Next(min, max); }
/// <summary> /// Get random float between min and max /// </summary> /// <param name="min">Min</param> /// <param name="max">Max</param> /// <returns>Float</returns> public static float GetRandomFloat(float min, float max) { return (float)globalRandomGenerator.NextDouble() * (max - min) + min; }
This was rather amusing. I thought you should be able to take more advantage of objects with this particular program. Since an answer is already on the table, I'll offer this approach. It was entertaining enough I even added a bonus method, "GetClosestStar." Have fun.
csharp
using System; using System.Collections.Generic;
namespace StarmapDistanceCheck { public class Star { private float x; private float y; private int starID;
private Star GetNewValidStar(int id, Random rnd) { while (true) { Star newStar = new Star(id, GetRandPos(rnd), GetRandPos(rnd)); if (IsValidStar(newStar)) { return newStar; } } }
private void InitStars(int starCount) { Random rnd = new Random(); for (int i = 0; i < starCount; i++) { this.Add(GetNewValidStar(i, rnd)); } }
public bool IsValidStar(Star newStar) { foreach (Star currentStar in this) { if (newStar.GetDistance(currentStar) < minimumDistance) { return false; } } return true; }
public Star GetClosestStar(Star toStar) { Star closest = null; float lastDist = -1; foreach (Star star in this) { if (toStar != star ) { float dist = star.GetDistance(toStar); if (dist < lastDist || lastDist==-1) { closest = star; lastDist = dist; } } } return closest; }
public float MinimumDistance { get { return this.minimumDistance; } }
}
class Program { static void Main() { StarMap starMap = new StarMap(7.0f, 160, 40); foreach (Star star in starMap) { Console.WriteLine(star + " : " + starMap.GetClosestStar(star).GetDistance(star)); } Console.ReadLine(); }