public void TraversePositionSet_ConnectedAndSpringEvent(IPositionSet ps) { if (OnGetConnection != null) { IPosition_Connected[] ary = (IPosition_Connected[])ps.ToArray(); if (ary != null) { foreach (IPosition_Connected p in ary) { float x = layer.ConvertPositionSetXToScreenX(p.GetX()); float y = layer.ConvertPositionSetYToScreenY(p.GetY()); IPositionSet_Connected_Adjacency adj_set = p.GetAdjacencyPositionSet(); adj_set.InitToTraverseSet(); while (adj_set.NextPosition()) { IPosition_Connected adj = adj_set.GetPosition_Connected(); float adj_x = layer.ConvertPositionSetXToScreenX(adj.GetX()); float adj_y = layer.ConvertPositionSetYToScreenY(adj.GetY()); OnGetConnection(x, y, adj_x, adj_y); } } } } TraversePositionSetAndSpringEvent(ps); }
//计算多边形的(有向)面积 public static double GetArea(IPositionSet ps) { double sum = 0; IPosition[] pa = (IPosition[])ps.ToArray(); int n = pa.Length; int nn; //判断是否首尾相接的点序列 if (pa[0] != pa[n - 1]) { nn = n + 1; } else { nn = n; } //计算叉积和 for (int i = 0; i < nn - 1; i++) { sum += pa[i].GetX() * pa[(i + 1) % n].GetY() - pa[i].GetY() * pa[(i + 1) % n].GetX(); } //计算面积 return(sum / 2); }
/* * public SimplePositionSet ConvexHull(SimplePositionSet ps) * { * int n = ps.GetCount(); * Point[] pts = new Point[n]; * for (int i = 0; i < n; i++) * { * SimplePosition pos = ps.GetNextPosition(); * pts[i] = new Point(pos.GetX(), pos.GetY()); * } * Point[] resPts = _ConvexHull(pts); * SimplePositionSet result = new SimplePositionSet(); * for (int i = 0; i < resPts.Length; i++) * result.AddPosition(new SimplePosition(resPts[i].X, resPts[i].Y)); * return result; * } */ public IPositionSet ConvexHull(IPositionSet ps) { //转换成数组 IPosition[] posArr = (IPosition[])ps.ToArray(); int N = posArr.Length; //排序 Polysort.Quicksort(posArr); IPosition left = posArr[0]; IPosition right = posArr[N - 1]; // Partition into lower hull and upper hull CDLL lower = new CDLL(left), upper = new CDLL(left); for (int i = 0; i < N; i++) { double det = Area2(left, right, posArr[i]); if (det > 0) { upper = upper.Append(new CDLL(posArr[i])); } else if (det < 0) { lower = lower.Prepend(new CDLL(posArr[i])); } } lower = lower.Prepend(new CDLL(right)); upper = upper.Append(new CDLL(right)).Next; // Eliminate points not on the hull eliminate(lower); eliminate(upper); // Eliminate duplicate endpoints 消除重复点 /* * if (lower.Prev.val.Equals(upper.val)) * lower.Prev.Delete(); * if (upper.Prev.val.Equals(lower.val)) * upper.Prev.Delete(); * */ // Join the lower and upper hull IPosition[] res = new IPosition[lower.Size() + upper.Size()]; lower.CopyInto(res, 0); upper.CopyInto(res, lower.Size()); PositionSetEdit_ImplementByICollectionTemplate result = new PositionSetEdit_ImplementByICollectionTemplate(); for (int i = 0; i < res.Length - 1; i++) { result.AddPosition(res[i]); } return(result); }
public static void lanch(IConvexHullEngine chEngine, int pointCount, float min, float max) { //求解凸包并作图 //IPositionSet ps = testData(); IPositionSet ps = new RandomPositionSet(pointCount, min, max); //System.Console.Out.WriteLine("position set:"); //printPositionSet(ps); IPositionSet cps = chEngine.ConvexHull(ps); //System.Console.Out.WriteLine("Jarvis Match:"); //printPositionSet(cps); PainterDialog.Clear(); PainterDialog.DrawPositionSet(ps); PainterDialog.DrawConvexHull(cps); PainterDialog.Show(); AnalyzeReport report = new AnalyzeReport(); //测试点集引用 cps.InitToTraverseSet(); ps.InitToTraverseSet(); bool correct = true; while (correct && cps.NextPosition()) { IPosition cp = cps.GetPosition(); bool find = false; ps.InitToTraverseSet(); while (!find && ps.NextPosition()) { IPosition p = ps.GetPosition(); if (cp == p) { find = true; } } if (!find) { correct = false; } } report.content += "引用测试:" + (correct ? "正确" : "错误") + "\n"; //测试凸包 if (correct) { report.content += "凸包正确性测试:\n"; IPositionSet cps_ref = (new QuickHull()).ConvexHull(ps); // System.Console.Out.WriteLine("Quick Hull:"); // printPositionSet(cps_ref); IPosition[] cpa = (IPosition[])(cps.ToArray()); IPosition[] cpa_ref = (IPosition[])(cps_ref.ToArray()); if (cpa.Length != cpa_ref.Length) { report.content += "数目不等"; correct = false; } if (correct) { int n = cpa.Length; int m = 0; int p = 0; for (; p < n; p++) { if (cpa[0] == cpa_ref[p]) { break; } } if (p == n) { correct = false; report.content += "发生错误!"; } if (correct) { for (int i = 0; i < n; i++) { if (cpa[i] == cpa_ref[(p + i + n) % n]) { m++; } } int tm = 0; for (int i = 0; i < n; i++) { if (cpa[i] == cpa_ref[(p - i + n) % n]) { tm++; } } if (tm > m) { m = tm; } report.content += "正确率:" + m.ToString() + "/" + n.ToString(); if (m == n) { report.content += "正确!"; } else { report.content += "不正确!"; } } } } report.Show(); }
/// <summary> /// 遍历positionSet并产生相应的事件(如果有新的时间请在里面添加,并在ResetPainter函数里面设为null) /// </summary> /// <param name="ps"></param> public void TraversePositionSetAndSpringEvent(IPositionSet ps) { ps.InitToTraverseSet(); IPosition[] positionSet_ary = (IPosition[])ps.ToArray(); for (int i = 0; i < positionSet_ary.Length; i++) { if (OnGetRealCoordinate != null) { this.OnGetRealCoordinate(layer.ConvertPositionSetXToRealX(positionSet_ary[i].GetX()), layer.ConvertPositionSetYToRealY(positionSet_ary[i].GetY())); } //DrawPointX和DrawPointY是屏幕上显示的坐标 float DrawPointX = layer.ConvertPositionSetXToScreenX(positionSet_ary[i].GetX()); float DrawPointY = layer.ConvertPositionSetYToScreenY(positionSet_ary[i].GetY()); if (i == 0) { if (OnGetFirstPoint != null) { this.OnGetFirstPoint(DrawPointX, DrawPointY); } } else if (i == positionSet_ary.Length - 1) { if (OnGetLastPoint != null) { this.OnGetLastPoint(DrawPointX, DrawPointY); } } else { if (OnGetMiddlePoint != null) { this.OnGetMiddlePoint(DrawPointX, DrawPointY); } } if (OnGetPoint != null) { this.OnGetPoint(DrawPointX, DrawPointY); } } #region old implement //if (OnGetLastPoint != null) //{ // this.OnGetLastPoint(x, y); //} //if (ps.NextPosition()) //{ // if (OnGetRealPoint != null) // { // this.OnGetRealPoint(ps.GetPosition().GetX(), ps.GetPosition().GetY()) // } // x = ps.GetPosition().GetX() * scaleX + translationX; // y = -(ps.GetPosition().GetY() * scaleY + translationY); // if (OnGetFirstPoint != null) // { // this.OnGetFirstPoint(x, y); // } // if (OnGetPoint != null) // { // this.OnGetPoint(x, y); // } //} //while (ps.NextPosition()) //{ // if (OnGetRealPoint != null) // { // this.OnGetRealPoint(ps.GetPosition().GetX(), ps.GetPosition().GetY()) // } // x = ps.GetPosition().GetX() * scaleX + translationX; // y = ps.GetPosition().GetY() * scaleY + translationY; // if (OnGetMiddlePoint != null) // { // if(ps.NextPosition()) // { // this.OnGetMiddlePoint(x, y); // } // } // if (OnGetPoint != null) // { // this.OnGetPoint(x, y); // } //} //if (OnGetLastPoint != null) //{ // this.OnGetLastPoint(x, y); //} #endregion }