线段余弦角+凸包算法
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 | /// /// 根据余弦定理求两个线段夹角 /// /// 端点 /// start点 /// end点 /// double Angle(PointF o, PointF s, PointF e) { double cosfi = 0, fi = 0, norm = 0; double dsx = s.X - o.X; double dsy = s.Y - o.Y; double dex = e.X - o.X; double dey = e.Y - o.Y; cosfi = dsx * dex + dsy * dey; norm = (dsx * dsx + dsy * dsy) * (dex * dex + dey * dey); cosfi /= Math.Sqrt(norm); if (cosfi >= 1.0) return 0; if (cosfi <= -1.0) return Math.PI; fi = Math.Acos(cosfi); if (180 * fi / Math.PI < 180) { return 180 * fi / Math.PI; } else { return 360 - 180 * fi / Math.PI; } } /// <summary> /// 凸包算法 /// </summary> /// <param name="_list"></param> /// <returns></returns> private List<TuLine> BruteForceTu(List<Info> _list) { //记录极点对 List<TuLine> role = new List<TuLine>(); //遍历 for ( int i = 0; i < _list.Count - 1; i++) { for ( int j = i + 1; j < _list.Count; j++) { double a = _list[j].Y - _list[i].Y; double b = _list[i].X - _list[j].X; double c = _list[i].X * _list[j].Y - _list[i].Y * _list[j].X; int count = 0; //将所有点代入方程 for ( int k = 0; k < _list.Count; k++) { double result = a * _list[k].X + b * _list[k].Y - c; if (result > 0) { count++; } else if (result < 0) { count--; } } //是极点,则将连线记录下来 if (Math.Abs(count) == _list.Count - 2) { TuLine line = new TuLine(); IPoint pi = new PointClass(); pi.X = _list[i].X; pi.Y = _list[i].Y; line.Begin = pi; IPoint Pj = new PointClass(); Pj.X = _list[j].X; Pj.Y = _list[j].Y; line.End = Pj; role.Add(line); } } } return role; } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步