Рисование сплайнами и кривыми Безье Постановка задачи. Требуется рисовать объекты 2d-графики, используя плавные кривые.
Обсуждение. В примере с корабликом мы уже рисовали окружности и сектора, хотя очевидно они не исчерпывают все необходимые нам графические объекты. В этом примере мы продемонстрируем другие варианты решения этой задачи. Ключевыми понятиями будут сплайн и кривая Безье.
Подготовительныедействия:
На форме размером 900х400 поместим надпись (label1) «Упругость сплайна» и окно для ввода textBox1. Создадим меню с кнопками : «Выбор кривой» и «Очистка экрана». Задайте семь типов кривой (подменю «Выбор кривой»):
1) Незамкнутая ломаная,
2) Замкнутая ломаная,
3) Незамкнутый сплайн,
4) Замкнутый сплайн,
5) Одна кривая Безье,
6) Незамкнутая кривая Безье,
7) Замкнутая кривая Безье.
Начнем постепенно с ними разбираться. Нам понадобятся объекты классов Graphics, SolidBrush, Pen, Point и Random. Каждой позиции меню зададим соответствующие обработчики событий, например, для незамкнутой ломаной будет задан метод незамкнутаяЛоманаяToolStripMenuItem_Click(), а для очистки экрана — метод
очисткаЭкранаToolStripMenuItem_Click(). Добавим два метода класса Form1:
privatePoint[] star5(intx, inty, intr), возвращающий массив 10 точек «Звезды», и
publicColorRandomColor() Будем использовать свойства холста g: SmoothingMode и FillMode, добавленные в библиотеке System.Drawing.Drawing2D; а также методы класса Graphics: FromHwnd(), Clear(), DrawLine(), DrawLines(), DrawCurve(), DrawCloseCurve(), DrawBezier(), DrawBeziers(), Fillellipse().
Немного теории
Линии, также как прямоугольники и эллипсы, являются графическими примитивами.
Для того, чтобы нарисовать отрезок прямой, надо указать координаты начала (Point start) и конца (Point end) отрезка, выбрать перо (pen) для рисования и применить метод объекта g.DrawLine(pen, start, end).
Для рисования незамкнутой ломаной, состоящей из отрезков, нужно задать массив последовательных точек Point[] pm и применить метод g.DrawLines(pen, pm). Если в качестве последней точки массива указать координаты первой точки, то контур станет замкнутым.
Для рисования кривых следует использовать методы DrawCurve() или DrawCloseCurve() для рисования сплайном, или же DrawBezier() и DrawBeziers() для рисования кривых Безье.
Справка
Сплайн (основной или фундаментальный сплайн, аналог лекала в черчении) — это последовательность отдельных кривых, объединенных в одну большую кривую. Сплайн задается массивом точек и параметром упругости. Сплайн обязательно проходит через заданные массивом pm точки на плоскости, а параметр упругости (elasticity — вещественное число типа float) определяет плавность их соединения. Если упругость = 0.0f (бесконечная физическая упругость), то соединение точек будет выполнено прямыми отрезками. Если упругость = 1.0f (отсутствие физической упругости), то кривая имеет наименьший суммарный изгиб. Если упругость > 1.0f, то кривая напоминает сдавленный берегами ручей, стремящийся увеличить изгиб своих излучин и течь по более длинному пути. Лучше всего исследовать влияние упругости, меняя ее и рисуя сплайн заново. Для вызова метода достаточно написать
g.DrawCurve(pen, pm, elasticity, FillMode.Alternate); — незамкнутый сплайн или
g.DrawClosedCurve(pen, pm, elasticity, FillMode.Alternate); — замкнутый сплайн.
Отличие второго метода от первого в том, что последняя точка массива добавляется от первой (eё можно не добавлять к массиву).