ホテル管理システム
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
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace HotelPms.Share.Windows.GraphicsApi
{
    public class Geometry
    {
        /// <summary>
        /// 任意二点の距離
        /// </summary>
        /// <param name="coord1"></param>
        /// <param name="coord2"></param>
        /// <returns></returns>
        public static double Dist2d(PointD coord1, PointD coord2)
        {
            double dx = coord1.X - coord2.X;
            double dy = coord1.Y - coord2.Y;
            return Math.Sqrt(dx * dx + dy * dy);
        }
 
        /// <summary>
        /// 二点同じ?
        /// </summary>
        /// <param name="coord1"></param>
        /// <param name="coord2"></param>
        /// <returns></returns>
        public static bool Equals(PointD coord1, PointD coord2)
        {
            return coord1.X == coord2.X && coord1.Y == coord2.Y;
        }
 
        /// <summary>
        /// 平行移動
        /// </summary>
        /// <param name="coords"></param>
        /// <param name="offset"></param>
        /// <returns></returns>
        public static IList<PointD> OffsetCoords(IList<PointD> coords, double offset)
        {
            var path = new List<PointD>();
            int N = coords.Count - 1;
            int max = N;
            double mi, mi1, li, li1, ri, ri1, si, si1, Xi1, Yi1;
            PointD p0, p1, p2;
 
            var isClosed = Equals(coords[0], coords[N]);
            if (!isClosed)
            {
                p0 = coords[0];
                p1 = coords[1];
 
                double qq1 = Dist2d(p0, p1);
                double qq2 = (p1.Y - p0.Y);
                double qq3 = qq2 / qq1;
                double qq4 = qq3 * offset;
                double qq5 = p0.X + qq4;
 
                p2 = new PointD(p0.X + (p1.Y - p0.Y) / Dist2d(p0, p1) * offset, p0.Y - (p1.X - p0.X) / Dist2d(p0, p1) * offset);
                path.Add(p2);
                coords.Add(coords[N].Clone());
                N++;
                max--;
            }
 
            for (var i = 0; i < max; i++)
            {
                p0 = coords[i];
                p1 = coords[(i + 1) % N];
                p2 = coords[(i + 2) % N];
                mi = (p1.Y - p0.Y) / (p1.X - p0.X);
                mi1 = (p2.Y - p1.Y) / (p2.X - p1.X);
 
                // Prevent alignements
                if (Math.Abs(mi - mi1) > 1e-10)  //0.0000000001
                {
                    li = Math.Sqrt((p1.X - p0.X) * (p1.X - p0.X) + (p1.Y - p0.Y) * (p1.Y - p0.Y));
                    li1 = Math.Sqrt((p2.X - p1.X) * (p2.X - p1.X) + (p2.Y - p1.Y) * (p2.Y - p1.Y));
                    ri = p0.X + offset * (p1.Y - p0.Y) / li;
                    ri1 = p1.X + offset * (p2.Y - p1.Y) / li1;
                    si = p0.Y - offset * (p1.X - p0.X) / li;
                    si1 = p1.Y - offset * (p2.X - p1.X) / li1;
                    Xi1 = (mi1 * ri1 - mi * ri + si - si1) / (mi1 - mi);
                    Yi1 = (mi * mi1 * (ri1 - ri) + mi1 * si - mi * si1) / (mi1 - mi);
 
                    // Correction for vertical lines
                    if (p1.X - p0.X == 0)
                    {
                        Xi1 = p1.X + offset * (p1.Y - p0.Y) / Math.Abs(p1.Y - p0.Y);
                        Yi1 = mi1 * Xi1 - mi1 * ri1 + si1;
                    }
                    if (p2.X - p1.X == 0)
                    {
                        Xi1 = p2.X + offset * (p2.Y - p1.Y) / Math.Abs(p2.Y - p1.Y);
                        Yi1 = mi * Xi1 - mi * ri + si;
                    }
                    path.Add(new PointD(Xi1, Yi1));
                }
            }
 
            if (isClosed) 
            {
                path.Add(path[0].Clone());
            } 
            else
            {
                coords.RemoveAt(coords.Count - 1);
                p0 = coords[coords.Count - 1];
                p1 = coords[coords.Count - 2];
                p2 = new PointD(p0.X - (p1.Y - p0.Y) / Dist2d(p0, p1) * offset, p0.Y + (p1.X - p0.X) / Dist2d(p0, p1) * offset);
                path.Add(p2);
            }
            return path;
        }
    }
}