public static int SelectIntValue(this IValueGenerator gen, Func <double> random, INamedDataCollection data) { Contract.Requires(gen != null); Contract.Requires(random != null); Contract.Requires(data != null); checked { //Rearrange the min and max to be integers (in a narrower or equal range) var min = (long)Math.Ceiling(gen.MinValue); var max = (long)Math.Floor(gen.MaxValue); //If they're the same we don't have a whole lot of choice! if (min == max) { return((int)min); } //If they're inverted the range is too narrow (e.g. Min:0.1 Max:0.9 we can't select any integers in that range) if (min > max) { //Swap max and min var tmp = max; max = min; min = tmp; } //Clamp and round the value return((int)Math.Round(MathHelper.Clamp(gen.SelectFloatValue(random, data), min, max), MidpointRounding.AwayFromZero)); } }
public float SelectFloatValue(Func <double> random, INamedDataCollection data) { if (_singleCache.HasValue && !_vary) { return(_singleCache.Value); } _singleCache = _transform(_basis.SelectFloatValue(random, data)); return(_singleCache.Value); }
public static IValueGenerator Average(IValueGenerator a, IValueGenerator b) { Contract.Requires(a != null); Contract.Requires(b != null); Contract.Ensures(Contract.Result <IValueGenerator>() != null); return(new FuncValue( (r, m) => a.SelectFloatValue(r, m) * 0.5f + b.SelectFloatValue(r, m) * 0.5f, Math.Min(a.MinValue, b.MinValue), Math.Max(a.MinValue, a.MaxValue) )); }
public static IValueGenerator Add(this IValueGenerator a, IValueGenerator b) { Contract.Requires(a != null); Contract.Requires(b != null); Contract.Ensures(Contract.Result <IValueGenerator>() != null); return(new FuncValue( (r, m) => a.SelectFloatValue(r, m) + b.SelectFloatValue(r, m), a.MinValue + b.MinValue, a.MinValue + a.MaxValue )); }
private IEnumerable <Parcel> RecursiveSplit(Parcel parcel, Func <double> random, INamedDataCollection metadata) { Contract.Requires(parcel != null); Contract.Requires(random != null); Contract.Requires(metadata != null); //Accumulate chance of termination, checking for any rule which forbods it (i.e. probability zero) float accumulator = 0; var noChance = false; for (var i = 0; i < _terminators.Count && !noChance; i++) { var c = _terminators[i].TerminationChance(parcel); if (c.HasValue) { accumulator += c.Value; noChance |= c.Value <= 0; } } //If random chance beats average of all termination chances then stop here if (accumulator / _terminators.Count >= random()) { return new[] { parcel } } ; var oabb = FitOabb(parcel, _nonOptionalObbChance.SelectFloatValue(random, metadata), _nonOptionalObbChance.SelectFloatValue(random, metadata), random); var splitLine = oabb.SplitDirection(); var children = Split(parcel, oabb, splitLine, random, metadata).ToArray(); //If any children are discarded try splitting the other way // ReSharper disable once AccessToModifiedClosure if (_terminators.Any(t => children.Any(c => t.Discard(c, random)))) { splitLine = splitLine.Perpendicular(); children = Split(parcel, oabb, splitLine, random, metadata).ToArray(); } //Either return this parcel because we can't find any valid children, or continue recursive splitting if (_terminators.Any(t => children.Any(c => t.Discard(c, random)))) { return new[] { parcel } } ; else { return(children.SelectMany(a => RecursiveSplit(a, random, metadata)).ToArray()); } }
private IEnumerable <Parcel> Split(Parcel parcel, OABR oabb, Vector2 sliceDirection, Func <double> random, INamedDataCollection metadata) { Contract.Requires(parcel != null); Contract.Requires(random != null); Contract.Requires(metadata != null); var extent = (oabb.Max - oabb.Min) / 2; var point = oabb.Middle + Math.Max(extent.X, extent.Y) * sliceDirection.Perpendicular() * _splitPoint.SelectFloatValue(random, metadata); var slices = parcel.Points().SlicePolygon(new Ray2(point, sliceDirection)); return(slices.Select(a => ToParcel(parcel, a))); }