/// <summary> /// Gets the segment at the vertices provided if it exists, or creates /// it if not. /// </summary> /// <param name="start">The start vertex.</param> /// <param name="end">The end vertex.</param> /// <param name="line">The line (optional).</param> /// <returns>Either a newly allocated BSP segment, or the one that /// already exists with the information provided.</returns> public BspSegment GetOrCreate(BspVertex start, BspVertex end, IBspUsableLine line = null) { Debug.Assert(start != end, "Cannot create a segment that is a point"); (int smallerIndex, int largerIndex) = start.Index.MinMax(end.Index); if (segmentTable.TryGetValue(smallerIndex, out var largerValues)) { if (largerValues.TryGetValue(largerIndex, out int segIndex)) { return(segments[segIndex]); } largerValues[largerIndex] = segments.Count; int newCollinearIndex = GetCollinearIndex(start, end); return(CreateNewSegment(start, end, newCollinearIndex, line)); } var largerIndexDict = new Dictionary <int, int> { [largerIndex] = segments.Count }; int collinearIndex = GetCollinearIndex(start, end); segmentTable[smallerIndex] = largerIndexDict; return(CreateNewSegment(start, end, collinearIndex, line)); }
/// <summary> /// Creates a subsector edge from some geometric data and for some /// side. /// </summary> /// <param name="start">The starting point.</param> /// <param name="end">The ending point.</param> /// <param name="line">The line this is on top of, or null if this is /// a miniseg.</param> /// <param name="front">True if this is on the front side, false if it /// is the back. This value is not used if this is a miniseg. This /// must never be false for a one sided line.</param> public SubsectorEdge(Vec2D start, Vec2D end, IBspUsableLine line = null, bool front = true) { Start = start; End = end; IsFront = front; Line = line; }
private BspSegment CreateNewSegment(BspVertex start, BspVertex end, int collinearIndex, IBspUsableLine line = null) { BspSegment seg = new BspSegment(start, end, collinearIndex, line); segments.Add(seg); return(seg); }
/// <summary> /// Creates a new BSP segment from the data provided. This will also /// add itself to the vertices provided as an edge reference. /// </summary> /// <param name="start">The start vertex.</param> /// <param name="end">The end vertex.</param> /// <param name="collinearIndex">The index for collinearity. See /// <see cref="CollinearTracker"/> for more info.</param> /// <param name="line">The line (if any, this being null implies it is /// a miniseg).</param> public BspSegment(BspVertex start, BspVertex end, int collinearIndex, IBspUsableLine line = null) : base(start, end) { Debug.Assert(start != end, "BSP segment shouldn't have a start and end index being the same"); StartVertex = start; EndVertex = end; CollinearIndex = collinearIndex; Line = new Optional <IBspUsableLine>(line); start.Edges.Add(this); end.Edges.Add(this); Debug.Assert(Length() >= 0.00001, "Extremely small BSP segment detected"); }