Welcome to Dream.In.Code
Getting C# Help is Easy!

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!




Random starmap, certain distance minimum between stars

 
Reply to this topicStart new topic

Random starmap, certain distance minimum between stars, Having issues randomly placing stars that will be >= a specified mi

mroberti
21 Aug, 2008 - 05:38 AM
Post #1

New D.I.C Head
*

Joined: 10 Aug, 2008
Posts: 5

OK, I'm ready to kill myself (well not quite!) smile.gif 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 static double Distance2D(float x, float y, float x2, float y2)
        {
            return (Math.Sqrt(Math.Pow(Math.Abs(x - x2), 2.0) +
                              Math.Pow(Math.Abs(y - y2), 2.0)));
        }

    }

    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;
        }

        #endregion
    }

}



User is offlineProfile CardPM
+Quote Post

SpiderSpartan
RE: Random Starmap, Certain Distance Minimum Between Stars
21 Aug, 2008 - 06:50 AM
Post #2

D.I.C Head
Group Icon

Joined: 6 Feb, 2008
Posts: 66



Thanked: 3 times
Dream Kudos: 25
My Contributions
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);
}


GoodDistance would look like this.
CODE

GoodDistance(Star tempStar)
{
     foreach (Star tempStar2 in starList)
     {
          double tempDistance = Distance2D(tempStar.x, tempStar.y, tempStar2.x,    tempStar2.y);
          if (tempDistance >= minimumDistance)
          {
               continue;
          }
          else
          {
                return false;
          }
     }
     return true;
}


then after the while loop, you know you have a good star, so add it to the list and stuff. Good luck.

This post has been edited by SpiderSpartan: 21 Aug, 2008 - 06:52 AM
User is offlineProfile CardPM
+Quote Post

SpiderSpartan
RE: Random Starmap, Certain Distance Minimum Between Stars
21 Aug, 2008 - 07:07 AM
Post #3

D.I.C Head
Group Icon

Joined: 6 Feb, 2008
Posts: 66



Thanked: 3 times
Dream Kudos: 25
My Contributions
This should do it for ya. Enjoy.

CODE

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);
            }

            // Print starList ID: X, Y
            /*foreach (Star temp in starList)
            {
                Console.WriteLine(temp.starID + ": " + temp.x + ", " + temp.y);
            }*/
        }

        public static bool GoodDistance(Star tempStar, float minimumDistance)
        {
            if (starList.Count <= 1)
                return true;
            foreach (Star tempStar2 in starList)
            {
                double tempDistance = Distance2D(tempStar.x, tempStar.y, tempStar2.x, tempStar2.y);
                if (tempDistance >= minimumDistance)
                {
                    continue;
                }
                else
                {
                    return false;
                }
            }
            return true;
        }

        public static double Distance2D(float x, float y, float x2, float y2)
        {
            return (Math.Sqrt(Math.Pow(Math.Abs(x - x2), 2.0) +
                              Math.Pow(Math.Abs(y - y2), 2.0)));
        }

    }

    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;
        }

        #endregion
    }

}

User is offlineProfile CardPM
+Quote Post

mroberti
RE: Random Starmap, Certain Distance Minimum Between Stars
21 Aug, 2008 - 08:51 AM
Post #4

New D.I.C Head
*

Joined: 10 Aug, 2008
Posts: 5

Wow, thanks! I'll give it a shot when I get home! Of course, I COULD try it out while I'm hiding in the datacenter at work.

I really appreciate it! I'll let everyone know how it worked in case someone down the road wants to create a starmap with nicely spaced stars!! smile.gif
User is offlineProfile CardPM
+Quote Post

baavgai
RE: Random Starmap, Certain Distance Minimum Between Stars
21 Aug, 2008 - 11:38 AM
Post #5

Dreaming Coder
Group Icon

Joined: 16 Oct, 2007
Posts: 2,031



Thanked: 105 times
Dream Kudos: 475
Expert In: C, C++, Java, C#, ASP.NET, PHP, Perl, Python, Oracle, SQL Server, MySql, HTML, JavaScript, Lua

My Contributions
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;

public Star(int starID, float x, float y) {
this.starID = starID;
this.x = x;
this.y = y;
}

public int StarId { get { return this.starID; } }
public float X { get { return this.x; } }
public float Y { get { return this.y; } }

public float GetDistance(float x, float y) {
float dx = this.x - x;
float dy = this.y - y;
return (float)Math.Sqrt((dx * dx) + (dy * dy));
}

public float GetDistance(Star other) {
return GetDistance(other.x, other.y);
}

public override string ToString() {
return "Star " + this.starID + " (" + this.x + "," + this.y + ")";
}
}

//private float minimumDistance = 7.0f;
public class StarMap : List<Star> {
private float minimumDistance;
private float fieldSize;
private float hFieldSize;

public StarMap(float minimumDistance, float fieldSize, int starCount) {
this.minimumDistance = minimumDistance;
this.fieldSize = fieldSize;
hFieldSize = fieldSize / 2.0f;
InitStars(starCount);
}

private float GetRandPos(Random rnd) {
return ((float)rnd.NextDouble() * fieldSize) - hFieldSize;
}

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();
}

}

}


User is offlineProfile CardPM
+Quote Post

mroberti
RE: Random Starmap, Certain Distance Minimum Between Stars
21 Aug, 2008 - 03:05 PM
Post #6

New D.I.C Head
*

Joined: 10 Aug, 2008
Posts: 5

Thanks baavgai! Bonus features, always nice!

I'm thinking of linking to this post in the gamedev forum here too. Someone HAS to have run into this before!
User is offlineProfile CardPM
+Quote Post

mroberti
RE: Random Starmap, Certain Distance Minimum Between Stars
24 Aug, 2008 - 04:13 PM
Post #7

New D.I.C Head
*

Joined: 10 Aug, 2008
Posts: 5

Hot damn! I got it implemented. Thanks for the help guys! I'm glad you showed me the method to do it in. Makes perfect sense the way you guys did it!

That's a wrap!
User is offlineProfile CardPM
+Quote Post

Fast ReplyReply to this topicStart new topic
Time is now: 12/2/08 10:42PM

Live C# Help!

C# Tutorials

Reference Sheets

C# Snippets

DIC Chatroom

Bye Bye Ads

Monthly Drawing

Thumb Drive

Top Contributors

Top 10 Kudos This Month