private void FlattenRoad(RoadGraphNode node1, RoadGraphNode node2) { Point start = node1.Position; Point end = node2.Position; var vector = (end - start).Normalize(); if (node1.Neighbors.Count > 2) { start += vector * Map.TileWidth * crossroadFlatteningRadius; } else { start -= vector * Map.TileWidth * overlapRadius; } if (node2.Neighbors.Count > 2) { end -= vector * Map.TileWidth * crossroadFlatteningRadius; } else { end += vector * Map.TileWidth * overlapRadius; } rampGenerator.GenerateRamp(map, start, end, 30, 15); if (AddWaypaths) { var path = new[] { info.ObjectFactory.CreateWaypoint(start.X, start.Y), info.ObjectFactory.CreateWaypoint(end.X, end.Y) }; map.AddWaypath(string.Empty, path); } }
private ICurve GetCurve(RoadGraphNode node1, RoadGraphNode node2) { ICurve curve; if (node1.Neighbors.Count == 1 && node2.Neighbors.Count == 1) { curve = new CubicBezierCurve( node1.Position, GetControlPoint(node1), GetControlPoint(node2), node2.Position); } else if (node1.Neighbors.Count == 1 && node2.Neighbors.Count > 1) { curve = new QuadraticBezierCurve( node1.Position, GetControlPoint(node1), node2.Position); } else if (node2.Neighbors.Count == 1 && node1.Neighbors.Count > 1) { curve = new QuadraticBezierCurve( node1.Position, GetControlPoint(node2), node2.Position); } else { curve = new LinearBezierCurve(node1.Position, node2.Position); } return(curve); }
private void AddAdditionalRoadsLeadingOutOfMap() { int count = -1; while (roadsLeadingOutOfMap.Count < MinimumRoadsLeadingOutOfMap && roadsLeadingOutOfMap.Count != count) { count = roadsLeadingOutOfMap.Count; var pointsNextToBorder = from n in info.Roads.Nodes where n.CanBeConnected && n.Neighbors.Count == 2 && map.IsWithinMap(n.Position) //&& //!roadsLeadingOutOfMap.Select(r => r.Node2.Position) // .Any(p => (p - n.Position).VectorLengthSquared() < MinimumDistanceBetweenRoadsLeadingOutOfMap * MinimumDistanceBetweenRoadsLeadingOutOfMap) let x = System.Math.Min(n.Position.X, map.HeightMap.MapWidth * Map.TileWidth - n.Position.X) let y = System.Math.Min(n.Position.Y, map.HeightMap.MapHeight * Map.TileWidth - n.Position.Y) orderby System.Math.Min(x, y) select new { X = x, Y = y, Node = n }; foreach (var point in pointsNextToBorder) { if (info.IsCancellationRequested) { return; } Point destination; if (point.X < point.Y) { if (point.X < point.Node.Position.X) { destination = new Point((map.HeightMap.MapWidth + outOfMapDestinationDistance) * Map.TileWidth, point.Node.Position.Y); } else { destination = new Point(-outOfMapDestinationDistance * Map.TileWidth, point.Node.Position.Y); } } else { if (point.Y < point.Node.Position.Y) { destination = new Point(point.Node.Position.X, (map.HeightMap.MapHeight + outOfMapDestinationDistance) * Map.TileWidth); } else { destination = new Point(point.Node.Position.X, -outOfMapDestinationDistance * Map.TileWidth); } } var destinationNode = new RoadGraphNode(destination, false, false); var edge = new RoadGraphEdge(point.Node, destinationNode, (destination - point.Node.Position).VectorLength()); if (TryAddRoadLeadingOutOfMap(point.Node, destination)) { break; } } } }
public RoadGraphEdge FindJoiningIntersection(RoadGraphNode start, RoadGraphEdge target) { return(start.edges.Find(e => { return roadGraph.GetNode(e.id, e.subId).edges.Exists(edge => { return edge.id == target.id && edge.subId == target.subId; }); })); }
private Point GetControlPoint(RoadGraphNode node) { const float minLength = 100; var incoming = (node.Position - node.Neighbors.First().Position); var lengthSquared = incoming.VectorLengthSquared(); if (lengthSquared < minLength * minLength) { incoming = incoming / (float)System.Math.Sqrt(lengthSquared) * minLength; } return(node.Position + incoming); }
private void AddRoadsFromTemplateToMap(ObjectTemplate template, Map map, MapInfo info, string roadType) { var tileGraph = new TileGraph(info.Tiles, TileInfo.Free); var roads = template.Objects.Where(o => o.RoadOptions != RoadOptions.None && o.Type == ObjectTemplate.RoadTemplate).ToArray(); int count = info.Roads.Nodes.Count; ScriptObject road1, road2; for (int i = 0; i < roads.Length; i += 2) { road1 = roads[i]; road2 = roads[i + 1]; var start = info.Roads.FindNode(new Point(road1.X, road1.Y)); if (start == null) { start = new RoadGraphNode(new Point(road1.X, road1.Y), !road1.RoadOptions.HasFlag(RoadOptions.Join) && roads.Count(r2 => road1.X == r2.X && road1.Y == r2.Y) == 1, true); info.Roads.Nodes.AddLast(start); } var end = info.Roads.FindNode(new Point(road2.X, road2.Y)); if (end == null) { end = new RoadGraphNode(new Point(road2.X, road2.Y), !road2.RoadOptions.HasFlag(RoadOptions.Join) && roads.Count(r2 => road2.X == r2.X && road2.Y == r2.Y) == 1, true); info.Roads.Nodes.AddLast(end); } start.LinkTo(end); road1.Type = roadType; road2.Type = roadType; info.Roads.Segments.Add(new Tuple <ScriptObject, ScriptObject>(road1, road2)); tileGraph.UpdateTiles(new[] { map.PositionToCoordinates(start.Position), map.PositionToCoordinates(end.Position) }, TileInfo.Road); } IEnumerable <RoadGraphNode> nodes = info.Roads.Nodes.Skip(count).ToArray(); var endpoints = from r in nodes where !r.CanBeConnected && r.Neighbors.Count == 1 select r; foreach (var endpoint in endpoints) { foreach (var node in nodes) { if (node != endpoint && (node.Position - endpoint.Position).VectorLengthSquared() < endpointConnectionRange * endpointConnectionRange) { endpoint.LinkTo(node); } } } }
private void RemoveEdge(RoadGraphNode[] roadGraph, int id, int subId, int toId, int toSubId) { if (roadGraph[id * 50 + subId] == null) { roadGraph[id * 50 + subId] = new RoadGraphNode(); roadGraph[id * 50 + subId].edges = new List <RoadGraphEdge>(); } if (roadGraph[id * 50 + subId].edges.Any(e => e.id == toId && e.subId == toSubId)) { //remove only exist roadGraph[id * 50 + subId].edges.RemoveAll(e => e.id == toId && e.subId == toSubId); } else { Debug.Log("No corresponding edge exist, stop removing"); } }
private bool TryAddRoadLeadingOutOfMap(RoadGraphNode node, Point destination) { if (roadsLeadingOutOfMap.Any(r => (destination - r.Node2.Position).VectorLengthSquared() < MinimumDistanceBetweenRoadsLeadingOutOfMap * MinimumDistanceBetweenRoadsLeadingOutOfMap)) { return(false); } var destinationNode = new RoadGraphNode(destination, false, false); var edge = new RoadGraphEdge(node, destinationNode, (destination - node.Position).VectorLength()); if (TryAddEdge(edge)) { info.Roads.Nodes.AddLast(destinationNode); roadsLeadingOutOfMap.Add(edge); return(true); } return(false); }
private void AddEdge(RoadGraphNode[] roadGraph, int id, int subId, int toId, int toSubId) { if (roadGraph[id * 50 + subId] == null) { roadGraph[id * 50 + subId] = new RoadGraphNode(); roadGraph[id * 50 + subId].edges = new List <RoadGraphEdge>(); } if (roadGraph[id * 50 + subId].edges.Any(e => e.id == toId && e.subId == toSubId)) { //already exists } else { roadGraph[id * 50 + subId].edges.Add(new RoadGraphEdge() { id = toId, subId = toSubId }); } }
private double CalculateSquaredDistance(RoadGraphNode node1, RoadGraphNode node2) { return((node1.Position - node2.Position).VectorLength()); }
private bool CanAddIncomingRoad(RoadGraphNode node, Point position) { var incoming = node.Position - position; return(node.Neighbors.All(n => Angle.Between(incoming, node.Position - n.Position) >= Angle.ToRadians(minAngleBetweenCrossroads))); }
public RoadGraphEdge(RoadGraphNode node1, RoadGraphNode node2, float length) { Node1 = node1; Node2 = node2; Length = length; }