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 { /// /// 任意二点の距離 /// /// /// /// 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); } /// /// 二点同じ? /// /// /// /// public static bool Equals(PointD coord1, PointD coord2) { return coord1.X == coord2.X && coord1.Y == coord2.Y; } /// /// 平行移動 /// /// /// /// public static IList OffsetCoords(IList coords, double offset) { var path = new List(); 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; } } }