private void OptimizePatches() { var patchesToOptimize = Patches.Where(p => p.WithinCity).ToList(); var shapesToClean = new List <Polygon> (); foreach (var patch in patchesToOptimize) { for (var i = 0; i < patch.Shape.Vertices.Count; i++) { var p0 = patch.Shape.Vertices[i]; var p1 = patch.Shape.Vertices[(i + 1) % patch.Shape.Vertices.Count]; if (p0 != p1 && (p0 - p1).magnitude < 8) { var shapesWithPoint = Patches.Where(p => p.Shape.Vertices.Contains(p1)).Select(p => p.Shape); var newP0 = GeometryHelpers.Scale(p0 + p1, 0.5f); foreach (var polygon in shapesWithPoint) { shapesToClean.Add(polygon); polygon.ReplaceVertex(p1, newP0); } } } } foreach (var polygon in shapesToClean.Distinct()) { var optimizedVertices = polygon.Vertices.Distinct().ToList(); polygon.Vertices.Clear(); polygon.Vertices.AddRange(optimizedVertices); } }
private void BuildRoads() { var topology = new Topology(this); var roads = new List <List <Vector2> > (); var streets = new List <List <Vector2> > (); foreach (var gate in Gates.ToList()) { var endPoint = Market.Shape.Vertices.OrderBy(v => (gate - v).magnitude).First(); var street = topology.BuildPath(gate, endPoint, topology.Outer); if (street != null) { //roads.Add(street); streets.Add(street); if (CityWall.Gates.Contains(gate)) { var direction = GeometryHelpers.Scale(gate - Center, 100000); var start = topology.Node2V.Values.OrderBy(v => (v - direction).magnitude).First(); var road = topology.BuildPath(start, gate, topology.Inner); if (road == null) { CityWall.Gates.Remove(gate); CityWall.Towers.Add(gate); Gates.Remove(gate); } else { roads.Add(road); } } } } if (!roads.Any()) { throw new InvalidOperationException("No roads into the town"); } Roads.AddRange(TidyUpRoads(roads)); Streets.AddRange(TidyUpRoads(streets)); foreach (var road in Roads) { var insideVertices = road.Where(rv => Patches.Where(p => p.Shape.ContainsPoint(rv)).All(p => p.WithinCity)).Except(Gates).ToList(); foreach (var insideVertex in insideVertices) { road.Remove(insideVertex); } } }
private static void DrawWalls(TownGeometry geometry, StringBuilder sb) { var replacedGates = new List <Vector2> (); foreach (var wall in geometry.Walls) { var start = wall.A; var end = wall.B; if (geometry.Gates.Contains(start)) { replacedGates.Add(start); start = start + GeometryHelpers.Scale(end - start, 0.3f); wall.A = start; geometry.Gates.Add(start); } if (geometry.Gates.Contains(end)) { replacedGates.Add(end); end = end - GeometryHelpers.Scale(end - start, 0.3f); wall.B = end; geometry.Gates.Add(end); } sb.Append($"<line x1=\"{start.x}\" y1=\"{start.y}\" x2=\"{end.x}\" y2=\"{end.y}\" class=\"wall\" />"); } foreach (var replacedGate in replacedGates.Distinct()) { geometry.Gates.Remove(replacedGate); } foreach (var tower in geometry.Towers) { sb.Append($"<rect width=\"8\" height=\"8\" x=\"{tower.x - 4}\" y=\"{tower.y - 4}\" class=\"tower\" />"); } foreach (var gate in geometry.Gates) { sb.Append($"<rect width=\"8\" height=\"8\" x=\"{gate.x - 4}\" y=\"{gate.y - 4}\" class=\"gate\" />"); } }
private void DrawWalls(TownGeometry geometry, StringBuilder sb) { Cube cube; WallsMesh = new GameObject("WallsMesh"); WallsMesh.transform.parent = child; WallsMesh.transform.localPosition = Vector3.zero; Walls = new GameObject("Walls"); Walls.transform.parent = child; Walls.transform.localPosition = Vector3.zero; var replacedGates = new List <Vector2> (); foreach (var wall in geometry.Walls) { var start = wall.A; var end = wall.B; if (geometry.Gates.Contains(start)) { replacedGates.Add(start); start = start + GeometryHelpers.Scale(end - start, 0.3f); wall.A = start; geometry.Gates.Add(start); } if (geometry.Gates.Contains(end)) { replacedGates.Add(end); end = end - GeometryHelpers.Scale(end - start, 0.3f); wall.B = end; geometry.Gates.Add(end); } cube = new Cube("Wall", GetLineVertices( start.x, end.x, start.y, end.y ), 0.1f, rendererOptions.WallMaterial, Walls.transform); cube.Transform.localPosition = Vector3.zero; cube = new Cube("WallMesh", GetLineVertices( start.x, end.x, start.y, end.y ), 4, rendererOptions.WallMaterial, WallsMesh.transform, false); cube.Transform.localPosition = Vector3.zero; } foreach (var replacedGate in replacedGates.Distinct()) { geometry.Gates.Remove(replacedGate); } foreach (var tower in geometry.Towers) { cube = new Cube("Tower", GetVertices(4, 4, tower.x - 2, tower.y - 2), 0.1f, rendererOptions.TowerMaterial, Walls.transform); cube.Transform.localPosition = Vector3.zero; cube = new Cube("TowerMesh", GetVertices(4, 4, tower.x - 2, tower.y - 2), 8, rendererOptions.TowerMaterial, WallsMesh.transform, false); cube.Transform.localPosition = Vector3.zero; } foreach (var gate in geometry.Gates) { cube = new Cube("Gate", GetVertices(4, 4, gate.x - 2, gate.y - 2), 0.1f, rendererOptions.GateMaterial, Walls.transform); cube.Transform.localPosition = Vector3.zero; cube = new Cube("GateMesh", GetVertices(4, 4, gate.x - 2, gate.y - 2), 6, rendererOptions.GateMaterial, WallsMesh.transform, false); cube.Transform.localPosition = Vector3.zero; } }