Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.92/117: Рейтинг темы: голосов - 117, средняя оценка - 4.92
0 / 0 / 0
Регистрация: 29.12.2010
Сообщений: 7
1

Написать свой алгоритм рисования кривых Безье

29.12.2010, 21:19. Показов 23648. Ответов 6
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Доброго времени суток. Ребят появилось задание написать по комп графике реализацию рисования Кривых Безье. Класс с нуля, без использования встроенных функций. Нашел алгоритм для 4ех точек, но что то никак не появляется форма с моей функцией. Мои предположения что плохо связана графика с алгоритмом. Уже 3ий час сижу все никак. Может кто подскажет в чем проблема и как её можно решить. Надо до завтра решить вопрос т.к. зачет на носу уже. Заранее спасибо.

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
namespace WindowsFormsApplication5
{
    public partial class Form1 : Form
    {
        private Pen pen = new Pen(Color.Black);
        private Graphics g;
 
        public Form1()
        {
            InitializeComponent();
            Image im = new Bitmap(pictureBox1.Width, pictureBox1.Height);
            g = Graphics.FromImage(im);
            g.Clear(Color.White);
            DrawBeze(new Point(320, 250), new Point(100, 200), new Point(300, 120), new Point(85, 63), g, pen);
            g.Dispose();
        }
        *******public static void DrawBeze(Point A,Point B,Point C, Point D,Graphics g,Pen p)
 *******{
            float Q1, Q2, Q3, Q4, T, T1, Step;
            int M, QX, QY;
 **************if (Math.Abs(D.X - A.X) > Math.Abs(D.Y - A.Y))
 **************{
 ******************M = D.X - A.X;
 **************}
 **************else
 ******************M = D.Y - A.Y;
 **************Step = 1 / M;
 **************T = 0;
 ***********while (T < 1)
 ***************{
                    T = T + Step;
                if (T > 1){
 *******************T = 1;
 *******************T1 = 0;}
                else 
 *******************T1 = 1 - T;
 ***************Q1 = T1 * T1 * T1;
 ***************Q2 = 3 * T1 * T1 * T;
 ***************Q3 = 3 * T1 * T ** T;
 ***************Q4 = ****T ** T ** T;
 ***************QX = (int)(Q1 * A.X + Q2 * B.X + Q3 * C.X + Q4 * D.X);
                QY = (int)(Q1 * A.Y + Q2 * B.Y + Q3 * C.Y + Q4 * D.Y);
                g.DrawRectangle(p,10,10,2,2);
 ***********}
 **************
 
 *******}
    }
}
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
29.12.2010, 21:19
Ответы с готовыми решениями:

Нарисовать астроиду из кривых Безье
Здравствуйте, помогите, пожалуйста, реализовать рисование астроиды из кривых Безье 2-ой степени.

Плавность рисования отдельных кривых Безье на основании перемещения соединяющей точки
Всем доброго времени суток:). Суть проблемы состоит в следующем: 1. У меня есть приложение на Qt...

Рисование кривых Безье
На одном сайте нашла статью, как чертить линии. На другом класс, который может создавать кривую...

Сравнить множество кривых Безье
Тут много писанины, что бы понятно было &quot;откуда ноги растут&quot;, ее смело можно пропустить истинным...

6
826 / 717 / 110
Регистрация: 06.10.2010
Сообщений: 825
Записей в блоге: 1
29.12.2010, 23:17 2
Цитата Сообщение от GProof Посмотреть сообщение
g.DrawRectangle(p,10,10,2,2);
Ты в итоге всегда один и тот же прямоугольник рисуешь
0
6280 / 3565 / 898
Регистрация: 28.10.2010
Сообщений: 5,926
30.12.2010, 00:24 3
а почему не воспользоваться тем что уже есть graphics.DrawBezier()
0
0 / 0 / 0
Регистрация: 29.12.2010
Сообщений: 7
30.12.2010, 01:00  [ТС] 4
Цитата Сообщение от Unril Посмотреть сообщение
Ты в итоге всегда один и тот же прямоугольник рисуешь
прекрасно знаю. это я уже пробовал просто использовать без полученных точек. на самом деле там так
C#
1
g.DrawRectangle(p,QX,QY,1,1);
Добавлено через 55 секунд
Цитата Сообщение от Петррр Посмотреть сообщение
а почему не воспользоваться тем что уже есть graphics.DrawBezier()
уже пользовался. преподаватель посмотрел неодобряюще. суть в том что надо написать с нуля.
0
826 / 717 / 110
Регистрация: 06.10.2010
Сообщений: 825
Записей в блоге: 1
30.12.2010, 19:02 5
Лучший ответ Сообщение было отмечено как решение

Решение

Класс кривой:
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
using System;
using System.Drawing;
 
namespace WindowsFormsApplicationTest2
{
    /// <summary>
    /// Кривоая безье
    /// </summary>
    public class BezierCurve
    {
        /// <summary>
        /// Количество точек для отрисовки.
        /// </summary>
        private const int N = 40;
 
        /// <summary>
        /// Опорные точки.
        /// </summary>
        private PointF[] dataPoints;
 
        /// <summary>
        /// Создание кривой безье
        /// </summary>
        /// <param name="points">Опроные точки</param>
        public BezierCurve(PointF[] points)
        {
            if (points.Length != 4)
            {
                throw new ArgumentOutOfRangeException();
            }
            dataPoints = points;
            Invalidate();
        }
 
        /// <summary>
        /// Точки для отрисовки
        /// </summary>
        public PointF[] DrawingPoints { get; private set; }
 
        /// <summary>
        /// Опорные точки
        /// </summary>
        public PointF[] DataPoints
        {
            get { return dataPoints; }
            set
            {
                if (value.Length != 4)
                {
                    throw new ArgumentOutOfRangeException();
                }
                dataPoints = value;
                Invalidate();
            }
        }
 
        /// <summary>
        /// Опорная точка
        /// </summary>
        /// <param name="i">Индекс опорной точки</param>
        public PointF this[int i]
        {
            get { return dataPoints[i]; }
            set
            {
                dataPoints[i] = value;
                Invalidate();
            }
        }
 
        /// <summary>
        /// Обновить точки для отрисовки.
        /// </summary>
        public void Invalidate()
        {
            DrawingPoints = new PointF[N + 1];
            float dt = 1f / N;
            float t = 0f;
            for (int i = 0; i <= N; i++)
            {
                DrawingPoints[i] = B(t);
                t += dt;
            }
        }
 
        /// <summary>
        /// Функция кривой
        /// </summary>
        /// <param name="t">Параметр. Может изменяться от 0 до 1</param>
        /// <returns>Точка кирвой</returns>
        private PointF B(float t)
        {
            float c0 = (1 - t) * (1 - t) * (1 - t);
            float c1 = (1 - t) * (1 - t) * 3 * t;
            float c2 = (1 - t) * t * 3 * t;
            float c3 = t * t * t;
            float x = c0 * dataPoints[0].X + c1 * dataPoints[1].X + c2 * dataPoints[2].X + c3 * dataPoints[3].X;
            float y = c0 * dataPoints[0].Y + c1 * dataPoints[1].Y + c2 * dataPoints[2].Y + c3 * dataPoints[3].Y;
            return new PointF(x, y);
        }
 
        /// <summary>
        /// Отрисовка кривой.
        /// </summary>
        /// <param name="g">График для отрисовки</param>
        public void Draw(Graphics g)
        {
            Pen pen = new Pen(Color.Black, 2f);
            g.DrawLines(pen, DrawingPoints);
        }
    }
}
Класс управляющих маркеров:
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
using System;
using System.Drawing;
using System.Windows.Forms;
 
namespace WindowsFormsApplicationTest2
{
    /// <summary>
    /// Управляющий маркер
    /// </summary>
    public class Marker
    {
        /// <summary>
        /// Радиус маркера
        /// </summary>
        private const int Radius = 10;
 
        /// <summary>
        /// Флаг, определяющий начало перетаскивания
        /// </summary>
        private bool drag;
 
        /// <summary>
        /// Ограничивающий прямоугольник
        /// </summary>
        private RectangleF rectangle;
 
        /// <summary>
        /// Создание нового маркера
        /// </summary>
        /// <param name="x">Координата X</param>
        /// <param name="y">Координата Y</param>
        public Marker(int x, int y)
        {
            rectangle = new RectangleF(x - Radius / 2f, y - Radius / 2f, Radius, Radius);
        }
 
        /// <summary>
        /// Событие, возникающее при перетаскивании
        /// </summary>
        public Action<PointF> OnDrag { get; set; }
 
        /// <summary>
        /// Собитие, возникающее при нажании на маркер
        /// </summary>
        public Action<PointF> OnMouseDown { get; set; }
 
        /// <summary>
        /// Положение маркера
        /// </summary>
        public PointF Location
        {
            get { return new PointF(rectangle.X + Radius / 2f, rectangle.Y + Radius / 2f); }
        }
 
        /// <summary>
        /// Отрисовка маркера
        /// </summary>
        /// <param name="g">График для отрисовки</param>
        public void Draw(Graphics g)
        {
            g.FillEllipse(Brushes.Black, rectangle);
        }
 
        /// <summary>
        /// Необходимо вызывать при нажатии мыши
        /// </summary>
        public void MouseDown(MouseEventArgs e)
        {
            if (rectangle.Contains(e.Location))
            {
                drag = true;
                if (OnMouseDown != null)
                {
                    OnMouseDown(e.Location);
                }
            }
        }
 
        /// <summary>
        /// Необходмио вызывать при отпускании мыши
        /// </summary>
        public void MouseUp()
        {
            drag = false;
        }
 
        /// <summary>
        /// Необходмо вызывать при передвижении мыши
        /// </summary>
        public void MouseMove(MouseEventArgs e)
        {
            if (drag)
            {
                rectangle.X = e.X - Radius / 2f;
                rectangle.Y = e.Y - Radius / 2f;
                if (OnDrag != null)
                {
                    OnDrag(e.Location);
                }
            }
        }
    }
}
Класс формы:
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
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
 
namespace WindowsFormsApplicationTest2
{
    public partial class Form1 : Form
    {
        readonly BezierCurve bezier;
        readonly Marker[] markers = new Marker[4];
 
        public Form1()
        {
            InitializeComponent();
            markers[0] = new Marker(100, 200);
            markers[1] = new Marker(150, 250);
            markers[2] = new Marker(200, 150);
            markers[3] = new Marker(250, 200);
            for (int index = 0; index < markers.Length; index++)
            {
                Marker marker = markers[index];
                int i = index;
                marker.OnDrag += f =>
                {
                    bezier[i] = f;
                    pictureBox.Invalidate();
                };
                marker.OnMouseDown += f => { Cursor = Cursors.Hand; };
            }
 
            bezier = new BezierCurve(markers.Select(m => m.Location).ToArray());
        }
 
        private void pictureBox_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
            Pen pen = new Pen(Color.Gray, 1f);
            e.Graphics.DrawLines(pen, markers.Select(m=>m.Location).ToArray());
            foreach (Marker marker in markers)
            {
               marker.Draw(e.Graphics);
            }
            bezier.Draw(e.Graphics);
        }
 
        private void pictureBox_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                foreach (Marker marker in markers)
                {
                    marker.MouseMove(e);
                    Thread.Sleep(0);
                }
            }
        }
 
        private void pictureBox_MouseDown(object sender, MouseEventArgs e)
        {
            foreach (Marker marker in markers)
            {
                marker.MouseDown(e);
            }
        }
 
        private void pictureBox_MouseUp(object sender, MouseEventArgs e)
        {
            foreach (Marker marker in markers)
            {
                marker.MouseUp();
            }
            Cursor = Cursors.Arrow;
        }
    }
}
Как выглядит:
Написать свой алгоритм рисования кривых Безье

Сама программа:
WindowsFormsApplicationTest2.zip
10
0 / 0 / 0
Регистрация: 29.12.2010
Сообщений: 7
30.12.2010, 21:14  [ТС] 6
Unril, спасибо большое очень помог мне. вот это я понимаю кривые безье.
0
0 / 0 / 0
Регистрация: 28.01.2014
Сообщений: 19
28.05.2015, 02:59 7
Как сделать так, чтобы самому выбирать начальные 4 точки.
0
28.05.2015, 02:59
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
28.05.2015, 02:59
Помогаю со студенческими работами здесь

Отрисовка кривых Безье OpenGL(C++)
Здравствуйте!!! Помогите пожалуйста нубу - необходимо нарисовать кривые Безье, но с инструментарием...

Рисование линий и кривых Безье, 2D-фигур
Интересует вопрос, как отрисовать в Unity прямую/кривую линию заданных толщины и цвета, а также...

Объединение кривых Безье (нахождение контрольных точек)
Здравствуйте, нужна помощь в восстановлении кубической кривой Безье. Суть проблемы: изначально...

Залить фигуру, нарисованную с помощью кривых Безье
Здравствуйте. С помощью кривых Безье я нарисовал замкнутую фигуру (цветок). Теперь его нужно залить...


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru