Здесь я постараюсь объяснить и показать на примерах графическме возможности GDI. Если вы уже знакомы стем как нарисовать круг, точку, линию..., то тут имеются интересные задачи на рисование и математику! Холст(Canvas) Свойство canvas — это объект типа TCanvas. Методы этого типа обеспечивают вывод графических примитивов (точек, линий, окружностей, прямоугольников и т. д.), а свойства позволяют задать характеристики выводимых графических примитивов: цвет, толщину и стиль линий; цвет и вид заполнения областей; характеристики шрифта при выводе текстовой информации. Точка, точка, запятая. Почти все компоненты Delphi имеют холст. А сейчас давайте разберем пару примеров! Запустите Delphi. Перед вами форма, на которой можно рисовать. Давайте сделаем так, чтобы можно было рисовать на нашей форме мышью. В разделе глобальных переменных объявите переменную up: boolean; он будет определять нажатали кнопка мыши или нет. По событию FormCreate сделайте ее равной false. Далее по событию FormMouseUp сделайте ее равной true, а по событию FormMouseDown присвойте ей значение false. В глобальных паременных заведите переменные x1,y1: integer; и по событию FormMouseMove присвойте им значения переметров x1:=x; y1:=y; это делается для того, чтобы потом другая функция узнала положение курсора. Теперь поставьте на форму таймер с интервалом 1. В таймере Code if not up then // если не отпущена кнопка то form1.Canvas.Pixels[x1,y1]:=0; // форма1.холст.точка[координаты x,y]:=цвет точки Получилось, но не совсем то, что хотелось бы. Усовершенствуем эту программу, сделаем, чтобы рисовалось нормально. Для этого мы будем рисовать не точками, а линиями! Нам понадобятся еще две переменные x2,y2: integer; объявите их в глобальных переменных. По событию FormMouseDown задайте этим переменным параметры функции x2:=x; y2:=y;. В таймере должен быть такой код: Code if not up then begin form1.Canvas.MoveTo(x2,y2); form1.Canvas.LineTo(x1,y1); x2:=x1; y2:=y1; end; Готово! Полный код программы: Code unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls;
type TForm1 = class(TForm) Timer1: TTimer; procedure FormCreate(Sender: TObject); procedure FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure Timer1Timer(Sender: TObject); procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); private { Private declarations } public { Public declarations } end;
var Form1: TForm1; Up: boolean; x1,y1,x2,y2: integer; implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject); begin Up:=true; end; procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin Up:=true; end; procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin Up:=false; x2:=x; y2:=y; end; procedure TForm1.Timer1Timer(Sender: TObject); begin if not up then begin form1.Canvas.MoveTo(x2,y2); form1.Canvas.LineTo(x1,y1); x2:=x1; y2:=y1; end; end; procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin x1:=x; y1:=y; end;
end. Добавлено (11.12.2007, 12:10) --------------------------------------------- Интересная задача на рисование и математику: нужно построить круг который обвит синусоидой! Делать будим по событию FormMouseDown; Code procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var a1,a2: real; // углы в радианах которые нам понадобятся x1,y1: extended; // координаты точки begin a1:=0;a2:=0; // обнуляем углы repeat a1:=a1+0.001; a2:=a2+0.01; x1:=x+cos(a1)*100; y1:=y+sin(a1)*100; // расчитываем координаты точек круга form1.Canvas.Pixels[round(x1),round(y1)]:=0; // ставим расчитаные точки x1:=x+cos(a1)*(100+sin(a2)*10); y1:=y+sin(a1)*(100+sin(a2)*10); form1.Canvas.Pixels[round(x1),round(y1)]:=0; until a1>=2*pi; end; Добавлено (11.12.2007, 12:32) --------------------------------------------- Карандаш Карандаш(canvas.pen) используется для вычерчивания точек, линий, контуров геометрических фигур: прямоугольников, окружностей, эллипсов, дуг и др. Вид линии, которую оставляет карандаш на поверхности холста, определяют свойства объекта pen, которые перечислены ниже: Свойство Определяет Color Цвет линии Width Толщину линии Style Вид линии Mode Режим отображения Свойство style определяет вид (стиль) линии, которая может быть непрерывной или прерывистой, состоящей из штрихов различной длины. Толщина пунктирной линии не может быть больше 1. Если значение свойства Pen.width больше единицы, то пунктирная линия будет выведена как сплошная. Значение свойства pen.styl определяет вид линии Константа Вид линии psSolid Сплошная линия psDash Пунктирная линия, длинные штрихи psDot Пунктирная линия, короткие штрихи psDashDot Пунктирная линия, чередование длинного и короткого штрихов psDashDotDot Пунктирная линия, чередование одного длинного и двух коротких штрихов psClear Линия не отображается Свойство Mode определяет, как будет формироваться цвет точек линии в зависимости от цвета точек холста, через которые эта линия прочерчивается. По умолчанию вся линия вычерчивается цветом, определяемым значением свойства Pen.Color. Однако программист может задать инверсный цвет линии по отношению к цвету фона. Это гарантирует, что независимо от цвета фона все участки линии будут видны, даже в том случае, если цвет линии и цвет фона совпадают. Значение свойства pеn.mode влияет на цвет линии Константа Цвет линии pmBlack Черный, не зависит от значения свойства Pen.Color pmWhite Белый, не зависит от значения свойства Pen.Color pmCopy Цвет линии определяется значением свойства Pen.Color pmNotCopy Цвет линии является инверсным по отношению к значению свойства Pen.Color pmNot Цвет точки линии определяется как инверсный по отношению к цвету точки холста, в которую выводится точка линии Добавлено (11.12.2007, 12:49) --------------------------------------------- Кисть Кисть (canvas.Brush) используется методами, обеспечивающими вычерчивание замкнутых областей, например геометрических фигур, для заливки (закрашивания) этих областей. Кисть, как объект, обладает двумя свойствами: Color - Цвет закрашивания замкнутой области Style - Стиль (тип) заполнения области Значения свойства Brush.style определяют тип закрашивания bsSolid - Сплошная заливка bsClear - Область не закрашивается bsHorizontal - Горизонтальная штриховка bsVertical - Вертикальная штриховка bsFDiagonal - Диагональная штриховка с наклоном линий вперед bsBDiagonal - Диагональная штриховка с наклоном линий назад bsCross - Горизонтально-вертикальная штриховка, в клетку bsDiagCross - Диагональная штриховка, в клетку Добавлено (11.12.2007, 16:45) --------------------------------------------- Вот еще одна задачка! Нужно смоделировать вращение замли вокруг солнца, и вращение луны вокруг земли. Нам понадобится таймер с интервалом 1, и пара переменных. Код программы: Code unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls;
type TForm1 = class(TForm) Timer1: TTimer; procedure Timer1Timer(Sender: TObject); procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } end;
var Form1: TForm1; a1,a2: real;
implementation
{$R *.dfm}
procedure TForm1.Timer1Timer(Sender: TObject); var x1,y1: real; // координаты земли x2,y2: real; // координаты луны begin form1.Repaint; // чистим форму form1.Canvas.Ellipse(150,150,250,250); // рисуем солнце a1:=a1+pi/365.25; // увеличиваем угол вращения земли относительно солнца a2:=a2+pi/27.3; // увеличиваем угол вращения луны относительно земли x1:=200+cos(a1)*150; y1:=200+sin(a1)*150; // расчет координат земли x2:=x1+cos(a2)*30; y2:=y1+sin(a2)*30; // расчет координат луны form1.Canvas.Ellipse(round(x1)-10,round(y1)-10,round(x1)+10,round(y1)+10); // рисуем землю form1.Canvas.Ellipse(round(x2)-3,round(y2)-3,round(x2)+3,round(y2)+3); // рисуем луну end;
procedure TForm1.FormCreate(Sender: TObject); begin a1:=0; a2:=0; // обнуляем углы end;
end.
Сообщение отредактировал Kostia - Среда, 12.12.2007, 05:48 |