ホテル管理システム
ogi
yesterday 1a1c8e71fcd14858f595029f089b2d4a00202b32
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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
using System;
using System.Collections.Generic;
using System.Drawing;
 
namespace HotelPms.Share.Windows.GraphicsApi
{
    /// <summary>
    /// 重ねる判断
    /// </summary>
    public static class Overlap
    {
        /// <summary>
        /// 線(a)と線(b)
        /// </summary>
        /// <param name="a1">線aの開始頂点</param>
        /// <param name="a2">線aの終了頂点</param>
        /// <param name="b1"></param>
        /// <param name="b2"></param>
        /// <returns></returns>
        public static bool LineLine(Point a1, Point a2, Point b1, Point b2 )
        {
            // b1->b2向量 与 a1->b1向量的向量积
            var ua_t = (b2.X - b1.X) * (a1.Y - b1.Y) - (b2.Y - b1.Y) * (a1.X - b1.X);
            // a1->a2向量 与 a1->b1向量的向量积
            var ub_t = (a2.X - a1.X) * (a1.Y - b1.Y) - (a2.Y - a1.Y) * (a1.X - b1.X);
            // a1->a2向量 与 b1->b2向量的向量积
            var u_b = (b2.Y - b1.Y) * (a2.X - a1.X) - (b2.X - b1.X) * (a2.Y - a1.Y);
            // u_b == 0时,角度为0或者180 平行或者共线不属于相交
            if (u_b != 0)
            {
                var ua = ua_t / u_b;
                var ub = ub_t / u_b;
 
                if (0 <= ua && ua <= 1 && 0 <= ub && ub <= 1)
                {
                    return true;
                }
            }
            return false;
        }
 
 
        /// <summary>
        /// 矩形と矩形
        /// </summary>
        /// <param name="r1"></param>
        /// <param name="r2"></param>
        /// <returns></returns>
        public static bool RectRect(Rectangle r1, Rectangle r2)
        {
            return !(r1.Right < r2.Left || r1.Bottom < r2.Top || r2.Right < r1.Left || r2.Bottom < r1.Top);
        }
 
        /// <summary>
        /// 矩形と矩形
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static bool RectRect2(Rectangle a, Rectangle b)
        {
            var a_min_x = a.X;
            var a_min_y = a.Y;
            var a_max_x = a.X + a.Width;
            var a_max_y = a.Y + a.Height;
 
            var b_min_x = b.X;
            var b_min_y = b.Y;
            var b_max_x = b.X + b.Width;
            var b_max_y = b.Y + b.Height;
 
            return a_min_x <= b_max_x &&
                    a_max_x >= b_min_x &&
                    a_min_y <= b_max_y &&
                    a_max_y >= b_min_y;
        }
 
        /// <summary>
        /// 線と矩形
        /// </summary>
        /// <param name="a1"></param>
        /// <param name="a2"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static bool LineRect(Point a1, Point a2, Rectangle b)
        {
            var r0 = new Point(b.Left, b.Top);
            var r1 = new Point(b.Left, b.Bottom);
            var r2 = new Point(b.Right, b.Bottom);
            var r3 = new Point(b.Right, b.Top);
 
            if (LineLine(a1, a2, r0, r1)) return true;
            if (LineLine(a1, a2, r1, r2)) return true;
            if (LineLine(a1, a2, r2, r3)) return true;
            if (LineLine(a1, a2, r3, r0)) return true;
            return false;
        }
 
        /// <summary>
        /// 線とポリコン
        /// </summary>
        /// <param name="a1"></param>
        /// <param name="a2"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static bool LinePolygon(Point a1, Point a2, IList<Point> b )
        {
            var length = b.Count;
 
            for (var i = 0; i < length; ++i)
            {
                var b1 = b[i];
                var b2 = b[(i + 1) % length];
 
                if (LineLine(a1, a2, b1, b2))
                    return true;
            }
 
            return false;
        }
 
        /// <summary>
        /// ポイント イン ポリコン
        /// </summary>
        /// <param name="point"></param>
        /// <param name="polygon"></param>
        /// <returns></returns>
        public static bool PointInPolygon(Point point, IList<Point> polygon)
        {
            //* 射线法判断点是否在多边形内
            //* 点射线(向右水平)与多边形相交点的个数为奇数则认为该点在多边形内
            //* 点射线(向右水平)与多边形相交点的个数为偶数则认为该点不在多边形内
            bool inside = false;
            int x = point.X;
            int y = point.Y;
 
            // use some raycasting to test hits
            // https://github.com/substack/point-in-polygon/blob/master/index.js
            var length = polygon.Count;
 
            for (int i = 0, j = length - 1; i < length; j = i++)
            {
                int xi = polygon[i].X, yi = polygon[i].Y, xj = polygon[j].X, yj = polygon[j].Y;
                bool intersect = ((yi > y) != (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
                // (yi > y) != (yj > y)表示此条边的两个端点的y值一个大于这个点的y一个小于这个点的y
                //  (x < (xj - xi) * (y - yi) / (yj - yi) + xi) 这个看起来像是求投影呢,还没搞明白
                if (intersect) { inside = !inside; }
            }
 
            return inside;
        }
 
        /// <summary>
        /// 矩形とポリコン
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static bool RectPolygon(Rectangle a, IList<Point> b)
        {
            var r0 = new Point(a.Left, a.Top);
            var r1 = new Point(a.Left, a.Bottom);
            var r2 = new Point(a.Right, a.Bottom);
            var r3 = new Point(a.Right, a.Top);
 
            // 矩形的每条边与多边形是否相交
            if (LinePolygon(r0, r1, b)) return true;
 
            if (LinePolygon(r1, r2, b)) return true;
 
            if (LinePolygon(r2, r3, b)) return true;
 
            if (LinePolygon(r3, r0, b)) return true;
 
            // 走到这可以检测出两个图形无交点
            // 检测是否矩形包含多边形,如果多边形上存在一个点在矩形内,则相交
            int l = b.Count;
            for (int i = 0; i < l; ++i)
            {
                if (PointInPolygon(b[i], new Point[] { r0, r1, r2, r3 }))
                    return true;
            }
 
            // 检测是否多边形包含矩形,如果矩形上存在一个点在多边形内,则相交
            if (PointInPolygon(r0, b))
                return true;
 
            if (PointInPolygon(r1, b))
                return true;
 
            if (PointInPolygon(r2, b))
                return true;
 
            if (PointInPolygon(r3, b))
                return true;
 
            return false;
        }
 
        /// <summary>
        /// ポリコンとポリコン
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static bool PolygonPolygon(IList<Point> a, IList<Point> b)
        {
            int i, l;
 
            // a的每条边与b的每条边做相交检测
            for (i = 0, l = a.Count; i < l; ++i)
            {
                var a1 = a[i];
                var a2 = a[(i + 1) % l];
 
                if (LinePolygon(a1, a2, b))
                    return true;
            }
 
            // 判断两个多边形的包含关系
            for (i = 0, l = b.Count; i < l; ++i)
            {
                if (PointInPolygon(b[i], a))
                    return true;
            }
 
            // 判断两个多边形的包含关系
            for (i = 0, l = a.Count; i < l; ++i)
            {
                if (PointInPolygon(a[i], b))
                    return true;
            }
            return false;
        }
 
        /// <summary>
        /// 计算两点之间的距离    
        /// </summary>
        /// <param name="x1"></param>
        /// <param name="y1"></param>
        /// <param name="x2"></param>
        /// <param name="y2"></param>
        /// <returns></returns>
        public static double lineSpace(double x1, double y1, double x2, double y2)
        {
            double lineLength = 0;
            lineLength = Math.Sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
            return lineLength;
 
        }
 
        /// <summary>
        /// 点到线段距离  
        /// </summary>
        /// <param name="x1">線の開始頂点x</param>
        /// <param name="y1">線の開始頂点y</param>
        /// <param name="x2">線の終了頂点x</param>
        /// <param name="y2">線の終了頂点y</param>
        /// <param name="x0">点x</param>
        /// <param name="y0">点y</param>
        /// <returns></returns>
        public static double PointToLine(double x1, double y1, double x2, double y2, double x0, double y0)
        {
            double space = 0;
            double a, b, c;
            a = lineSpace(x1, y1, x2, y2);// 线段的长度    
            b = lineSpace(x1, y1, x0, y0);// (x1,y1)到点的距离    
            c = lineSpace(x2, y2, x0, y0);// (x2,y2)到点的距离    
            if (c <= 0.000001 || b <= 0.000001)
            {
                space = 0;
                return space;
            }
            if (a <= 0.000001)
            {
                space = b;
                return space;
            }
            if (c * c >= a * a + b * b)
            {
                space = b;
                return space;
            }
            if (b * b >= a * a + c * c)
            {
                space = c;
                return space;
            }
            double p = (a + b + c) / 2;// 半周长    
            double s = Math.Sqrt(p * (p - a) * (p - b) * (p - c));// 海伦公式求面积    
            space = 2 * s / a;// 返回点到线的距离(利用三角形面积公式求高)    
            return space;
        }
    }
}