Главная страница

прнор. 8классGraphicsСоздание анимации (1). Графика на С#


Скачать 2.3 Mb.
НазваниеГрафика на С#
Анкорпрнор
Дата02.05.2023
Размер2.3 Mb.
Формат файлаppt
Имя файла8классGraphicsСоздание анимации (1).ppt
ТипДокументы
#1103159

Графика на С#


На примере графики наглядно видны преимущества ООП, смысл использования классов, их методов и свойств. Добавляя в пространство имен своего проекта соответствующие библиотеки, вы получаете сразу набор инструментов, необходимых для графики. Это графические примитивы (линии, прямоугольники, эллипсы и т.п.), перо для черчения, кисть для закраски  и много других полезных объектов и методов. Пространство имен System.Drawing (Рисование) обеспечивает доступ к функциональным возможностям графического интерфейса GDI+ , используя около 50 (!) классов, в том числе класс Graphics


Графические примитивы

Класс Graphics


Он инкапсулирует поверхность рисования GDI+. Этот класс не наследуется. Методов в этом классе огромное количество, поэтому сначала представим их в таблице, а затем рассмотрим некоторые из них с примерами и пояснениями.
Класс Graphics предоставляет методы рисования на устройстве отображения (другие термины — графический контекст, «холст»). Определимся сразу, на чем мы хотим рисовать. Далее в примерах он обозначается как объект g.

Способы задания «холста»


Графический объект — «холст» для рисования на форме Form1 (указатель this) можно задать, например,  одним оператором:
Graphics g = this.CreateGraphics();
Примечание. Заметим, что стандартным образом
Graphics g = new Graphics();
создать объект-холст не удается. На этом операторе генерируется ошибка:

Способы задания «холста»


Еще пример задания графического контекста на визуальном компоненте PictureBox (ящик для рисования) через растровый объект класса Bitmap.
В классе Form1 зададим два объекта: Graphics g;  //  графический объект — некий холст Bitmap buf;  //  буфер для Bitmap-изображения В конструктор Form1() добавим следующие операторы: buf = new Bitmap(pictureBox1.Width, pictureBox1.Height);
// с размерами g = Graphics.FromImage(buf);
// инициализация g

Способы задания «холста»


Eсли все графические операции выполняются внутри одной функции, можно использовать одну строку:
Graphics g = Graphics.FromImage(new Bitmap(pictureBox1.Width, pictureBox1.Height));
После этого можно задать фон холста белым:
g.Clear(Color.White);
Еще один пример задания «холста» на форме через дескриптор окна:
Graphics g = Graphics.FromHwnd(this.Handle);

Способы задания «холста»


Еще пример задания графического контекста на визуальном компоненте PictureBox (ящик для рисования) через растровый объект класса Bitmap.
В классе Form1 зададим два объекта: Graphics g;  //  графический объект — некий холст Bitmap buf;  //  буфер для Bitmap-изображения В конструктор Form1() добавим следующие операторы: buf = new Bitmap(pictureBox1.Width, pictureBox1.Height);
// с размерами g = Graphics.FromImage(buf);
// инициализация g

Способы задания «холста»


Одним из самых используемых является получение ссылки на объект Graphics через объект PaintEventArgs при обработке события Paint формы или элемента управления:


private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
// Далее вставляется код рисования
}

Методы класса Graphics


Имя метода


Описание (методы перегружены)


Clear(Color)


Очищает всю поверхность рисования и выполняет заливку поверхности указанным цветом фона.


Dispose()


Освобождает все ресурсы, используемые данным объектом Graphics.


DrawEllipse(Pen, Rectangle)


Рисует эллипс


DrawLine(Pen, Point, Point)


Проводит линию, соединяющую две структуры Point.


DrawRectangle(Pen, Rectangle)


Рисует прямоугольник, определяемый структурой Rectangle.


FillRectangle(Brush, Rectangle)


Заполняет внутреннюю часть прямоугольника, определяемого структурой Rectangle.


Начало системы координат находится в левом верхнем углу окна, внутренней области окна формы. Ось X в этой системе координат, принятой по умолчанию, направлена слева направо, а ось Y — сверху вниз.


Координаты точки


Точку возможно нарисовать в виде закрашенного квадрата с шириной стороны, равным 1 пикселу (или побольше). Эта задача выполняется при помощи метода FillRectangle:
g.FillRectangle(redBrush, e.X, e.Y, 1, 1);


private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
g.Clear(Color.Yellow);
g.FillRectangle(Brushes. Red, 80, 70, 4, 4);
}


Метод FillRectangle вызывается для объекта g класса Graphics. В качестве первого параметра методу FillRectangle передается кисть redBrush, которую нужно использовать для рисования. Второй и третий параметры метода FillRectangle задают координаты, в которых будет нарисован квадрат.

Класс Pen


Класс Pen определяет объект, используемый для рисования прямых линий и кривых. Этот класс не наследуется. Конструкторы класса: 1) Pen(Color)  инициализирует новый экземпляр класса Pen с указанным цветом. 2) Pen(Color, Single) инициализирует новый экземпляр класса Pen с указанными свойствами Color и Width.
Width – в устанавливает ширину пера Pen, в единицах объекта Graphics, используемого для рисования.

Класс Pen. Примеры


Pen redPen = new Pen(Color.Red);
// толщина пера по умолчанию 1 пиксель
Color green = Color.Green;
// с использованием дополнительной переменной Pen greenPen = new Pen(green, 4.5f);
Можно вводить новый объект без указания явного имени пера (пример создания динамического объекта – пера): g.DrawRectangle(new Pen(Color.Red, 3), r); например, для рисования прямоугольника r красным пером толщиной 3 пикселя, используя графический контекст («холст») g.


Метод DrawLine рисует линию, соединяющую две точки с заданными координатами (метод перегружен).
DrawLine(Pen, Point, Point);
DrawLine(Pen, PointF, PointF);
DrawLine(Pen, int, int, int, int);
DrawLine(Pen, float, float, float, float);
Первый параметр задает инструмент для рисования линии – перо. Остальные параметры методов DrawLine задают координаты соединяемых точек. Эти координаты могут быть заданы как объекты класса Point и PointF, а также в виде целых чисел и чисел с плавающей десятичной точкой.


Рисование прямой линии


Класс Brush определяет объекты, которые используются для заливки внутри графических фигур, таких как прямоугольники, эллипсы, круги, многоугольники и дорожки. Это абстрактный базовый класс, который не может быть реализован. Для создания объекта «кисть» используются классы, производные от Brush, такие как SolidBrush, TextureBrush и LinearGradientBrush,  например: SolidBrush br = new SolidBrush(Color.Aqua); g.FillRectangle(br, r);
// закраска прямоугольника на «холсте» g Или без явного объявления объекта «кисть» br: g.FillRectangle(new SolidBrush(Color.Red), r);


Класс Brush


Рисование прямой линии


private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
g.Clear(Color.Yellow);
g.DrawLine(new Pen(Brushes.Blue, 2), 10, 20, 200, 30);
}
или
Graphics g = e.Graphics;
g.Clear(Color.Yellow);
Pen myPen = new Pen(Color.Red, 2);
g.DrawLine(myPen, 30, 50, 30, 150);


Метод DrawRectangle позволяет рисовать прямоугольники, заданные координатой верхнего левого угла, а также шириной и высотой. В библиотеке классов .NET Frameworks имеется три перегруженных варианта этого метода:
DrawRectangle(Pen, Rectangle);
DrawRectangle(Pen, int, int, int, int);
DrawRectangle(Pen, float, float, float, float);
В качестве первого параметра этим методам передается перо класса Pen. Остальные параметры задают расположение и размеры прямоугольника. Класс Rectangle используется для описания расположения и размеров прямоугольной области. Свойства X и Y этого класса задают координаты верхнего левого угла прямоугольной области, соответственно, по горизонтальной и вертикальной оси координат.


Рисование прямоугольника


private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
g.Clear(Color.Yellow);
Pen myPen = new Pen(Color.Red, 2);
g.DrawRectangle(myPen, 10, 10, 200, 50);
//незакрашеный прямоугольник
g.FillRectangle(Brushes.Blue, 10, 70, 200, 80);
//закрашеный прямоугольник
}


Рисование прямоугольника


Метод DrawEllipse рисует эллипс, вписанный в прямоугольную область, расположение и размеры которой передаются ему в качестве параметров.
Предусмотрено четыре перегруженных варианта метода DrawEllipse:
DrawEllipse(Pen, Rectangle);
DrawEllipse(Pen, RectangleF);
DrawEllipse(Pen, int, int, int, int);
DrawEllipse(Pen, float, float, float, float);
Эти методы отличаются только способом, при помощи которого описывается расположение и размеры прямоугольной области, в которую вписан эллипс.


Рисование эллипса


Рисование эллипса


private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
g.Clear(Color.Yellow);
Pen myPen = new Pen(Color.Red, 2);
g.DrawEllipse(myPen, 100, 100, 100, 100);
//незакрашенный эллипс
g.FillEllipse(Brushes. LightGray, 50, 50, 50, 50); //закрашенный эллипс
}


При помощи метода DrawArc программа может нарисовать сегмент эллипса. Сегмент задается при помощи координат прямоугольной области, в которую вписан эллипс, а также двух углов, отсчитываемых в направлении против часовой стрелки. Первый угол Angle1 задает расположение одного конца сегмента, а второй Angle2 – расположение другого конца сегмента.


Рисование сегмента эллипса


Предусмотрено четыре перегруженных варианта метода DrawArc:
DrawArc(Pen, Rectangle, float, float);
DrawArc(Pen, RectangleF, float, float);
DrawArc(Pen, int, int, int, int, int, int);
DrawArc(Pen, float, float, float, float, float, float);
Первый параметр метода DrawArc определяет перо, с помощью которого будет нарисован сегмент. Расположение и размеры прямоугольной области передаются методу DrawArc аналогично тому, как это делается для рассмотренного выше метода DrawEllipse.


Рисование сегмента эллипса


private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
g.Clear(Color.Yellow);
Pen myPen = new Pen(Color.Red, 2);
g.DrawArc(myPen, 10, 10, 200, 150, 30, 270);
// незамкнутый сегмент эллипса
g.DrawPie(myPen, 30, 30, 100, 110, 20, 200);
//незакрашеный замкнутый сегмент эллипса
g.FillPie(Brushes.Green, 170, 10, 200, 150, 0, 120);
// закрашеный замкнутый сегмент эллипса
}


Рисование сегмента эллипса


Метод DrawPolygon поможет Вам в тех случаях, когда нужно нарисовать многоугольник, заданный своими вершинами. Предусмотрено два варианта этого метода:
DrawPolygon(Pen, Point[]);
DrawPolygon(Pen, PointF[]);
В первом случае методу DrawPolygon через второй параметр передается массив точек класса Point, в котором координаты точек заданы целыми числами, а во втором – массив класса PointF, где координаты соединяемых точек задаются в виде числа с плавающей десятичной точкой.


Рисование многоугольника


Многоугольник DrawPolygon.
В нем определили перо myPen
и массив точек myPoints.


private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
g.Clear(Color.Yellow);
Pen myPen = new Pen(Color.Red, 2);
Point[] myPoints =
{
new Point(40, 50),
new Point(50, 60),
new Point(60, 40),
new Point(70, 60),
new Point(80, 40),
new Point(90, 60),
new Point(120, 70),
new Point(100, 90),
new Point(50, 90),
};
g.DrawPolygon(myPen, myPoints);
g.FillRectangle(Brushes.Black, 100,75, 5, 5);
}


Рисование многоугольника


Методы для рисования закрашенных фигур
В классе Graphics определен ряд методов, предназначенных для рисования закрашенных фигур.
Есть два отличия методов с префиксом Fill от одноименных методов с префиксом Draw. Прежде всего, методы с префиксом Fill рисуют закрашенные фигуры, а методы с префиксом Draw – не закрашенные. Кроме этого, в качестве первого параметра методам с префиксом Fill передается не перо класса Pen, а кисть класса Brush.


    Метод


    Описание


    FillRectangle


    Рисование закрашенного прямоугольника


    FillRectangles


    Рисование множества закрашенных многоугольников


    FillPolygon


    Рисование закрашенного многоугольника


    FillEllipse


    Рисование закрашенного эллипса


    FillPie


    Рисование закрашенного сегмента эллипса


    FillClosedCurve



    FillRegion


    Рисование закрашенной области типа Region


Пример рисования в С#
Кораблик


private void Form1_Paint(object sender, PaintEventArgs e)
{ Graphics g = e.Graphics;
g.Clear(Color.Turquoise);
SolidBrush myCorp = new SolidBrush(Color.DarkMagenta);
SolidBrush myTrum = new SolidBrush(Color.DarkOrchid);
SolidBrush myTrub = new SolidBrush(Color.DeepPink);
SolidBrush mySeа = new SolidBrush(Color.Blue);
Pen myWind = new Pen(Color.Yellow, 2);
g.FillRectangle(myTrub, 300, 125, 75, 75);
g.FillRectangle(myTrub, 480, 125, 75, 75);
g.FillPolygon(myCorp, new Point[]
{new Point(100,300),new Point(700,300),
new Point(700,300),new Point(600,400),
new Point(600,400),new Point(200,400),
new Point(200,400),new Point(100,300) });
g.FillRectangle(myTrum, 250, 200, 350, 100);
int x = 50; int Radius = 50;
while (x <= 800 - Radius)
{g.FillPie(mySeа, 0 + x, 375, 50, 50, 0, -180); x += 50; }
for (int i = 300; i <= 550; i += 50)
{ g.DrawEllipse(myWind, i, 240, 20, 20); }
}


Результат работы программы

Метод узловой точки


private void Form1_Paint(object sender, PaintEventArgs e)
{
int x = 50, y = 50, a = 10;
Graphics g = e.Graphics;
g.Clear(Color.Yellow);
Point[] raketa =
{
new Point(x, y),
new Point(x + 3 * a, y),
new Point(x + 5 * a, y + a),
new Point(x + 11 * a, y + a),
new Point(x + 13 * a, y + 3 * a),
new Point(x + 11 * a, y + 5 * a),
new Point(x + 5 * a, y + 5 * a),
new Point(x + 3 * a, y + 6 * a),
new Point(x, y + 6 * a),
new Point(x + 2 * a,y + 4 * a),
new Point(x + 2 * a, y + 2 * a),
new Point(x,y),
};


Point[] sled =
{
new Point(x - 2 * a, y + a),
new Point(x + a, y + 2 * a),
new Point(x + a, y + 4 * a),
new Point(x - 2 * a, y + 5 * a),
new Point(x - 2 * a, y + a),
};
SolidBrush B1 = new SolidBrush(Color.DarkMagenta);
SolidBrush B2 = new SolidBrush(Color.Red);
g.FillPolygon(B1, raketa);
g.FillPolygon(B2, sled);
SolidBrush B3 = new SolidBrush(Color.Blue);
g.FillEllipse(B3, x + 6 * a, y + 5 * a / 2, a, a);
g.FillEllipse(B3, x + 8 * a, y + 5 * a / 2, a, a);
g.FillEllipse(B3, x + 10 * a, y + 5 * a / 2, a, a);
}


150,200, 20
350, 350 30

Элемент управления Timer


Timer является компонентом для запуска действий, повторяющихся через определенный промежуток времени. События повторяются с периодичностью, указанной в миллисекундах в свойстве Interval. Установка свойства Enabled в значение true запускает таймер.
Хотя он не является визуальным элементом, но его также можно перетащить с Панели Инструментов на форму:

Элемент управления Timer


Наиболее важные свойства и методы таймера:
Свойство Enabled: при значении true указывает, что таймер будет запускаться вместе с запуском формы
Свойство Interval: указывает интервал в миллисекундах, через который будет срабатывать обработчик события Tick, которое есть у таймера
Метод Start(): запускает таймер
Метод Stop(): останавливает таймер


    Событие Tick


Каждый тик таймера порождает событие Tick, обработчик которого обычно и создают в приложении. В этом обработчике могут изменяться какие-либо величины, и вызываться принудительная перерисовка окна. Для создания анимации весь код, рисующий что-либо на форме, должен находиться в обработчике события Paint.


    Для создания простой анимации достаточно использовать таймер, при тике которого будут изменяться параметры изображения (например, координаты концов отрезка) и вызываться обработчик события Paint для рисования по новым параметрам. При таком подходе не надо заботиться об удалении старого изображения, ведь оно создается в окне заново.
    Invalidate() – метод, делающий недействительной всю поверхность элемента управления и вызывающий его перерисовку.

int t;


int t;
private void timer1_Tick(object sender, EventArgs e)
{
label2.Text = Convert.ToString(t++); // отсчет времени
if (t % 5 == 0) button1.Left += 5; // перемещение кнопки
}


    Событие timer1_Tick

int t;


int t;
private void timer1_Tick(object sender, EventArgs e)
{
label2.Text = Convert.ToString(t++); // отсчет времени
if (t % 5 == 0) button1.Left += 5; // перемещение кнопки
}
private void button1_Click(object sender, EventArgs e)
{
if (timer1.Enabled == true)
{ timer1.Stop(); }
else
{ timer1.Start(); }
}


    Обработчик события Button1_Click


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


int x1 = 100, y1 = 100, x2 = 10, y2 = 10;
private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
g.Clear(Color.Yellow);
Pen myPen = new Pen(Color.Red, 2);
g.FillEllipse(Brushes.LightGray, x1, y1, x2, y2);
}
int t = 0;
private void timer1_Tick(object sender, EventArgs e)
{
t = t+1;
label2.Text = t.ToString();
x2 = x2 + 1; // изменение большой полуоси эллипса а
y2 = y2 + 1; // изменение малой полуоси эллипса b
Invalidate(); //Принудительный вызов перерисовки Paint
}
private void button1_Click(object sender, EventArgs e)
{
if (timer1.Enabled == true) { timer1.Stop(); }
else { timer1.Start(); }
}


    Создание анимации


    Результат работы программы

Метод узловой точки. Движение ракеты


int x1 = 50, a1=10;
private void Form1_Paint(object sender, PaintEventArgs e)
{
int x = x1, y = 50, a = a1;
Graphics g = e.Graphics;
g.Clear(Color.Yellow);
Point[] raketa =
{
new Point(x, y),
new Point(x + 3 * a, y),
new Point(x + 5 * a, y + a),
new Point(x + 11 * a, y + a),
new Point(x + 13 * a, y + 3 * a),
new Point(x + 11 * a, y + 5 * a),
new Point(x + 5 * a, y + 5 * a),
new Point(x + 3 * a, y + 6 * a),
new Point(x, y + 6 * a),
new Point(x + 2 * a,y + 4 * a),
new Point(x + 2 * a, y + 2 * a),
new Point(x,y),
};


Point[] sled =
{
new Point(x - 2 * a, y + a),
new Point(x + a, y + 2 * a),
new Point(x + a, y + 4 * a),
new Point(x - 2 * a, y + 5 * a),
new Point(x - 2 * a, y + a),
};
SolidBrush B1 = new SolidBrush(Color.DarkMagenta);
SolidBrush B2 = new SolidBrush(Color.Red);
g.FillPolygon(B1, raketa);
g.FillPolygon(B2, sled);
SolidBrush B3 = new SolidBrush(Color.Blue);
g.FillEllipse(B3, x + 6 * a, y + 5 * a / 2, a, a);
g.FillEllipse(B3, x + 8 * a, y + 5 * a / 2, a, a);
g.FillEllipse(B3, x + 10 * a, y + 5 * a / 2, a, a);
}
private void button1_Click(object sender, EventArgs e)
{
if (timer1.Enabled == true) { timer1.Stop(); }
else { timer1.Start(); }
}
private void timer1_Tick(object sender, EventArgs e)
{
x1 = x1 + 5;
Invalidate(); //Принудительный вызов перерисовки Paint
}



написать администратору сайта