void phi() { Point[] points_in_new_coord_where_Q_center = new Point[n]; int qx = Q.Value.X, qy = Q.Value.Y; for (int i = 0; i < n; ++i) { points_in_new_coord_where_Q_center[i] = new Point(points_arr[i].X - qx, points_arr[i].Y - qy); } double [] phi_arr = new double[n]; for (int i = 0; i < n; ++i) { int x = points_in_new_coord_where_Q_center[i].X, y = points_in_new_coord_where_Q_center[i].Y; double r = Math.Sqrt(x * x + y * y); phi_arr[i] = Math.Asin(y) / r; } IEnumerable <Point> sort_enum_phi_arr; // Point [] sort_phi_arr = new Point[n]; sort_enum_phi_arr = points_in_new_coord_where_Q_center.OrderBy(p => acos((p.X) / Math.Sqrt(p.X * p.X + p.Y * p.Y), p)); sort_phi_arr = sort_enum_phi_arr.ToArray(); }
private void button2_Click(object sender, EventArgs e) // алгоритм Грехема { if (n < 2) { label1.Text = "Введіть більше точок"; return; } label1.Text = ""; if (!Q.HasValue) { label1.Text = "Задайте внутрішню точку (правою кнопкою миші)"; return; } //polar_sort // сортировка по полярному углу относительно точки Q Point[] points_in_new_coord_where_Q_center = new Point[n]; int qx = Q.Value.X, qy = Q.Value.Y; for (int i = 0; i < n; ++i) { points_in_new_coord_where_Q_center[i] = new Point(points_arr[i].X - qx, points_arr[i].Y - qy); } double[] phi_arr = new double[n]; for (int i = 0; i < n; ++i) { int x = points_in_new_coord_where_Q_center[i].X, y = points_in_new_coord_where_Q_center[i].Y; double r = Math.Sqrt(x * x + y * y); phi_arr[i] = Math.Asin(y) / r; } IEnumerable <Point> sort_enum_phi_arr; // Point[] sort_phi_arr = new Point[n]; sort_enum_phi_arr = points_in_new_coord_where_Q_center.OrderBy(p => acos((p.X) / Math.Sqrt(p.X * p.X + p.Y * p.Y), p)); sort_phi_arr = sort_enum_phi_arr.ToArray(); // end_polar_sort Point[] sort_points_arr = new Point[n]; for (int i = 0; i < n; ++i) { sort_points_arr[i] = new Point(sort_phi_arr[i].X + qx, sort_phi_arr[i].Y + qy); } bool[] is_ob = new bool[n]; is_ob.Initialize(); is_ob[0] = true; is_ob[1] = true; bool for_exit = false; for (int i = 2; i < n; ++i) { is_ob[i] = true; for (int j = i - 1; j > 0; --j) { if (is_ob[j]) { for (int k = j - 1; k >= 0; --k) { if (is_ob[k]) { for_exit = false; if (point_is_left_AB(sort_points_arr[k], sort_points_arr[i], sort_points_arr[j])) { is_ob[j] = false; for_exit = false; } else { for_exit = true; } break; } } if (for_exit) { break; } } } } //для последней точки (замыкающей) int last_in_ob = 0; for (int i = n - 2; i > 0; --i) { if (is_ob[i]) { if (point_is_left_AB(sort_points_arr[i], sort_points_arr[0], sort_points_arr[n - 1])) { is_ob[n - 1] = false; } last_in_ob = i; break; } } for (int i = 1; i < n; ++i) { { if (is_ob[i]) { if (point_is_left_AB(sort_points_arr[last_in_ob], sort_points_arr[i], sort_points_arr[0])) { is_ob[0] = false; } } break; } } Draw(); Gl.glColor3d(0, 0, 1); Gl.glPolygonMode(Gl.GL_FRONT_AND_BACK, Gl.GL_LINE); Gl.glBegin(Gl.GL_POLYGON); for (int i = 0; i < n; ++i) { if (is_ob[i]) { Gl.glVertex2d(sort_points_arr[i].X, sort_points_arr[i].Y); } } Gl.glEnd(); for (int i = 0; i < n; ++i) { Gl.glRasterPos2d(sort_phi_arr[i].X + qx, sort_phi_arr[i].Y + qy); string text = (i + 1).ToString(); // в цикле foreach перебираем значения из массива text, // который содержит значение строки для визуализации foreach (char char_for_draw in text) { // визуализируем символ c, с помощью функции glutBitmapCharacter, используя шрифт GLUT_BITMAP_9_BY_15. Glut.glutBitmapCharacter(Glut.GLUT_BITMAP_9_BY_15, char_for_draw); } } Gl.glFlush(); AnT.Invalidate(); }
private void Ендрю_Джавірса_Click(object sender, EventArgs e) { if (n < 2) { label1.Text = "Введіть більше точок"; return; } label1.Text = ""; Point[] x_arr = new Point[n]; IEnumerable <Point> x_sort_enum; Point[] x_sort; for (int i = 0; i < n; ++i) { x_arr[i] = new Point(points_arr[i].X, points_arr[i].Y); } x_sort_enum = x_arr.OrderBy(p => p.X); x_sort = x_sort_enum.ToArray(); Point left = new Point(x_sort[0].X, x_sort[0].Y); Point right = new Point(x_sort[n - 1].X, x_sort[n - 1].Y); int n_up = 0, n_down = 0; Point[] up = new Point[n]; Point[] down = new Point[n]; int iup = 0, idown = 0; up[iup++] = new Point(left.X, left.Y); down[idown++] = new Point(left.X, left.Y); // верхний и нижний массивы foreach (Point p in x_sort) { if (point_is_left_AB(left, right, p)) { up[iup++] = new Point(p.X, p.Y); } else if (point_is_right_AB(left, right, p)) { down[idown++] = new Point(p.X, p.Y); } } up[iup++] = new Point(right.X, right.Y); down[idown++] = new Point(right.X, right.Y); bool[] in_ob_up = new bool[iup]; bool[] in_ob_down = new bool[idown]; in_ob_up.Initialize(); in_ob_down.Initialize(); in_ob_up[0] = true; in_ob_up[iup - 1] = true; in_ob_down[0] = true; in_ob_down[idown - 1] = true; // обработка верхнего for (int i = 0; i < iup - 1;) { int index_of_max_angle = index_max_angle_up(iup, up, i); in_ob_up[index_of_max_angle] = true; i = index_of_max_angle; } //обработка нижнего массива for (int i = 0; i < idown - 1;) { int index_of_max_angle = index_max_angle_down(idown, down, i); in_ob_down[index_of_max_angle] = true; i = index_of_max_angle; } // рисуем Draw(); Gl.glPolygonMode(Gl.GL_FRONT_AND_BACK, Gl.GL_LINE); Gl.glBegin(Gl.GL_POLYGON); Gl.glColor3d(1, 0, 0); for (int i = 0; i < iup; ++i) { if (in_ob_up[i]) { Gl.glVertex2d(up[i].X, up[i].Y); } } Gl.glColor3d(0, 0, 1); for (int i = idown - 1; i >= 0; --i) { if (in_ob_down[i]) { Gl.glVertex2d(down[i].X, down[i].Y); } } Gl.glEnd(); AnT.Invalidate(); Gl.glFlush(); return; }