public class CompositeVolume : Volume
{
private readonly Random Random = new Random();
public override Collection<Volume> Subvolumes // stub
{
get;
set;
}
public override float Capacity // stub
{
get;
}
// this is the interesting part:
public override Vec GetRandomPosition ()
{
if (Subvolumes.Count == 0) {
return null;
}
else {
float sum = 0f;
Dictionary<Volume, float> map = new Dictionary<Volume, float> ();
foreach (Volume v in Subvolumes) {
sum += v.Capacity;
map[v] = sum;
}
float select = (float) Random.NextDouble () * sum;
Volume inner = map.First (pair => pair.Value >= select).Key;
return inner.GetRandomPosition ();
}
}
}
Refactorings
No refactoring yet !
rikkus
May 7, 2009, May 07, 2009 15:38, permalink
The easiest way to choose a random subvolume would probably be as shown. Also note that I don't recognise Random.NextDouble() - In .NET that's not a static method, for good reason: You generally have to initialise a Random object with a seed before using it.
Subvolumes.Skip(random.Next(Subvolumes.Count)).First()
Volume is an abstract geometrical object. It contains a capacity.
CompositeVolume implements Volume. It contains a list of subvolumes.
I want to find a random position inside a CompositeVolume. Depending on the size of each subvolume I select one of them (bigger => higher probability), and let it select a random position in itself.
I'm pretty satisfied with the code as it stands, but since I'm new to C# and especially to .net 3.5, I wondered how it could be improved. I'm open for all suggestions. :)
Edit:
- "Random" is actually a static member of the class. I added it to the code. Sorry about that.
- Simply selecing a random entry in the list is not possible, because I want to take the Capacity property into consideration. Given two Subvolumes with Capacity 1.f and 2.f, the latter should be selected twice as often.