/// <summary> /// 给每个点设置相对角度(角度为向量(or_Pnt,rela_Pnt)和(0,1)的夹角) /// </summary> /// <param name="or_Pnt"></param> /// <param name="rela_Pnt"></param> private void SetRelaAng(Point_qt or_Pnt, ref Point_qt rela_Pnt) { double x = rela_Pnt.X - or_Pnt.X; double y = rela_Pnt.Y - or_Pnt.Y; rela_Pnt.Rela_Ang = y / Math.Sqrt(x * x + y * y); }
/// <summary> /// 将Geometry里的Point压入Stack /// </summary> /// <returns></returns> private Stack <Point_qt> PutPoints2Stack() { Point_qt pnt_qt; Point_qt pnt_qt_1st; pnt_qt_1st = new Point_qt(this.GetX(0), this.GetY(0), this.GetZ(0)); Stack <Point_qt> stack_pnts = new Stack <Point_qt>(this.GetPointCount()); for (int i = 1; i < stack_pnts.Count; i++) { pnt_qt = new Point_qt(this.GetX(i), this.GetY(i), this.GetZ(i)); if (pnt_qt.X < pnt_qt_1st.X) { Swop(ref pnt_qt_1st, ref pnt_qt); } else if ((pnt_qt.X - pnt_qt_1st.X) < 0.000001 && pnt_qt.Y < pnt_qt_1st.Y) { Swop(ref pnt_qt_1st, ref pnt_qt); } stack_pnts.Push(pnt_qt); } stack_pnts.Push(pnt_qt_1st); return(stack_pnts); }
private void Swop(ref Point_qt p1, ref Point_qt p2) { Point_qt ptemp; ptemp = p1; p1 = p2; p2 = ptemp; }
/// <summary> /// 给list里边的Point设置相对角度 /// </summary> /// <param name="or_Pnt"></param> /// <param name="list"></param> private void SetListPntAng(Point_qt or_Pnt, ref List <Point_qt> list) { Point_qt[] ar = list.ToArray(); for (int i = 0; i < list.Count; i++) { SetRelaAng(or_Pnt, ref ar[i]); } list = ar.ToList(); }
/// <summary> /// 获得向量spnt_epnt在线段上的投影 /// </summary> /// <param name="edge"></param> /// <param name="spnt"></param> /// <param name="epnt"></param> /// <returns></returns> private double GetVecProj(Edge_qt edge, Point_qt spnt, Point_qt epnt) { Point_qt p1 = edge.FromNode; Point_qt p2 = edge.ToNode; double e1_x = p2.X - p1.X; double e1_y = p2.Y - p1.Y; double e2_x = spnt.X - epnt.X; double e2_y = spnt.Y - epnt.Y; return((e1_x * e2_x + e1_y * e2_y) / Math.Sqrt(e1_x * e1_x + e1_y * e1_y)); }
/// <summary> /// 将Geometry里的Point压入List /// </summary> /// <returns></returns> private List <Point_qt> PutPoints2List() { Point_qt pnt_qt; List <Point_qt> list_pnts = new List <Point_qt>(this.GetPointCount()); for (int i = 0; i < list_pnts.Count; i++) { pnt_qt = new Point_qt(this.GetX(i), this.GetY(i), this.GetZ(i)); list_pnts.Add(pnt_qt); } return(list_pnts); }
/// <summary> /// 返回向量P1P2上距离点P1 dis处的坐标 /// </summary> /// <param name="dis"></param> /// <param name="p1"></param> /// <param name="p2"></param> /// <returns></returns> private Point_qt CalcPnt_Coor(double dis, Point_qt p1, Point_qt p2) { Point_qt p = new Point_qt(); double X = p2.X - p1.X; double Y = p2.Y - p1.Y; double length = Math.Sqrt(X * X + Y * Y); p.X = p1.X + (p2.X - p1.X) * dis / length; p.Y = p1.Y + (p2.Y - p1.Y) * dis / length; return(p); }
/// <summary> /// 将Geometry里的Point压入List /// </summary> /// <returns></returns> private List <Point_qt> PutPoints2List() { Point_qt pnt_qt; int pCnt = qtGeometry.GetPointCount(); List <Point_qt> list_pnts = new List <Point_qt>(pCnt); for (int i = 0; i < pCnt; i++) { pnt_qt = new Point_qt(qtGeometry.GetX(i), qtGeometry.GetY(i), qtGeometry.GetZ(i)); pnt_qt.PID = i; list_pnts.Add(pnt_qt); } return(list_pnts); }
/// <summary> /// 得到点线距 /// </summary> /// <param name="edge"></param> /// <param name="pnt"></param> /// <returns></returns> private double GetD_PL(Edge_qt edge, Point_qt pnt) { double x = pnt.X; double y = pnt.Y; Point_qt p1 = edge.FromNode; Point_qt p2 = edge.ToNode; double m = p2.X - p1.X; double n = p2.Y - p1.Y; double fenzi = Math.Abs(n * x - n * p1.X - m * y + m * p1.Y); double fenmu = Math.Sqrt(n * n + m * m); return(fenzi / fenmu); }
/// <summary> /// 返回点p使得向量p1p和向量p1p2二维平面垂直(p1p2顺时针旋转90度得到p1p) /// p1p的模长为M /// </summary> /// <param name="M"></param> /// <param name="p1"></param> /// <param name="p2"></param> /// <returns></returns> private Point_qt ReferencePoint_Clock(double M, Point_qt p1, Point_qt p2) { Point_qt p = new Point_qt(); Vec2 p1p2 = new Vec2(p2.X - p1.X, p2.Y - p1.Y); Vec2 p1p = p1p2.GetCrossVec2(); if (p1p2 * p1p > 0) { p1p.X = -p1p.X; p1p.Y = -p1p.Y; } p1p = p1p.GetUnitVec2() * M; p.X = p1.X + p1p.X; p.Y = p1.Y + p1p.Y; return(p); }
/// <summary> /// 构建凸包的递归算法 /// </summary> /// <param name="RelaPnt"></param> /// <param name="stack"></param> private void Foo(Point_qt RelaPnt, Stack <Point_qt> stack) { Point_qt p2 = stack.Pop(); Point_qt p1 = stack.Pop(); if (IsLeft(p1, p2, RelaPnt)) { stack.Push(p1); stack.Push(p2); stack.Push(RelaPnt); } else { stack.Push(p1); Foo(RelaPnt, stack); } }
/// <summary> /// 判断点p3是否在线段p1p2左边 /// </summary> /// <param name="p1"></param> /// <param name="p2"></param> /// <param name="p3"></param> /// <returns></returns> private bool IsLeft(Point_qt p1, Point_qt p2, Point_qt p3) { double x_12 = p2.X - p1.X; double y_12 = p2.Y - p1.Y; double x_13 = p3.X - p1.X; double y_13 = p3.Y - p1.Y; if ((x_12 * y_13 - y_12 * x_13) < 0) { return(false); } else { return(true); } }
/// <summary> /// 根据QTGeometry里的点集构建顺序list /// </summary> /// <returns></returns> private List <Point_qt> GetSortedList() { List <Point_qt> list = PutPoints2List(); if ((list[0].X - list[list.Count - 1].X) < 0.000001 && (list[0].Y - list[list.Count - 1].Y) < 0.000001) { list.RemoveAt(0); } SortByX(ref list); orPnt = list[0]; //选出X值最小的点 list.Remove(orPnt); //移除orPnt; SetListPntAng(orPnt, ref list); //给list里边的Point赋角度值 SortByAngl(ref list); //list按角度排序 DeleSameAng(ref list); //筛选list中角度相同的点 return(list); }
/** * 以下是根据凸包得到一个最小外接矩形 * 基本思想是:根据凸包的每条边算得一个外接矩形面积,最后选取SMBR */ public List <Point_qt> GetSMBR() { Point_qt p1 = new Point_qt(); Point_qt p2 = new Point_qt(); Point_qt p3 = new Point_qt(); Point_qt p4 = new Point_qt(); List <Point_qt> list = new List <Point_qt>(); Edge_qt edge = GetBestEdge(); p1 = CalcPnt_Coor(edge.minX, edge.FromNode, edge.ToNode); p2 = CalcPnt_Coor(edge.MaxX, edge.FromNode, edge.ToNode); p3 = ReferencePoint_Clock(edge.MaxY, p2, p1); p4 = ReferencePoint_unClock(edge.MaxY, p1, p2); list.Add(p1); list.Add(p2); list.Add(p3); list.Add(p4); return(list); }
private void button1_Click(object sender, EventArgs e) { Point_qt p1; List <Point_qt> list = new List <Point_qt>(); Random ran = new Random(); for (int i = 0; i < 8; i++) { int a = ran.Next(1, 20); double b = ran.NextDouble(); p1 = new Point_qt(a); list.Add(p1); } List <Point_qt> list_pre = list; list.Sort((p, p2) => { return(p.Rela_Ang.CompareTo(p2.Rela_Ang)); }); }