예제 #1
0
        public float SelectFloatValue(Func <double> random, INamedDataCollection data)
        {
            Contract.Requires(random != null);
            Contract.Requires(data != null);

            return(default(float));
        }
        protected override float GenerateFloatValue(Func <double> random, INamedDataCollection data)
        {
            Contract.Requires(random != null);
            Contract.Requires(data != null);

            return(default(float));
        }
예제 #3
0
        public override ITerminationRule Rule(Func <double> random, INamedDataCollection metadata)
        {
            Contract.Requires(random != null);
            Contract.Requires(metadata != null);

            return(default(ITerminationRule));
        }
예제 #4
0
        public override IReadOnlyList <Vector2> Apply(Func <double> random, INamedDataCollection metadata, IReadOnlyList <Vector2> footprint, IReadOnlyList <Vector2> basis, IReadOnlyList <Vector2> lot)
        {
            var center  = footprint.Aggregate((a, b) => a + b) / footprint.Count;
            var radians = _angle.SelectFloatValue(random, metadata).ToRadians();

            return(footprint.Select(a => Vector3.Transform((a - center).X_Y(0), Quaternion.CreateFromAxisAngle(Vector3.UnitY, radians)).XZ() + center).ToArray());
        }
예제 #5
0
        public void Build(TracingConfiguration config, Func <double> random, INamedDataCollection metadata, Region region)
        {
            Contract.Requires(config != null);
            Contract.Requires(random != null);
            Contract.Requires(metadata != null);
            Contract.Requires(region != null);

            //var extent = region.Max - region.Min;
            //var eigens = config.TensorField.Presample(new Vector2(region.Min.X, region.Min.Y), new Vector2(region.Max.X, region.Max.Y), (int)Math.Max(extent.X, extent.Y));

            var ex     = _max - _min;
            var eigens = config.TensorField.Presample(_min, _max, (uint)Math.Max(ex.X, ex.Y));

            var seeds = SeedsAlongEdge(region, config.SeparationField, eigens.MajorEigenVectors, eigens.MinorEigenVectors);

            Build(seeds, region.Min, region.Max,
                  config.SeparationField,
                  true, true,
                  config.MergeDistance,
                  config.SegmentLength,
                  config.CosineSearchConeAngle,
                  p => !region.PointInPolygon(p), e => e.Streamline.Region == region,
                  s => {
                s.Width  = (uint)config.RoadWidth.SelectIntValue(random, metadata);
                s.Region = region;

                LinearReduction(s);
            });
        }
예제 #6
0
        /// <summary>
        /// Get the sidewalk width, or if one has not been generated, generate one based off MinimumSidewalkWidthName and MaximumSidewalkWidthName value
        /// </summary>
        /// <param name="provider">The provider to get and put value from/to</param>
        /// <param name="random">A random number generator (generating values from 0 to 1)</param>
        /// <param name="min">The minimum allowable value</param>
        /// <param name="max">The maximum allowable value</param>
        /// <returns></returns>
        public static float RoadSidewalkWidth(this INamedDataCollection provider, Func <double> random, float?min = null, float?max = null)
        {
            Contract.Requires(provider != null);
            Contract.Requires(random != null);

            return(provider.DetermineHierarchicalValue(random, MathHelper.Lerp, RoadSidewalkWidthName, MinimumSidewalkWidthName, MaximumSidewalkWidthName, min, max));
        }
예제 #7
0
        public override void Subdivide(Prism bounds, ISubdivisionGeometry geometry, INamedDataCollection hierarchicalParameters)
        {
            //Select external building parameters
            var externals = SelectExternals().ToArray();

            //Create things
            _floors    = CreateFloors(SelectFloors().ToArray(), Footprints(externals));
            _verticals = SelectVerticals().ToArray();
            _facades   = CreateFacades(geometry, externals, hierarchicalParameters);

            //Setup relationship between floors (floor PrerequisiteOf floor-further-from-ground)
            foreach (var keyValuePair in _floors)
            {
                //Ground floor has no prerequisites
                if (keyValuePair.Key == 0)
                {
                    continue;
                }

                //Work out the index of the prerequisite
                var prereqIndex = keyValuePair.Key < 0 ? keyValuePair.Key + 1 : keyValuePair.Key - 1;

                //Try to find it (this *shouldn't* ever fail, if we have a continuous run of floors)
                IFloor prereq;
                if (_floors.TryGetValue(prereqIndex, out prereq))
                {
                    keyValuePair.Value.AddPrerequisite(prereq);
                }
            }
        }
예제 #8
0
        /// <summary>
        /// Get the sidewalk material, or if one has not been generated, generate one based off DefaultSidewalkMaterial
        /// </summary>
        /// <param name="provider"></param>
        /// <param name="random"></param>
        /// <param name="defaultMaterial"></param>
        /// <returns></returns>
        public static string RoadSidewalkMaterial(this INamedDataCollection provider, Func <double> random, string defaultMaterial = null)
        {
            Contract.Requires(provider != null);
            Contract.Requires(random != null);

            return(provider.DefaultMaterial(random, RoadSidewalkMaterialName, defaultMaterial ?? provider.GetValue(DefaultSidewalkMaterialName)));
        }
예제 #9
0
        /// <summary>
        /// Get the standard ceiling height, or if one has not been generated, generate one based off MinimumStandardCeilingHeightName and MaximumStandardCeilingHeightName value
        /// </summary>
        /// <param name="provider">The provider to get and put value from/to</param>
        /// <param name="random">A random number generator (generating values from 0 to 1)</param>
        /// <param name="min">The minimum allowable value</param>
        /// <param name="max">The maximum allowable value</param>
        /// <returns></returns>
        public static float StandardCeilingHeight(this INamedDataCollection provider, Func <double> random, float?min = null, float?max = null)
        {
            Contract.Requires(provider != null);
            Contract.Requires(random != null);

            return(provider.DetermineHierarchicalValue(random, MathHelper.Lerp, StandardCeilingHeightName, MinimumStandardCeilingHeightName, MaximumStandardCeilingHeightName, min, max));
        }
예제 #10
0
        /// <summary>
        /// Determine a value by deriving it from a previously calculated value and then store the result
        /// </summary>
        /// <typeparam name="T">The type of the value</typeparam>
        /// <param name="provider">Provider for previously defined value as well as the target to store the new value in</param>
        /// <param name="name">The name of the value</param>
        /// <param name="update">Function to derive a new value from an old one</param>
        /// <param name="generate">Function to generate a new value if no old one existed</param>
        /// <returns>The determined value</returns>
        public static T DetermineHierarchicalValue <T>(this INamedDataCollection provider, TypedName <T> name, Func <T, T> update, Func <T> generate) where T : IEquatable <T>
        {
            Contract.Requires(provider != null);
            Contract.Requires(update != null);
            Contract.Requires(generate != null);

            T value;

            if (provider.TryGetValue <T>(name, out value))
            {
                var oldValue = value;
                value = update(oldValue);

                if (!EqualityComparer <T> .Default.Equals(oldValue, value))
                {
                    provider.Set <T>(name, value);
                }
            }
            else
            {
                value = generate();
                provider.Set <T>(name, value);
            }

            return(value);
        }
예제 #11
0
        public void Build(TracingConfiguration config, Func <double> random, INamedDataCollection metadata, Vector2 min, Vector2 max)
        {
            Contract.Requires(config != null);
            Contract.Requires(random != null);
            Contract.Requires(metadata != null);

            if (!_begun)
            {
                Begin(min, max);
                AddBoundary(min, max);
            }

            var extent = max - min;
            var eigens = config.TensorField.Presample(min, max, (uint)Math.Max(extent.X, extent.Y));

            var count = (int)((extent.X * extent.Y) / 2500);

            Func <Vector2, bool> isOutOfBounds = v => v.X > max.X || v.X <min.X || v.Y> max.Y || v.Y < min.Y;

            var seeds = RandomSeedsInBounds(random, count, eigens.MajorEigenVectors, eigens.MinorEigenVectors, min, max, isOutOfBounds);

            Build(seeds, min, max, config.SeparationField, true, true, config.SegmentLength, config.MergeDistance, config.CosineSearchConeAngle, isOutOfBounds, null, s =>
            {
                s.Width = (uint)config.RoadWidth.SelectIntValue(random, metadata);

                LinearReduction(s);
            });
        }
예제 #12
0
        public override IReadOnlyList <Vector2> Apply(Func <double> random, INamedDataCollection metadata, IReadOnlyList <Vector2> footprint, IReadOnlyList <Vector2> basis, IReadOnlyList <Vector2> lot)
        {
            var c = new Clipper();

            const int SCALE = 1000;

            c.AddPath(footprint.Select(a => new IntPoint((int)(a.X * SCALE), (int)(a.Y * SCALE))).ToList(), PolyType.ptSubject, true);

            var clip = _lot ? lot : basis;

            c.AddPath(clip.Select(a => new IntPoint((int)(a.X * SCALE), (int)(a.Y * SCALE))).ToList(), PolyType.ptClip, true);

            var solutions = new List <List <IntPoint> >();

            c.Execute(ClipType.ctIntersection, solutions);

            var clipperSolution = solutions.Single();

            Contract.Assume(clipperSolution != null);

            if (Clipper.Orientation(clipperSolution))
            {
                clipperSolution.Reverse();
            }

            return(clipperSolution.Select(a => new Vector2(a.X / (float)SCALE, a.Y / (float)SCALE)).ToArray());
        }
예제 #13
0
        public static string DefaultMaterial(this INamedDataCollection provider, Func <double> random, TypedName <string> name, params string[] possibilities)
        {
            Contract.Requires(provider != null);
            Contract.Requires(random != null);
            Contract.Requires(possibilities != null);

            //Select a random value from the possibilities
            var generated = possibilities.Length == 0 ? null : possibilities[random.RandomInteger(0, possibilities.Length - 1)];

            return(provider.DetermineHierarchicalValue(name, oldValue =>
            {
                //If no possibilities were provided, everything is valid!
                if (possibilities.Length == 0)
                {
                    return oldValue;
                }

                //Use the old value if it is one of the allowed possibilities
                if (((IList <string>)possibilities).Contains(oldValue))
                {
                    return oldValue;
                }

                //Otherwise generate a new value (from the range of allowed possibilities)
                return generated;
            }, () => generated));
        }
예제 #14
0
        public static float ExternalWallThickness(this INamedDataCollection provider, Func <double> random, float?min = null, float?max = null)
        {
            Contract.Requires(provider != null);
            Contract.Requires(random != null);

            return(provider.DetermineHierarchicalValue(random, MathHelper.Lerp, ExternalWallThicknessName, MinimumExternalWallThicknessName, MaximumExternalWallThicknessName, min, max));
        }
예제 #15
0
        public override void Subdivide(Prism bounds, ISubdivisionGeometry geometry, INamedDataCollection hierarchicalParameters)
        {
            //Create land parcels
            var nodes = CreateParcelNodes(GenerateParcels(bounds.Footprint).ToArray(), bounds.Height).ToArray();

            //Set ground height (for nodes which care)
            foreach (var grounded in nodes.Select(node => node.Value).OfType <IGrounded>())
            {
                grounded.GroundHeight = GroundHeight;
            }

            //Build neighbour set
            var neighbours = new NeighbourSet <ISubdivisionContext>();

            foreach (var keyValuePair in nodes)
            {
                foreach (var edge in keyValuePair.Key.Edges)
                {
                    neighbours.Add(new LineSegment2(edge.Start, edge.End), keyValuePair.Value);
                }
            }

            //Associate node with their neighbours (for nodes which care)
            foreach (var neighbour in nodes.Where(node => node.Value is INeighbour))
            {
                ((INeighbour)neighbour.Value).Neighbours = CalculateNeighbours(neighbour, neighbours).ToArray();
            }
        }
예제 #16
0
 public override ITerminationRule Rule(Func <double> random, INamedDataCollection metadata)
 {
     return(new AccessRule(
                _resource,
                TerminationChance.SelectFloatValue(random, metadata)
                ));
 }
예제 #17
0
        /// <summary>
        /// Evaluate this building design spec to create a set of building internals (floors and vertical elements)
        /// </summary>
        /// <param name="random"></param>
        /// <param name="metadata"></param>
        /// <param name="finder"></param>
        /// <returns></returns>
        public Internals Internals(Func <double> random, INamedDataCollection metadata, Func <KeyValuePair <string, string>[], Type[], ScriptReference> finder)
        {
            Contract.Requires(random != null);
            Contract.Requires(metadata != null);
            Contract.Requires(finder != null);
            Contract.Ensures(Contract.Result <Internals>() != null);

            var ground      = _floorSelectors.OfType <GroundMarker>().Single();
            var aboveGround = _floorSelectors.TakeWhile(a => !(a is GroundMarker)).Append(ground).ToArray();
            var belowGround = _floorSelectors.SkipWhile(a => !(a is GroundMarker)).Skip(1).ToArray();

            List <FootprintSelection> footprints = new List <FootprintSelection>();

            //Select above ground floors, then assign indices
            var   above          = SelectFloors(random, metadata, finder, aboveGround, ground, aboveGround: true);
            int   index          = 0;
            float compoundHeight = 0;

            foreach (var run in above.Reverse())
            {
                if (run.Selection.Count > 0)
                {
                    footprints.Add(new FootprintSelection(run.Marker, index));
                    foreach (var floor in run.Selection.Reverse())
                    {
                        floor.Index          = index++;
                        floor.CompoundHeight = compoundHeight;

                        compoundHeight += floor.Height;
                    }
                }
            }

            //Select below ground floors, then assign indices
            var below = SelectFloors(random, metadata, finder, belowGround, ground, aboveGround: false);

            index          = 0;
            compoundHeight = 0;
            foreach (var run in below)
            {
                foreach (var floor in run.Selection)
                {
                    floor.Index          = --index;
                    floor.CompoundHeight = compoundHeight;

                    compoundHeight -= floor.Height;
                }
                footprints.Add(new FootprintSelection(run.Marker, index));
            }

            //Create result object (with floors)
            var internals = new Internals(this, above.Select(a => a.Selection.ToArray()).ToArray(), below.Select(a => a.Selection.ToArray()).ToArray(), footprints.ToArray());

            //Select vertical elements for floors and add to result
            internals.Verticals = SelectVerticals(random, finder, _verticalSelectors, internals.Floors).ToArray();

            //return result
            return(internals);
        }
        public override bool Check(Parcel parcel, Func <double> random, INamedDataCollection metadata)
        {
            var min   = _min.SelectFloatValue(random, metadata);
            var max   = _max.SelectFloatValue(random, metadata);
            var ratio = parcel.AspectRatio();

            return(ratio >= min && ratio <= max);
        }
예제 #19
0
        public override bool Check(Parcel parcel, Func <double> random, INamedDataCollection metadata)
        {
            var min  = _min.SelectFloatValue(random, metadata);
            var max  = _max.SelectFloatValue(random, metadata);
            var area = parcel.Area();

            return(area >= min && area <= max);
        }
예제 #20
0
        public bool Check(Parcel parcel, Func <double> random, INamedDataCollection metadata)
        {
            Contract.Requires(parcel != null);
            Contract.Requires(random != null);
            Contract.Requires(metadata != null);

            return(_constraints.All(constraint => constraint.Check(parcel, random, metadata)));
        }
예제 #21
0
        public override bool Check(Parcel parcel, Func <double> random, INamedDataCollection metadata)
        {
            Contract.Requires(parcel != null);
            Contract.Requires(random != null);
            Contract.Requires(metadata != null);

            return(default(bool));
        }
예제 #22
0
        public ITensorField Unwrap(Func <double> random, INamedDataCollection metadata)
        {
            Contract.Requires(random != null);
            Contract.Requires(metadata != null);
            Contract.Ensures(Contract.Result <ITensorField>() != null);

            return(default(ITensorField));
        }
        public TracingConfiguration Minor(Func <double> random, INamedDataCollection metadata)
        {
            Contract.Requires(random != null);
            Contract.Requires(metadata != null);
            Contract.Ensures(Contract.Result <TracingConfiguration>() != null);

            return(_minor.Unwrap(random, metadata));
        }
예제 #24
0
        public static string DefaultMaterial(this INamedDataCollection provider, Func <double> random, params string[] possibilities)
        {
            Contract.Requires(provider != null);
            Contract.Requires(random != null);
            Contract.Requires(possibilities != null);

            return(DefaultMaterial(provider, random, DefaultMaterialName, possibilities));
        }
예제 #25
0
        public override void Subdivide(Prism bounds, ISubdivisionGeometry geometry, INamedDataCollection hierarchicalParameters)
        {
            //Generate a topological map of city roads
            var m = GenerateBlockMesh();

            //Materialize the topological map into a topographical one
            MaterializeMesh(m);
        }
예제 #26
0
 public override ITerminationRule Rule(Func <double> random, INamedDataCollection metadata)
 {
     return(new AreaRule(
                _min.SelectFloatValue(random, metadata),
                _max.SelectFloatValue(random, metadata),
                TerminationChance.SelectFloatValue(random, metadata)
                ));
 }
예제 #27
0
            public ITensorField Unwrap(Func <double> random, INamedDataCollection metadata)
            {
                var tensors = Tensors;

                Contract.Assume(tensors != null);

                return(new Addition(tensors.Select(a => a.Unwrap(random, metadata)).ToArray()));
            }
        public override void Subdivide(Prism bounds, ISubdivisionGeometry geometry, INamedDataCollection hierarchicalParameters)
        {
            if (!_deleted)
            {
                base.Subdivide(bounds, geometry, _parameters ?? hierarchicalParameters);
            }

            IsSubdivided = true;
        }
예제 #29
0
        public IEnumerable <ISpec> Expand(Func <double> random, INamedDataCollection metadata)
        {
            var count = Count.SelectIntValue(random, metadata);

            for (var i = 0; i < count; i++)
            {
                yield return(Space);
            }
        }
        public override IEnumerable <FloorRun> Select(Func <double> random, INamedDataCollection metadata, Func <KeyValuePair <string, string>[], Type[], ScriptReference> finder)
        {
            Contract.Requires(random != null);
            Contract.Requires(metadata != null);
            Contract.Requires(finder != null);
            Contract.Ensures(Contract.Result <IEnumerable <FloorRun> >() != null);

            return(default(IEnumerable <FloorRun>));
        }