lixiaojun
2025-04-03 2e52f10a2cccb1471859b05e0d0e9dd9649859c8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
namespace Yw.WinFrmUI.Hydro
{
    /// <summary>
    /// 射线碰撞
    /// </summary>
    internal static class Ray32dCaster
    {
 
        /// <summary>
        /// 投射
        /// </summary>
        /// <param name="ray">射线</param>
        /// <param name="zoom">缩放</param>
        /// <param name="visuals">可见构件列表</param>
        /// <param name="vecache">点缓存</param>
        public static List<VisualL3d> Casting(this Ray3 ray, float zoom, List<VisualL3d> visuals, Vector3CacheHelper vecache)
        {
            if (ray == null)
            {
                return default;
            }
            if (visuals == null || visuals.Count < 1)
            {
                return default;
            }
            if (vecache == null)
            {
                return default;
            }
            var list = new List<VisualL3d>();
            foreach (var visual in visuals)
            {
                if (visual is NodeL3d node)
                {
                    var vec = vecache.GetById(node.Id);
                    var epsilon = node.Style2d.Normal.Radiu * zoom;
                    if (ray.IntersectsPoint(vec[0], epsilon, float.MaxValue, out _))
                    {
                        list.Add(visual);
                    }
                }
                else if (visual is LinkL3d link)
                {
                    var vec = vecache.GetById(link.Id);
                    var epsilon = link.Style2d.Normal.Width / 2f * zoom;
                    if (ray.IntersectsLine(vec[0], vec[1], epsilon, float.MaxValue, out _))
                    {
                        list.Add(visual);
                    }
                }
            }
            return list;
        }
 
        /// <summary>
        /// 投射最近节点
        /// </summary>
        /// <param name="ray">射线</param>
        /// <param name="zoom">缩放</param>
        /// <param name="nodes">节点</param>
        /// <param name="vecache">点缓存</param>
        /// <returns></returns>
        public static NodeL3d CastingClosest(this Ray3 ray, float zoom, List<NodeL3d> nodes, Vector3CacheHelper vecache)
        {
            if (ray == null)
            {
                return default;
            }
            if (nodes == null || nodes.Count < 1)
            {
                return default;
            }
            if (vecache == null)
            {
                return default;
            }
            NodeL3d closest = null;
            float minDistance = float.MaxValue;
            foreach (var node in nodes)
            {
                var vec = vecache.GetById(node.Id);
                var epsilon = node.Style2d.Normal.Radiu * zoom;
                if (ray.IntersectsPoint(vec[0], epsilon, float.MaxValue, out float distance))
                {
                    if (distance <= minDistance)
                    {
                        minDistance = distance;
                        closest = node;
                    }
                }
            }
            return closest;
        }
 
        /// <summary>
        /// 投射最近管段
        /// </summary>
        /// <param name="ray">射线</param>
        /// <param name="links">管段</param>
        /// <param name="vecache">点缓存</param>
        /// <returns></returns>
        public static LinkL3d CastingClosest(this Ray3 ray, float zoom, List<LinkL3d> links, Vector3CacheHelper vecache)
        {
            if (ray == null)
            {
                return default;
            }
            if (links == null || links.Count < 1)
            {
                return default;
            }
            if (vecache == null)
            {
                return default;
            }
            LinkL3d closest = null;
            float minDistance = float.MaxValue;
            foreach (var link in links)
            {
                var vec = vecache.GetById(link.Id);
                var epsilon = link.Style2d.Normal.Width * zoom;
                if (ray.IntersectsLine(vec[0], vec[1], epsilon, float.MaxValue, out float distance))
                {
                    if (distance <= minDistance)
                    {
                        minDistance = distance;
                        closest = link;
                    }
                }
            }
            return closest;
        }
 
        /// <summary>
        /// 投射最近构件
        /// </summary>
        /// <param name="ray">射线</param>
        /// <param name="nw">管网</param>
        /// <param name="vecache">点缓存</param>
        /// <returns></returns>
        public static VisualL3d CastingClosest(this Ray3 ray, float zoom, NetworkL3d nw, Vector3CacheHelper vecache)
        {
            VisualL3d visual = CastingClosest(ray, zoom, nw?.Nodes, vecache);
            if (visual == null)
            {
                visual = CastingClosest(ray, zoom, nw?.Links, vecache);
            }
            return visual;
        }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
    }
}