Кривая Безье и метод де Кастельжо



бет3/3
Дата26.01.2023
өлшемі353,79 Kb.
#63107
түріРешение
1   2   3
Байланысты:
Кривая Безье и метод де Кастельжо

Кривой Безье называется кривая, задаваемая полиномом 3 порядка: y=ax3+bx2+cx+d. То есть для ее определения нужно задать четыре параметра (a,b,c,d).
Кривые Безье используются очень часто в 2d- и 3d-графике. Они позволяют задавать любой тип соединений («сшивания») кривых, в этом они являются более универсальными, чем рассмотренные выше сплайны (для которых кроме заданных точек дополнительно вводится только один параметр — упругость).
Для полного определения кривой Безье, проходящей через начальную (start) и конечную (finish) точки необходимо задать еще две управляющие точки (control1 и control2), задающих касательные к этим точкам и радиусы кривизны.

Отдаляя управляющую точку control1 от точки start, мы увеличиваем радиус кривизны, смещая ее относительно точки start, мы изменяем направление касательной к кривой в точке start. Все это справедливо и для пары finish-control2.
Эти четыре точки полностью определяют коэффициенты (a,b,c,d) кривой Безье.  Полезно самостоятельно исследовать, как меняется форма кривой Безье при перемещении управляющих точек. Теперь это можно сделать в программе, описанной вышее «Кривая Безье и метод де Кастельжо».
Остальное понятно из комментариев в тексте программы (файл Form1.cs):
using System;
using System.Drawing;
using System.Drawing.Drawing2D; // добавлено
using System.Windows.Forms;
namespace сплайны_и_кривые_Безье
{
public partial class Form1 : Form
{
Graphics g;

public Form1()


{
InitializeComponent();
g = Graphics.FromHwnd(this.Handle); // холст
// сглаживание: enum SmoothingMode
g.SmoothingMode = SmoothingMode.AntiAlias;
}

private void очисткаЭкранаToolStripMenuItem_Click(object sender, EventArgs e)


{
g.Clear(BackColor);
}

private Point[] star5(int x, int y, int r) // звезда


{
Point point1 = new Point(x, y-6*r);
Point point2 = new Point(x+2*r, y-3*r);
Point point3 = new Point(x+6*r, y-2*r);
Point point4 = new Point(x+3*r, y+r);
Point point5 = new Point(x+4*r, y+5*r);
Point point6 = new Point(x, y+3*r);
Point point7 = new Point(x - 4 * r, y + 5 * r);
Point point8 = new Point(x - 3 * r, y + r);
Point point9 = new Point(x - 6 * r, y - 2 * r);
Point point10 = new Point(x - 2 * r, y - 3 * r);
Point[] pm =
{
point1,
point2,
point3,
point4,
point5,
point6,
point7,
point8,
point9,
point10
};
return pm;
}
private void незамкнутаяЛоманаяToolStripMenuItem_Click(object sender, EventArgs e)
{
Pen redPen = new Pen(Color.Red, 2f);
// Задание 10 точек, определяющих незамкнутую ломаную
Point[] pm = star5(200, 200, 25);
// Рисование незамкнутой ломаной из отрезков (Line)
g.DrawLines(redPen, pm); // для замыкания добавьте первую точку
}

private void замкнутаяЛоманаяToolStripMenuItem_Click(object sender, EventArgs e)


{
Pen greenPen = new Pen(Color.Green, 2f);
// Задание 10 точек, определяющих замкнутую область "звезда"
Point[] pm = star5(250, 220, 25);
// Рисование замкнутой ломаной из отрезков
g.DrawClosedCurve(greenPen, pm, 0f, FillMode.Winding);
// Упругость: 0f - беск.физ.упругость - прямыми;
}
private void сплайнToolStripMenuItem_Click(object sender, EventArgs e)
{
Pen pen = new Pen(RandomColor(), 2f);
// Задание точек, определяющих кривую
Point[] pm = star5(500, 200, 25);
float elasticity = Convert.ToSingle(textBox1.Text); // - упругость
// Рисование замкнутой кривой через 10 точек сплайном
// g.DrawClosedCurve(bluePen, pm, elasticity, FillMode.Alternate);
// Упругость: 0f - беск.физ.упругость - прямыми;
// 1f - отсутствие физ.упругости, наименьший суммарный изгиб
// >1 - сдавленный берегами ручей, стремящийся увеличить изгиб своих излучин и течь по более длинному пути.
g.DrawClosedCurve(pen, pm, elasticity, FillMode.Alternate);
}

private void незамкнутыйСплайнToolStripMenuItem_Click(object sender, EventArgs e)


{
Pen pen = new Pen(RandomColor(), 3f);
// Задание точек, определяющих кривую
Point[] pm = star5(400, 200, 25);
float elasticity = Convert.ToSingle(textBox1.Text);
// Рисование незамкнутой кривой через 10 точек сплайном
g.DrawCurve(pen, pm, elasticity);
}
public Color RandomColor()
{
int r, g, b;
byte[] bytes1 = new byte[3]; // массив 3 цветов
Random rnd1 = new Random();
rnd1.NextBytes(bytes1); // генерация в массив
r = Convert.ToInt16(bytes1[0]);
g = Convert.ToInt16(bytes1[1]);
b = Convert.ToInt16(bytes1[2]);
return Color.FromArgb(r, g, b); // возврат цвета
}

private void однаКриваяБезьеToolStripMenuItem_Click(object sender, EventArgs e)


{
// кривая Безье: 4 точки (x,y) - старт,
// управление1, управление2, end
Point start = new Point(500, 100);
Point control1 = new Point( 500, 300);
Point control2 = new Point( 700, 300 );
Point finish = new Point( 800, 100);
g.DrawBezier(new Pen(Color.Black, 3), start, control1, control2, finish); // это кривая Безье, дальше - для наглядности
SolidBrush br = new SolidBrush(Color.Green);
Pen pen = new Pen(Color.Green, 1);
g.FillEllipse(br, start.X-5, start.Y-5, 11, 11);
g.FillEllipse(br, control1.X - 5, control1.Y - 5, 11, 11);
g.FillEllipse(br, control2.X - 5, control2.Y - 5, 11, 11);
g.FillEllipse(br, finish.X - 5, finish.Y - 5, 11, 11);
g.DrawLine(pen, start, control1);
g.DrawLine(pen, finish, control2);
}

private void незамкнутаяКриваяБезьеToolStripMenuItem_Click(object sender, EventArgs e)


{
// Зададим точки для 2-х кривых Безье - всего 7.
Point start = new Point(500, 100);
Point control1 = new Point(750, 50);
Point control2 = new Point(510, 310);
Point end1 = new Point(500, 300);
Point control3 = new Point(490, 310);
Point control4 = new Point(240, 50);
Point end2 = new Point(490, 100);
Point[] bezierPoints =
{
start, control1, control2, end1, control3, control4, end2
};
// Рисуем
g.DrawBeziers(new Pen(Color.Red, 3), bezierPoints);
}

private void замкнутаяКриваяБезьеToolStripMenuItem_Click(object sender, EventArgs e)


{
// Зададим точки для 2-х кривых Безье - всего 7.
Point start = new Point(600, 150);
Point control1 = new Point(850, 100);
Point control2 = new Point(610, 360);
Point end1 = new Point(600, 350);
Point control3 = new Point(590, 360);
Point control4 = new Point(350, 100);
Point end2 = start; // первая и третья точки совпадают
Point[] bezierPoints =
{
start, control1, control2, end1, control3, control4, end2
};
// Рисуем
g.DrawBeziers(new Pen(Color.Orange, 4), bezierPoints);
}
}
}
Внешний вид формы при выборе другой позиции меню после рисования двух фигур (Незамкнутый сплайн и Замкнутая кривая Безье) выглядит так:

Если после очистки экрана  задать 1-4 пункты подменю «Выбор кривой», то мы увидим четыре сплайна типа «Звезда»:

Если после очистки экрана  задать 5-7 пункты подменю «Выбор кривой», то мы увидим 3 кривых Безье, где красный (незамкнутый) и желтый (замкнутый) контуры состоят всего из двух кривых Безье.


Достарыңызбен бөлісу:
1   2   3




©emirsaba.org 2024
әкімшілігінің қараңыз

    Басты бет