Форум программистов, компьютерный форум, киберфорум
C# Windows Forms
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
0 / 0 / 0
Регистрация: 16.11.2017
Сообщений: 7

Нарисовать ровный многоугольник (n граней) в прямоугольнике (не круге и не квадрате)

16.11.2017, 17:54. Показов 1274. Ответов 4
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Приветствую!

Мне необходимо рисовать разные многоугольники в прямоугольниках (см. пример)

Алгоритм как рисовать правильные многоугольники в круге я нашел, а вот как тоже самое сделать в прямоугольнике с разной шириной и высотой, чтобы например треугольник вытянулся, не знаю.

Вот пример кода формы для рисования правильных многоугольников в круге.

Кликните здесь для просмотра всего текста
C#
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
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
 
namespace ThisProject
{
    public partial class F_TEST : Form
    {
        public F_TEST()
        {
            InitializeComponent();
        }
 
        private void F_TEST_Load(object sender, EventArgs e) { }
 
        protected override void OnPaint(PaintEventArgs e)
        {
            lbl_1.Text = trackBar_1.Value.ToString();
            lbl_2.Text = trackBar_2.Value.ToString();
            DrawRegularPolygon(e.Graphics, trackBar_1.Value, 100, 360 - trackBar_2.Value, new Point(this.ClientSize.Width / 2, this.ClientSize.Height / 2));
        }
 
        private void DrawRegularPolygon(Graphics G, int sides, int radius, int startingAngle, Point center)
        {
            //Точки будущей фигуры
            List<Point> points = new List<Point>();
            //Градусы между точками
            float step = 360.0f / sides;
 
            for (double i = startingAngle; i < startingAngle + 360.0; i += step)
            {
                //Находим новую точку
                Point CurentPoint = new Point();
                CurentPoint.X = (int)(Math.Cos(i * Math.PI / 180.0) * radius + center.X);
                CurentPoint.Y = (int)(Math.Sin(-(i * Math.PI / 180.0)) * radius + center.Y);
                points.Add(CurentPoint);
            }
 
            G.SmoothingMode = SmoothingMode.HighQuality;
            //Рисуем фигуру (полигон)
            G.DrawPolygon(Pens.Blue, points.ToArray());
            //Рисуем круг
            G.DrawEllipse(Pens.Red, center.X - radius - 1, center.Y - radius - 1, 2 * radius + 2, 2 * radius + 2);
        }
 
        private void trackBar_Scroll(object sender, EventArgs e)
        {
            this.Refresh();
        }
    }
}


Результат работы кода можно посмотреть на скриншоте.

Нужно тоже самое, но при этом чтобы можно было задать размер прямоугольника и очень важно, чтобы у получившейся фигуры нижняя грань была строго горизонтальна (в моем примере можно крутить фигуру и тем самым для разных фигур я могу выставлять начальные градусы поворота)

Как вариант использовать алгоритм выше и растягивать до нужного размера, но мне кажется такой подход неправильным...
Миниатюры
Нарисовать ровный многоугольник (n граней) в прямоугольнике (не круге и не квадрате)   Нарисовать ровный многоугольник (n граней) в прямоугольнике (не круге и не квадрате)  
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
16.11.2017, 17:54
Ответы с готовыми решениями:

Нарисовать квадрат в квадрате, в квадрате и так далее
Прошу помощи, мне подкинули задачку. Необходимо вывести на экран вот это: * * * * * * * * * * * * * * * * * *...

Создать приложение, в котором на форме автоматически прорисовываются точки в прямоугольнике и в круге
Должно получиться что-то типа такого

Определить, поместится ли круг в квадрате и квадрат в круге
Известны площадь круга и квадрата . Определить а) уместиться ли круг в квадрате б) уместиться ли квадрат в круге

4
 Аватар для ViterAlex
8951 / 4863 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
16.11.2017, 19:07
Рисуешь как будто в квадрате, но для Graphics задаёшь ScaleTransform. Можно использовать Matrix для преобразования над точками и рисовать без масштабирования.
1
0 / 0 / 0
Регистрация: 16.11.2017
Сообщений: 7
17.11.2017, 00:08  [ТС]
Цитата Сообщение от ViterAlex Посмотреть сообщение
Рисуешь как будто в квадрате, но для Graphics задаёшь ScaleTransform. Можно использовать Matrix для преобразования над точками и рисовать без масштабирования.
Спасибо! Выбрал использование Matrix для того, чтобы качество не терять, вот готовый класс для работы, если вдруг кому понадобится:
C#
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
    public class Polygon
    {
        private enTypePolygon _Type;
 
        public enum enTypePolygon : int
        {
            triangle = 3,
            square = 4,
            pentagon = 5,
            hexagon = 6
        }
        
        public Polygon(enTypePolygon type)
        {
            _Type = type;
        }
 
        public Polygon(int countPoints)
        {
            if (countPoints < 3) countPoints = 3;
            if (countPoints > 6) countPoints = 6;
            _Type = (enTypePolygon)countPoints;
        }
 
        public Polygon()
        {
            _Type = enTypePolygon.triangle;
        }
 
        public void Draw(Graphics g, RectangleF rect, bool scale)
        {
            Draw(g, rect, 0, scale);
        }
 
        public void Draw(Graphics g, RectangleF rect, float angle)
        {
            Draw(g, rect, angle, false);
        }
 
        public void Draw(Graphics g, RectangleF rect)
        {
            Draw(g, rect, 0, false);
        }
 
        public void Draw(Graphics g, RectangleF rect, float angle, bool scale)
        {
            RectangleF Rectangle = new RectangleF();
            GraphicsPath Path = new GraphicsPath();
            Point CurentPoint;
            float MinSize = rect.Width < rect.Height ? rect.Width : rect.Height;
            float Radius = (MinSize / 2);
            PointF PointCenter = new PointF(rect.X + rect.Width / 2, rect.Y + rect.Height / 2);
            float Step = 360.0f / (int)_Type;
 
            List<Point> Points = new List<Point>();
            for (double i = angle; i < angle + 360.0; i += Step)
            {
                CurentPoint = new Point();
                CurentPoint.X = (int)(Math.Cos(i * Math.PI / 180.0) * Radius + PointCenter.X);
                CurentPoint.Y = (int)(Math.Sin(-(i * Math.PI / 180.0)) * Radius + PointCenter.Y);
                Points.Add(CurentPoint);
            }
 
            Rectangle.X = Points.Min(ii => ii.X);
            Rectangle.Y = Points.Min(ii => ii.Y);
            Rectangle.Width = Points.Max(ii => ii.X) - Rectangle.X;
            Rectangle.Height = Points.Max(ii => ii.Y) - Rectangle.Y;
 
            g.SmoothingMode = SmoothingMode.HighQuality;
 
            Path.AddPolygon(Points.ToArray());
 
            if (scale == true)
                Path.Transform(new Matrix(Rectangle, GetPointsRectangleForMatrix(rect)));
 
            g.DrawPath(Pens.Blue, Path);
 
            //For test
            //g.DrawRectangle(Pens.Red, rect.X - 1, rect.Y - 1, rect.Width + 2, rect.Height + 2);
            //g.DrawRectangle(Pens.Red, Rectangle.X - 1, Rectangle.Y - 1, Rectangle.Width + 2, Rectangle.Height + 2);
            //g.DrawEllipse(Pens.DarkGreen, PointCenter.X - MinSize / 2 - 1, PointCenter.Y - MinSize / 2 - 1, MinSize + 2, MinSize + 2);
        }
 
        private PointF[] GetPointsRectangleForMatrix(RectangleF rect)
        {
            PointF[] Points = new PointF[3];
            Points[0] = new PointF(rect.X, rect.Y);
            Points[1] = new PointF(rect.X + rect.Width, rect.Y);
            Points[2] = new PointF(rect.X, rect.Y + rect.Height);
            return Points;
        }
    }
}
Миниатюры
Нарисовать ровный многоугольник (n граней) в прямоугольнике (не круге и не квадрате)   Нарисовать ровный многоугольник (n граней) в прямоугольнике (не круге и не квадрате)  
0
 Аватар для ViterAlex
8951 / 4863 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
17.11.2017, 09:18
GrapgicsPath тут совсем не обязателен. Преобразование нужно производить над массивом точек методом TransformPoints. И не нужно забывать, что Matrix реализует IDisposable.
0
0 / 0 / 0
Регистрация: 16.11.2017
Сообщений: 7
17.11.2017, 11:12  [ТС]
Цитата Сообщение от ViterAlex Посмотреть сообщение
GrapgicsPath тут совсем не обязателен. Преобразование нужно производить над массивом точек методом TransformPoints. И не нужно забывать, что Matrix реализует IDisposable.
Окей, вот переработанный вариант =)

Теперь можно задать вариант масштабирования, Pen и установить флаг "Горизонтально", тогда автоматом поставится угол, чтобы нижняя граница фигуры была горизонтальна.

C#
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
    public class Polygon
    {
        public enTypePolygon Type { get; set; }
        public RectangleF Rectangle { get; set; }
        public float Angle { get; set; }
        public enScale Scale { get; set; }
        public bool Horizontally { get; set; }
        public Pen Pen { get; set; }
 
        public enum enTypePolygon : int
        {
            triangle = 3,
            square = 4,
            pentagon = 5,
            hexagon = 6
        }
 
        public enum enScale : int
        {
            none = 0, //не масштабировать
            filling = 1, //заполнять
            scaling = 2 //масштабировать (вписать)
        }
 
        public Polygon(enTypePolygon type, Pen pen, RectangleF rect, float angle, enScale scale)
        {
            Type = type;
            Pen = pen;
            Rectangle = rect;
            Angle = angle;
            Scale = scale;
        }
 
        public Polygon(int countPoints, Pen pen, RectangleF rect, float angle, enScale scale)
        {
            if (countPoints < 3) countPoints = 3;
            if (countPoints > 6) countPoints = 6;
            Type = (enTypePolygon)countPoints;
            Pen = pen;
            Rectangle = rect;
            Angle = angle;
            Scale = scale;
        }
 
        public Polygon()
        {
            Type = enTypePolygon.triangle;
            Pen = Pens.Black;
            Rectangle = new RectangleF(0f, 0f, 50f, 50f);
            Angle = 0;
            Scale = enScale.none;
        }
 
        public void Draw(Graphics g)
        {
            RectangleF polygonRectangle = new RectangleF();
            RectangleF newRectangle = new RectangleF();
            PointF pointCenter = new PointF(Rectangle.X + Rectangle.Width / 2, Rectangle.Y + Rectangle.Height / 2);
            float minSize = Rectangle.Width < Rectangle.Height ? Rectangle.Width : Rectangle.Height;
            float radius = (minSize / 2);
            int countStep = (int)Type;
            float step = 360.0f / countStep;
            float curentStep = 0;
            float IndexSize;
 
            if (Horizontally == true)
            {
                switch (Type)
                {
                    case enTypePolygon.triangle:
                        curentStep = 90;
                        break;
                    case enTypePolygon.square:
                        curentStep = 45;
                        break;
                    case enTypePolygon.pentagon:
                        curentStep = 18;
                        break;
                    case enTypePolygon.hexagon:
                        curentStep = 0;
                        break;
                }
            }
            else
                curentStep = Angle;
 
            //Определяем точки будущей фигуры
            PointF[] Points = new PointF[countStep];
            for (int i = 0; i < countStep; i++)
            {
                Points[i] = new PointF();
                Points[i].X = (int)(Math.Cos(curentStep * Math.PI / 180.0) * radius + pointCenter.X);
                Points[i].Y = (int)(Math.Sin(-(curentStep * Math.PI / 180.0)) * radius + pointCenter.Y);
                curentStep += step;
            }
 
            //Определяем область в которой находится фигура
            polygonRectangle.X = Points.Min(ii => ii.X);
            polygonRectangle.Y = Points.Min(ii => ii.Y);
            polygonRectangle.Width = Points.Max(ii => ii.X) - polygonRectangle.X;
            polygonRectangle.Height = Points.Max(ii => ii.Y) - polygonRectangle.Y;
 
            //Настройка качества Graphics
            g.SmoothingMode = SmoothingMode.HighQuality;
 
            //Маштабирование
            switch (Scale)
            {
                case enScale.scaling: //с сохранением пропорций
                    IndexSize = (new float[] { ((float)Rectangle.Width / (float)polygonRectangle.Width), ((float)Rectangle.Height / (float)polygonRectangle.Height) }).Min();
                    newRectangle.Width = polygonRectangle.Width * IndexSize;
                    newRectangle.Height = polygonRectangle.Height * IndexSize;
 
                    newRectangle.X = pointCenter.X - newRectangle.Width / 2;
                    newRectangle.Y = pointCenter.Y - newRectangle.Height / 2;
 
                    using (Matrix Matrix = new Matrix(polygonRectangle, GetPointsRectangleForMatrix(newRectangle)))
                    {
                        Matrix.TransformPoints(Points);
                    }
 
                    polygonRectangle = newRectangle;
                    break;
                case enScale.filling: //с заполнением
                    using (Matrix Matrix = new Matrix(polygonRectangle, GetPointsRectangleForMatrix(Rectangle)))
                    {
                        Matrix.TransformPoints(Points);
                    }
                    polygonRectangle = Rectangle;
                    break;
            }
 
            //Отрисовка фигуры
            g.DrawPolygon(Pen, Points);
 
            //Для теста
            g.DrawRectangle(Pens.Black, Rectangle.X - 2, Rectangle.Y - 2, Rectangle.Width + 4, Rectangle.Height + 4);
            g.DrawRectangle(Pens.Red, polygonRectangle.X - 1, polygonRectangle.Y - 1, polygonRectangle.Width + 2, polygonRectangle.Height + 2);
            g.DrawEllipse(Pens.DarkGreen, pointCenter.X - minSize / 2 - 1, pointCenter.Y - minSize / 2 - 1, minSize + 2, minSize + 2);
        }
 
        private PointF[] GetPointsRectangleForMatrix(RectangleF rect)
        {
            PointF[] Points = new PointF[3];
            Points[0] = new PointF(rect.X, rect.Y);
            Points[1] = new PointF(rect.X + rect.Width, rect.Y);
            Points[2] = new PointF(rect.X, rect.Y + rect.Height);
            return Points;
        }
 
        public void Dispoze()
        {
            Pen?.Dispose();
        }
    }
Миниатюры
Нарисовать ровный многоугольник (n граней) в прямоугольнике (не круге и не квадрате)   Нарисовать ровный многоугольник (n граней) в прямоугольнике (не круге и не квадрате)   Нарисовать ровный многоугольник (n граней) в прямоугольнике (не круге и не квадрате)  

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
17.11.2017, 11:12
Помогаю со студенческими работами здесь

Определить, находится ли точка одновременно и в круге, и в квадрате или вне их
На плоскости заданы точка, круг радиуса R с центром в начале координат и вписанный в него квадрат, со сторонами, параллельными осям...

Известны площади круга и квадрата Уместится ли круг в квадрате или квадрат в круге?
2)Известны площади круга и квадрата. Определить: а) уместится ли круг в квадрат; б) уместится ли квадрат в круге.

Известны площади круга и квадрата. Определить: а)местится ли круг в квадрате б)уместится ли квадрат в круге
Известны площади круга и квадрата. Определить: а)местится ли круг в квадрате б)уместится ли квадрат в круге /* Заданы площади круга...

Как можно нарисовать ровный круг в консоли?
Всем привет! Делаю проект на 1 курсе. Для начала нужно понять, как нарисовать в консоли круг или эллипс. Из символов как-то неуклюже...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Новые блоги и статьи
Установка Emscripten SDK (emsdk) и CMake на Windows для сборки C и C++ приложений в WebAssembly (Wasm)
8Observer8 30.01.2026
Чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. Система контроля версиями Git. . .
Подключение Box2D v3 к SDL3 для Android: физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
Влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru