Пример #1
0
        // 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));
        }
Пример #2
0
        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;
        }
Пример #3
0
        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());
            }
        }
Пример #4
0
    // 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;
            }
        }
    }
Пример #5
0
        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;
        }
    }