Interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Buttons, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
Label1: TLabel;
Label2: TLabel;
Edit1: TEdit;
GroupBox1: TGroupBox;
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
Edit2: TEdit;
Edit3: TEdit;
Edit4: TEdit;
Image1: TImage;
Button1: TButton;
BitBtn1: TBitBtn;
procedure Button1Click(Sender: TObject);
procedure Edit1KeyPress(Sender: TObject; var Key: Char);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
ak,a,b,c:real;
Implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
x,y,k,y1,ap,bp,cp,d:real;
iw,ih:integer;
fl:boolean;
p:array[0..2] of tpoint; //координаты вершин треугольника
begin
ak:=strtofloat(edit1.Text); //сторона квадрата
a:=strtofloat(edit2.Text); //стороны треугольника
b:=strtofloat(edit3.Text);
c:=strtofloat(edit4.Text);
image1.Picture:=nil; //очистка image
// Располагаем стороны треугольника в порядке
//возрастания
if a>b then
begin
x:=a; a:=b; b:=x;
end;
if b>c then
begin
x:=b; b:=c; c:=x;
end;
if a>b then
begin
x:=a; a:=b; b:=x;
end;
// Проверка существования такого треугольника
If (a<=0) or ((a+b)<=c) then
begin
showmessage('Это не треугольник');
edit2.SetFocus;
exit;
end;
fl:=false;
iw:=image1.Width;
ih:=image1.Height;
k:=iw / ak; //коэффициент масштабирования
if c<=ak then
begin
fl:=true;
showmessage('Пройдет');
end
else
//сторона треугольника больше диагонали квадрата
if c>ak*sqrt(2) then
begin
showmessage('Не пройдет');
exit;
end
else
begin
y1:=sqrt(sqr(c)-sqr(ak));
ap:=4*sqr(ak)+4*sqr(y1);
bp:=4*y1*(sqr(a)-sqr(b)-sqr(ak)-sqr(y1));
cp:=sqr(sqr(b))+sqr(sqr(a))+sqr(sqr(ak))+sqr(sqr(y1))+
2*(-sqr(a)*sqr(b)+sqr(b)*sqr(ak)+sqr(b)*sqr(y1)-sqr(a)*sqr(ak)-
sqr(a)*sqr(y1)+sqr(ak)*sqr(y1)-2*sqr(ak)*sqr(b));
d:=sqr(bp)-4*ap*cp;
if d< 0 then
begin
showmessage('Не пройдет');
exit;
end;
y:=(-bp+sqrt(d))/(2*ap);
x:=sqr(b)-sqr(y);
if (x<0) or (y>ak) then
begin
showmessage('Не пройдет');
exit;
end;
x:=sqrt(x);
if y>ak then
begin
showmessage('Не пройдет');
exit;
end
else
begin
fl:=true;
showmessage('Пройдет'); ;
end;
end;
if not fl then
exit;
p[0].X:=0;
p[0].Y:=0;
// очистка Image и задание параметров изображения
image1.Picture:=nil;
image1.Canvas.Pen.Color:=clred;
//image1.Canvas.Brush.Style:=bscross;
image1.Canvas.Brush.Color:=clred;
image1.Canvas.Rectangle(0,0,round(ak*k),round(ak*k));
image1.Canvas.Brush.Color:=clgreen;
//Если большая сторона треугольника меньше
// стороны квадрата
if c<=ak then
begin
p[1].X:=round(c*k);
p[1].Y:=0;
x:=(sqr(b)-sqr(a)+sqr(c))/(2*c);
y:=sqrt((sqr(b)-sqr(x)));
p[2].x:=round(x*k);
p[2].y:=round(y*k);
image1.Canvas.Polygon(p);
exit;
end;
//Если большая сторона треугольника больше
// стороны квадрата
y1:=sqrt(sqr(c)-sqr(ak));
p[1].X:=round(ak*k);
p[1].Y:=round(y1*k);
// x:=(sqr(b)-sqr(a)+sqr(y1)-2*y*y1+sqr(ak))/(2*ak);
// y:=sqrt((sqr(b)-sqr(x)));
p[2].x:=round(x*k);
p[2].y:=round(y*k);
image1.Canvas.Polygon(p);
end;
// Обработка вводимых символов в поля Edit
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
var
edit:tedit;
begin
edit:=sender as tedit;
case key of
'0'..'9',#8:;
'-':begin
if (edit.Text='') then
key:=#0
else
if (edit.Text<>'') and ((copy(edit.Text,length(edit.Text),1)='E') or
(copy(edit.Text,length(edit.Text),1)='e'))then
key:='-'
else
key:=#0;
end;
'+':begin
if (edit.Text='') then
key:='+'
else
if (edit.Text<>'') and ((copy(edit.Text,length(edit.Text),1)='E') or
(copy(edit.Text,length(edit.Text),1)='e'))then
key:='+'
else
key:=#0;
end;
',','.':begin
key:=decimalseparator;
if pos(decimalseparator,edit.Text)<>0 then
key:=#0
end;
'E','e':begin
key:='E';
if ((pos('E',edit.Text)<>0) or (pos('e',edit.Text)<>0))
or ((length(edit.Text)=1)
and ((copy(edit.Text,1,1)='-') or
(copy(edit.Text,1,1)='+'))) or
((length(edit.Text)=0)
and
((pos('E',edit.Text)=0) or (pos('e',edit.Text)=0))) then
key:=#0;
end;
#13: case edit.Tag of //обработка нажатия клавиши Enter
// предварительно вручную устанавливаем свойства tag
// для каждого edit-а
0:edit2.SetFocus;
1:edit3.SetFocus;
2:edit4.SetFocus;
3:button1.SetFocus;
end
else
key:=#0;
end;
end;
end.
Обработка нажатия клавиш при вводе достаточно сложная процедура и не идеальная. Но все-таки она требует пояснений.
С одной стороны для всех Edit-ов обработка одинакова, за исключением обработки нажатия кпавиши Enter. Поэтому объявлена переменная edit:tedit, которой в начале процедуры присваивается значение параметра sender: edit:=sender as tedit. Для выполнения различных действий при нажатии Enter для каждого Edit-а установлено свое, отличное от других, свойство Tag. Для предоставления пользователю возможности ввода чисел в нормальной форме обрабатывается нажатие клавиш латинских ‘E’ и ‘e’ для ввода порядка числа. Вместо обработки каждой нажатой клавиши можно было обработать ошибки конвертирования при преобразовании из строки в число.
Пример 5.
Приведем еще одно полноэкранное приложение решения следующей задачи.
В каждой больничной палате четыре койки. Введите количество палат, количество больных мужчин и количество больных женщин. Определите, можно ли разместить всех больных по палатам (в одну палату кладут больных одного пола).
Изобразите на форме схематично палаты с занятыми и свободными местами.
Форма показана на рис. 1.11
Рис. 1.11 Форма примера 5
Текст Unit-а
{В каждой больничной палате четыре койки.
Введите количество палат, количество больных мужчин и количество больных женщин. Определите, можно ли разместить всех больных по палатам (в одну палату кладут больных одного пола). Изобразите на форме схематично палаты с занятыми и свободными местами.
}
unit Unit1;