public void DisconnectFrom(Road rd) { Assert.IsTrue(RoadsConnectedTo.Contains(rd)); RoadsConnectedTo.Remove(rd); }
/// <summary> /// Given a road and a new position to add to the road, /// gets or creates a vertex to add to the road. /// The vertex will always already be added to the vertex BVH. /// If the returned vertex is null, it shouldn't be added to the road. /// If "EndRoad" is true, the road should not continue on. /// </summary> private VertexFindResults FindOrMakeVertex(Road r, Vector2 nextPos) { Vertex lastPoint = r.Points[r.Points.Count - 1]; //Reject if the segment length is too short or its position is outside the city limits. if (lastPoint.Pos.DistSqr(nextPos) <= (SegmentMinLength * SegmentMinLength) || !IsInBounds(nextPos)) { return(VertexFindResults.Reject()); } //If the next position is near another vertex, use that vertex and end the road there. foreach (Vertex v in Vertices.GetAllNearbyPos(nextPos)) { //Don't let the road loop back onto itself. if (v.RoadsConnectedTo.Contains(r)) { continue; } //Don't create a segment that already exists. if (v.VertsConnectedTo.Contains(lastPoint)) { return(VertexFindResults.Reject()); } v.ConnectTo(lastPoint); return(VertexFindResults.Accept(v, true)); } Rect segBnds = new Rect().BoundByPoints(nextPos, lastPoint.Pos); //If the segment intersects another segment, turn it into an intersection and continue. List <Segment> segs = Segments.GetAllNearbyBnds(segBnds).ToList(); float t1 = float.NaN, t2 = float.NaN; Segment?hitSeg = null; //Get any intersected segments. //If we intersect with a previous part of this road, reject. for (int i = 0; i < segs.Count; ++i) { float temp1 = float.NaN, temp2 = float.NaN; bool intersects = GeneratorUtils.SegmentsIntersect(lastPoint.Pos, nextPos, segs[i].P1.Pos, segs[i].P2.Pos, ref temp1, ref temp2); if (segs[i].Owner == r || segs[i].P1.RoadsConnectedTo.Contains(r) || segs[i].P2.RoadsConnectedTo.Contains(r)) { if (intersects) { return(VertexFindResults.Reject()); } } else if (intersects) { t1 = temp1; t2 = temp2; hitSeg = segs[i]; } } if (hitSeg.HasValue) { //Split up the road that the segment is a part of // by adding a new vertex at the intersection. Vertex vtx = new Vertex(hitSeg.Value.P1.Pos + ((hitSeg.Value.P2.Pos - hitSeg.Value.P1.Pos) * t2)); vtx.ConnectTo(lastPoint); Vertices.Add(vtx); SplitSegment(vtx, hitSeg.Value); return(VertexFindResults.Accept(vtx, false)); } //This segment isn't special in any way. Vertex vert = new Vertex(nextPos); vert.ConnectTo(lastPoint); Vertices.Add(vert); return(VertexFindResults.Accept(vert, false)); }
public void ConnectTo(Road rd) { Assert.IsTrue(!RoadsConnectedTo.Contains(rd)); RoadsConnectedTo.Add(rd); }