// returns first intersection point with box boundary or null if there are none public static Vector2?MeetingPoint(this Ray2 ray, Box2 box) { var meetingDistance = double.PositiveInfinity; for (Vector2.Axis axis = 0; axis < Vector2.Axis.Count; axis++) { var otherAxis = 1 - axis; for (Interval.EndType end = 0; end < Interval.EndType.Count; end++) { var intersectionDistance = (box.Corner(end)[axis] - ray.Origin[axis]) / ray.Direction[axis]; if (intersectionDistance > 0) { var intersectionCoord = ray.Origin[otherAxis] + ray.Direction[otherAxis] * intersectionDistance; if (box.Range(otherAxis).Contains(intersectionCoord)) { meetingDistance = Math.Min(meetingDistance, intersectionDistance); } } } } if (double.IsPositiveInfinity(meetingDistance)) { return(null); } return(ray.PointAt(meetingDistance)); }
private void FindSplitAxis(KDNode node) { // 比较快的方法 选择范围大的维度 Vector2 range = node.max - node.min; Vector2.Axis splitAxis = Vector2.Axis.X; if (range.y > range.x) { splitAxis = Vector2.Axis.Y; } node.splitAxis = splitAxis; }
public static Interval Range(this Box2 @this, Vector2.Axis axis) { switch (axis) { case Vector2.Axis.X: return(@this.XRange); case Vector2.Axis.Y: return(@this.YRange); default: throw new ArgumentOutOfRangeException("Invalid 2D axis " + axis.ToString()); } }
// Adds a specific corridor (defined by the input parameters) to `_data`. It also adds all // secondary rooms intersecting the corridor path. private void AddCorridor(int start, int end, int constant, Vector2.Axis axis) { var t = Math.Min(start, end); while (t <= Math.Max(start, end)) { var point = Vector2.Zero; if (axis == Vector2.Axis.X) { point = new Vector2(t, constant); } else if (axis == Vector2.Axis.Y) { point = new Vector2(constant, t); } t++; foreach (Room room in Rooms.GetChildren()) { if (IsMainRoom(room)) { continue; } var topLeft = Level.WorldToMap(room.Position - room.Size / 2); var bottomright = Level.WorldToMap(room.Position + room.Size / 2); if (topLeft.x <= point.x && point.x < bottomright.x && topLeft.y <= point.y && point.y < bottomright.y) { AddRoom(room); t = axis == Vector2.Axis.X ? (int)bottomright.x : (int)bottomright.y; } _data[point] = null; } } }
private int FindSplitIndex(KDNode node, int retryOffset = 0) { // 取第一个 并将其后移 最终保证 左边都比它小 右边都比它大 有点类似于快速排序第一步 int start = node.startIndex + retryOffset; int end = node.endIndex - 1; Vector2.Axis splitAxis = node.splitAxis; int pivot = permutation[start]; while (start < end) { while (start < end && managed[permutation[end]].position[splitAxis] >= managed[pivot].position[splitAxis]) { --end; } permutation[start] = permutation[end]; while (start < end && managed[permutation[start]].position[splitAxis] <= managed[pivot].position[splitAxis]) { ++start; } permutation[end] = permutation[start]; } permutation[start] = pivot; int foundIndex = start; if (foundIndex == node.startIndex || foundIndex == node.endIndex) { // 运气不太好 出现了极限情况 if (node.startIndex + retryOffset < node.endIndex - 1) { // Debug.LogError($"再试一次 start={node.startIndex} off={retryOffset} end={node.endIndex}"); foundIndex = FindSplitIndex(node, retryOffset + 1); return(foundIndex); } } node.splitPos = managed[permutation[foundIndex]].position[splitAxis]; return(foundIndex); }
private void AddCorridor(Dictionary <Vector2, object> dataDict, float start, float end, float constant, Vector2.Axis axis) { var minVal = (int)Math.Min(start, end); var maxVal = (int)Math.Max(start, end); for (int t = minVal; t <= maxVal; t++) { var point = Vector2.Zero; if (axis == Vector2.Axis.X) { point = new Vector2(t, constant); } else { point = new Vector2(constant, t); } dataDict[point] = null; } }
/// <summary>The <c>_addCorridor</c> method adds corridor points along either the X axis or the Y axis /// starting from the <c>start</c> position to the <c>end</c> position.</summary> public void _addCorridor(Dictionary <Vector2, int> data, int start, int end, int constant, Vector2.Axis axis) { for (int t = Math.Min(start, end); t <= Math.Max(start, end); t++) { var point = Vector2.Zero; switch (axis) { case Vector2.Axis.X: point = new Vector2(t, constant); break; case Vector2.Axis.Y: point = new Vector2(constant, t); break; } data[point] = 0; } }