private void CreateBuildingOnRoad(Road road) { var cell = road.ParentCell; const int offset = 6; const float minDistance = 0.5f; //Create an offset line of this road towards the inside of the cell var offsetLine = road.GenerateOffsetParallelTowardsPoint(offset, cell.SitePoint); //calculate total length of the line var length = offsetLine.Length(); var traveled = minDistance; //keep repeating until the end is reached while (traveled < length - minDistance) { //get point on line using normalized values [0,1] var pc = traveled / length; var pos = offsetLine.FindRandomPointOnLine(pc, pc); //Create a building site from this point var bs = BuildingSite.FromPoint(pos); bs.ParentRoad = road; road.Buildings.Add(bs); //travel along the line using the width of the building site traveled += (minDistance + bs.Width / 2); } }
public BuildingSite(double x, double y) : base(x,y) { Width = 15; Height = 15; UserData = null; ParentRoad = null; }
/// <summary> /// Build a road inside a district cell /// </summary> public List <Road> BuildRoad(DistrictCell cell, bool generateInnerRoads, int subdivisions) { //Edges are the bounds of the road and will be part of the road as well var edges = cell.Edges.ToList(); //find the longest line in the cell as a start line var longest = FindLongestLineInCell(edges); //a cell edge can be shared so first remove the line from one of the shared cells //all edges of the cell are part of the road var roads = new List <Road>(); foreach (var edge in cell.Edges) { //add the original side edge var road = Road.FromLine(edge); roads.Add(road); } var innerRoads = new List <Road>(); if (generateInnerRoads && subdivisions > 0) { //Create another subdivision roads = GenerateRoad(roads, innerRoads, Road.FromLine(longest.Key), Road.FromLine(longest.Value), subdivisions - 1); } //set up a reference to the parent cell foreach (var road in roads) { road.ParentCell = cell; } return(roads); }
/// <summary> /// Keep generating roads until branches are zero /// </summary> private List <Road> GenerateRoad(List <Road> roads, List <Road> inner, Road startLine, Road endLine, int branches) { //find a new start and end point var start = startLine.Center(); var end = endLine.Center(); //When an intersection occurs break the line HandlePossibleRoadIntersections(new Line(start, end), startLine, endLine, roads, inner); //reduce branches to end recursion branches--; if (branches + 1 <= 0) { roads.AddRange(inner); return(roads); } //From the pool of lines choose 2 random ones that aren't the same var road1 = roads.GetRandomValue(); var road2 = roads.GetRandomValue(); //make sure both are unique while (road1 == road2) { road2 = roads.GetRandomValue(); } //generate a new road by connecting 2 roads return(GenerateRoad(roads, inner, road1, road2, branches)); }
private void HandlePossibleRoadIntersections(Line line, Road startLine, Road endLine, List <Road> borders, List <Road> innerRoads) { bool flipped = false; //check for possible intersection, //if an intersection happens the end point becomes the point of intersection //has to be reverse because otherwise the lines will intersect with the edges for (var i = 0; i < innerRoads.Count; i++) { var l = innerRoads[i]; //if the line intersects if (!line.IntersectsWith(l)) { continue; } //find the intersection point bool parallel = false; var ip = line.FindIntersectionPoint(l, ref parallel); //parrallel lines don't intersect so ignore if (parallel) { continue; } //Create the new line from the intersection line = CreateIntersectedLine(line, ip, ref flipped); //Split the line that is intersected with in 2 new lines if (flipped) { startLine = innerRoads[i]; } else { endLine = innerRoads[i]; } //stop at the first intersection break; } //Because of the new line the start and end line will have to be split in 2 new lines //the total of new lines will be 3 //Adjust the borders borders.Remove(startLine); borders.Remove(endLine); //create the split lines borders.Add(new Road(startLine.Start, line.Start)); borders.Add(new Road(line.Start, startLine.End)); borders.Add(new Road(endLine.Start, line.End)); borders.Add(new Road(line.End, endLine.End)); //Add the new road to the inner roads innerRoads.Add(Road.FromLine(line)); innerRoads.Remove(startLine); innerRoads.Remove(endLine); }
private void HandlePossibleRoadIntersections(Line line, Road startLine, Road endLine,List<Road> borders,List<Road> innerRoads ) { bool flipped = false; //check for possible intersection, //if an intersection happens the end point becomes the point of intersection //has to be reverse because otherwise the lines will intersect with the edges for (var i = 0; i < innerRoads.Count; i++) { var l = innerRoads[i]; //if the line intersects if (!line.IntersectsWith(l)) continue; //find the intersection point bool parallel = false; var ip = line.FindIntersectionPoint(l, ref parallel); //parrallel lines don't intersect so ignore if (parallel) continue; //Create the new line from the intersection line = CreateIntersectedLine(line, ip, ref flipped); //Split the line that is intersected with in 2 new lines if (flipped) { startLine = innerRoads[i]; } else { endLine = innerRoads[i]; } //stop at the first intersection break; } //Because of the new line the start and end line will have to be split in 2 new lines //the total of new lines will be 3 //Adjust the borders borders.Remove(startLine); borders.Remove(endLine); //create the split lines borders.Add(new Road(startLine.Start,line.Start)); borders.Add(new Road(line.Start, startLine.End)); borders.Add( new Road(endLine.Start, line.End)); borders.Add(new Road(line.End, endLine.End)); //Add the new road to the inner roads innerRoads.Add(Road.FromLine(line)); innerRoads.Remove(startLine); innerRoads.Remove(endLine); }
/// <summary> /// Keep generating roads until branches are zero /// </summary> private List<Road> GenerateRoad(List<Road> roads,List<Road> inner , Road startLine ,Road endLine, int branches) { //find a new start and end point var start = startLine.Center(); var end = endLine.Center(); //When an intersection occurs break the line HandlePossibleRoadIntersections(new Line(start,end),startLine,endLine, roads, inner); //reduce branches to end recursion branches--; if (branches + 1 <= 0) { roads.AddRange(inner); return roads; } //From the pool of lines choose 2 random ones that aren't the same var road1 = roads.GetRandomValue(); var road2 = roads.GetRandomValue(); //make sure both are unique while (road1 == road2) { road2 = roads.GetRandomValue(); } //generate a new road by connecting 2 roads return GenerateRoad(roads, inner, road1, road2, branches); }
public void DrawRoad(Road road, Color linecolor, Color startColor, Color endColor, bool drawStartEnd = true, int width = 1) { //width = line.Intersected ? width + 1 : width; DrawLine(road,linecolor, width); if (drawStartEnd) { DrawPoint(road.Start, 7, Colors.Red); DrawPoint(road.End, 7, Colors.Red); } var slope = road.Slope(); var pc = Color.FromRgb(50,50,50); foreach (var building in road.Buildings) { DrawPoint(building, 4, pc); //Draw bounds of the building //DrawRectangle(building,building.Width,building.Height,pc); var halfWidth = (building.Width/2); var halfLength = (building.Height/2); var boundX = new Point(building.X - halfWidth, building.Y - halfLength); var boundY = new Point(building.X + halfWidth, building.Y + halfLength); //DrawLine(boundY,boundX, pc, 1); } }
public static Road FromLine(Line l) { var r = new Road(l.Start, l.End) { CellLeft = l.CellLeft, CellRight = l.CellRight }; return r; }
/// <summary> /// Generate Buildings on the edges of the road /// </summary> private void GenerateBuildingsOnRoad(Road road) { //create building parent if none exists if (_buildingParent == null) { _buildingParent = new GameObject("Buildings"); _buildingParent.SetParent(_townParent); } var cell = road.ParentCell; int offset = _terrainSettings.RoadWidth; const float minDistance = 0.2f; //access building prefabs for this cell var prefabs = GetPrefabsForType(cell.DistrictType); if (prefabs == null) { return; } //Create an offset line of this road towards the inside of the cell var offsetLine = road.GenerateOffsetParallelTowardsPoint(offset, cell.SitePoint); //calculate total length of the line var length = offsetLine.Length(); var traveled = minDistance * 2; //keep repeating until the end is reached while (traveled < length - (minDistance * 2)) { //get point on line using normalized values [0,1] var pc = traveled / length; var pos = offsetLine.FindRandomPointOnLine(pc, pc); //Select a random prefab var prefab = prefabs.GetRandomValue(); //Create a building site from this point var bs = BuildingSite.FromPoint(pos); bs.ParentRoad = road; //Spawn the building SpawnBuilding(pos.ToVector3(), prefab, bs); //travel along the line using the width of the building site traveled += (minDistance + bs.Width / 2); } }
/// <summary> /// traverse a road line and draw the road texture on the terrain /// </summary> private void DrawRoad(Road road) { //road texture is always the 1st splatmap of the terrain const int roadTextureIndex = 0; const float inc = 0.05f; var roadWidth = _terrainSettings.RoadWidth; //Get start and end position of the road var start = road.Start.ToVector3(); var end = road.End.ToVector3(); //calculate distance between the start and end var distance = Vector3.Distance(start, end); //change texture at start position ChangeTerrainTexture(start, roadTextureIndex, roadWidth); //go from start to the end and change the texture at each position var currPos = Vector3.MoveTowards(start, end, inc); for (var i = 0; i <= distance / inc; i++) { ChangeTerrainTexture(currPos, roadTextureIndex, roadWidth); currPos = Vector3.MoveTowards(currPos, end, inc); } //change texture at end position ChangeTerrainTexture(end, roadTextureIndex, roadWidth); }