Advertisement
SmnVadik

Lab 6.3 (Delphi)

Sep 9th, 2023 (edited)
494
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 12.13 KB | None | 0 0
  1. unit Unit1;
  2.  
  3. interface
  4.  
  5. uses
  6.     Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  7.     System.Classes, Vcl.Graphics,
  8.     Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Grids, Vcl.Menus;
  9.  
  10. type
  11.     TForm1 = class(TForm)
  12.     StringGridPoints: TStringGrid;
  13.     EditAmount: TEdit;
  14.     ButtonPoints: TButton;
  15.         Memo1: TMemo;
  16.         ButtonFind: TButton;
  17.     MainMenu1: TMainMenu;
  18.     N1: TMenuItem;
  19.     N2: TMenuItem;
  20.     N3: TMenuItem;
  21.     N4: TMenuItem;
  22.     N5: TMenuItem;
  23.     N6: TMenuItem;
  24.     N7: TMenuItem;
  25.     OpenDialog1: TOpenDialog;
  26.     SaveDialog1: TSaveDialog;
  27.         procedure ButtonFindClick(Sender: TObject);
  28.     procedure FormCreate(Sender: TObject);
  29.     procedure ButtonPointsClick(Sender: TObject);
  30.     procedure EditAmountKeyPress(Sender: TObject; var Key: Char);
  31.     procedure EditAmountChange(Sender: TObject);
  32.     procedure StringGridPointsKeyPress(Sender: TObject; var Key: Char);
  33.     procedure StringGridPointsSetEditText(Sender: TObject; ACol, ARow: Integer;
  34.       const Value: string);
  35.     procedure N3Click(Sender: TObject);
  36.     procedure N7Click(Sender: TObject);
  37.     procedure N4Click(Sender: TObject);
  38.     procedure N5Click(Sender: TObject);
  39.     procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  40.     procedure N2Click(Sender: TObject);
  41.     private
  42.         { Private declarations }
  43.     public
  44.         { Public declarations }
  45.     end;
  46.  
  47. type
  48.     TPoint = record
  49.         X, Y: Double;
  50.     end;
  51.  
  52.     TLineEquation = class
  53.     private
  54.         FK, FB: Double;
  55.     public
  56.         property K: Double read FK;
  57.         property B: Double read FB;
  58.  
  59.         function DistanceToLineSquared(X, Y: Double): Double;
  60.         class function FromPoints(X1, Y1, X2, Y2: Double): TLineEquation;
  61.     end;
  62.  
  63. var
  64.     Form1: TForm1;
  65.     Path: String;
  66.     IsFileOpen: Boolean;
  67.  
  68. implementation
  69.  
  70. {$R *.dfm}
  71.  
  72. function TLineEquation.DistanceToLineSquared(X, Y: Double): Double;
  73. var
  74.     Distance: Double;
  75. begin
  76.     Distance := (FK * X - Y + FB) / Sqrt(FK * FK + 1);
  77.     Result := Distance * Distance;
  78. end;
  79.  
  80. class function TLineEquation.FromPoints(X1, Y1, X2, Y2: Double): TLineEquation;
  81. var
  82.     Line: TLineEquation;
  83. begin
  84.     Line := TLineEquation.Create;
  85.     If (X2 - X1) <> 0 Then
  86.     Begin
  87.         Line.FK := (Y2 - Y1) / (X2 - X1);
  88.         Line.FB := Y1 - Line.FK * X1;
  89.     End;
  90.     Result := Line;
  91. end;
  92.  
  93. function FindDividingLine(const Points: TArray<TPoint>): TLineEquation;
  94. var
  95.     Size, I, J, K: Integer;
  96.     BestError, Error: Double;
  97.     BestLine, CurrentLine: TLineEquation;
  98. begin
  99.     Size := Length(Points);
  100.     if Size mod 2 <> 0 then
  101.         raise Exception.Create('Количество точек должно быть четным.');
  102.  
  103.     BestError := Double.MaxValue;
  104.     BestLine := TLineEquation.Create;
  105.  
  106.     for I := 0 to Size - 1 do
  107.     begin
  108.         for J := I + 1 to Size - 1 do
  109.         begin
  110.             CurrentLine := TLineEquation.FromPoints(Points[I].X, Points[I].Y,
  111.               Points[J].X, Points[J].Y);
  112.  
  113.             Error := 0;
  114.             for K := 0 to Size - 1 do
  115.                 Error := Error + CurrentLine.DistanceToLineSquared(Points[K].X, Points[K].Y);
  116.  
  117.             if Error < BestError then
  118.             begin
  119.                 BestError := Error;
  120.                 BestLine := CurrentLine;
  121.             end;
  122.         end;
  123.     end;
  124.     Result := BestLine;
  125. end;
  126.  
  127. procedure TForm1.ButtonFindClick(Sender: TObject);
  128. var
  129.     Points: TArray<TPoint>;
  130.     Line: TLineEquation;
  131.     I, Size: Integer;
  132. begin
  133.     Size := StrToInt(EditAmount.Text);
  134.     SetLength(Points, Size);
  135.     For I := 0 to Size - 1 do
  136.     Begin
  137.         Points[I].X := StrToFloat(StringGridPoints.Cells[I + 1, 1]);
  138.         Points[I].Y := StrToFloat(StringGridPoints.Cells[I + 1, 2])
  139.     End;
  140.     Line := FindDividingLine(Points);
  141.     N5.Enabled := True;
  142.     Memo1.Text := 'Уравнение прямой: y = ' + FormatFloat('0.00', Line.K) + 'x + ' + FormatFloat('0.00', Line.B);
  143. end;
  144.  
  145. procedure TForm1.ButtonPointsClick(Sender: TObject);
  146. var
  147.     Size, I: Integer;
  148. begin
  149.  
  150.     StringGridPoints.Enabled := True;
  151.     StringGridPoints.Rows[1].Clear;
  152.     StringGridPoints.Rows[2].Clear;
  153.     StringGridPoints.Cells[0,1] := 'X';
  154.     StringGridPoints.Cells[0,2] := 'Y';
  155.  
  156.     Size := StrToInt(EditAmount.Text);
  157.     StringGridPoints.ColCount := Size + 1;
  158.     For I := 1 to Size do
  159.     Begin
  160.         StringGridPoints.Cells[I, 0] := IntToStr(I);
  161.     End;
  162.     Memo1.Clear;
  163.     ButtonFind.Enabled := False;
  164.     N5.Enabled := False
  165. end;
  166.  
  167. procedure TForm1.EditAmountChange(Sender: TObject);
  168. var
  169.     num: Integer;
  170.     IsCorrect: Boolean;
  171. begin
  172.     IsCorrect := True;
  173.     try
  174.         num := StrToInt(EditAmount.Text)
  175.     except
  176.         IsCorrect := False;
  177.     end;
  178.     If IsCorrect And (num > 0) And (Num < 100) And (Num mod 2 = 0) Then
  179.     Begin
  180.         ButtonPoints.Enabled := True;
  181.     End
  182.     Else
  183.         ButtonPoints.Enabled := False;
  184.     StringGridPoints.Enabled := False;
  185.     ButtonFind.Enabled := False;
  186.     Memo1.Clear;
  187.     N5.Enabled := False
  188. end;
  189.  
  190. procedure TForm1.EditAmountKeyPress(Sender: TObject; var Key: Char);
  191. begin
  192.     if not (Key in ['0'..'9', #13, #8]) then
  193.         Key := #0;
  194.     if (Key = #13) And (ButtonPoints.Enabled) then
  195.         ButtonPoints.Click;
  196. end;
  197.  
  198. procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  199. begin
  200.     CanClose := Application.MessageBox('Вы действительно хотите выйти?', 'Выход', MB_ICONQUESTION + MB_YESNO) = ID_YES
  201. end;
  202.  
  203. procedure TForm1.FormCreate(Sender: TObject);
  204. var
  205.     I: Integer;
  206. begin
  207.     StringGridPoints.Cells[0,0] := '№/№';
  208.     StringGridPoints.Cells[0,1] := 'X';
  209.     StringGridPoints.Cells[0,2] := 'Y';
  210. end;
  211.  
  212. procedure TForm1.N2Click(Sender: TObject);
  213. const
  214.     Info1 = 'На плоскости заданы 2n точек своими координатами. Найти уравнение'#13#10;
  215.     Info2 = 'какой-либо прямой, делящей данное множество на два подмножества по n точек.'#13#10;
  216.     Info3 = '1. Минимальное количество точек - 2, максимальная - 20.'#13#10;
  217.     Info4 = '2. Количество точек должно быть кратно двум.'#13#10;
  218.     Info5 = '3. Диапазон ввода координат от 0 до 99.'#13#10;
  219. begin
  220.     Application.MessageBox(Info1 + Info2 + Info3 + Info4 + Info5, 'Справка', 0);
  221. end;
  222.  
  223. procedure TForm1.N3Click(Sender: TObject);
  224. begin
  225.     Application.MessageBox('Сымоник Вадим, гр. 251004', 'Разработчик', 0)
  226. end;
  227.  
  228. Function GetSize(var FileInput: TextFile): String;
  229. Const
  230.     MIN_NUM = 1;
  231.     MAX_NUM = 100;
  232. Var
  233.     Size, Num: Integer;
  234.     Str: String;
  235.     IsCorrect: Boolean;
  236. Begin
  237.     Size := 0;
  238.     Str := '';
  239.     If Not Eof(FileInput) Then
  240.     Begin
  241.         IsCorrect := True;
  242.         Try
  243.             Read(FileInput, Size);
  244.         Except
  245.             MessageBox(Form1.Handle, PChar('Недопустимый размер массива!'),
  246.               'Ошибка', MB_ICONSTOP);
  247.             IsCorrect := False;
  248.             Size := 0;
  249.         End;
  250.     End
  251.     Else
  252.         MessageBox(Form1.Handle, PChar('Недостаточно данных в файле!'),
  253.           'Ошибка', MB_ICONSTOP);
  254.     If (Size > 0) And (Size <= MAX_NUM) Then
  255.         If Size mod 2 = 0 Then
  256.             Str := IntToStr(Size)
  257.         Else
  258.             Application.MessageBox('Нечетное количество данных', 'Ошибка', 0)
  259.     Else
  260.         Application.MessageBox('Проверьте корректность данных в файле', 'Ошибка', 0);
  261.     GetSize := Str;
  262. End;
  263.  
  264. Function TakeInformationIntoCell(Var FileInput: TextFile;
  265.   Var IsCorrect: Boolean): String;
  266. Var
  267.     Temp: Integer;
  268.     Str: String;
  269.     StrTemp: String;
  270. Begin
  271.     If Not Eof(FileInput) Then
  272.     Begin
  273.         Try
  274.             Read(FileInput, Temp);
  275.             Str := IntToStr(Temp);
  276.             StrTemp := IntToStr(Abs(Temp));
  277.         Except
  278.             MessageBox(Form1.Handle, PChar('Неверные данные!'), 'Ошибка',
  279.               MB_ICONSTOP);
  280.             IsCorrect := False;
  281.         End;
  282.         If Length(StrTemp) > 2 Then
  283.         Begin
  284.             IsCorrect := False;
  285.             MessageBox(Form1.Handle,
  286.               PChar('Недопустимый диапазон входных данных!'), 'Ошибка',
  287.               MB_ICONSTOP);
  288.             Str := '';
  289.         End;
  290.     End
  291.     Else
  292.     Begin
  293.         IsCorrect := False;
  294.         MessageBox(Form1.Handle, PChar('Недостаточно значений в файле!'),
  295.           'Ошибка', MB_ICONSTOP);
  296.         Str := '';
  297.     End;
  298.     TakeInformationIntoCell := Str;
  299. End;
  300.  
  301. Procedure InputPointsInMatrix(var FileInput: TextFile);
  302. Var
  303.     I, J: Integer;
  304.     IsCorrect: Boolean;
  305. Begin
  306.     IsCorrect := True;
  307.     With Form1 do
  308.     Begin
  309.         For I := 1 to StringGridPoints.ColCount - 1 do
  310.         Begin
  311.             For J := 1 to StringGridPoints.RowCount - 1 do
  312.             Begin
  313.                 StringGridPoints.Cells[I, J] :=
  314.                   TakeInformationIntoCell(FileInput, IsCorrect);
  315.             End;
  316.         End;
  317.         ButtonFind.Enabled := IsCorrect;
  318.     End;
  319. End;
  320.  
  321. procedure TForm1.N4Click(Sender: TObject);
  322. var
  323.     FileInput: TextFile;
  324. begin
  325.     If OpenDialog1.Execute Then
  326.     Begin
  327.         AssignFile(FileInput, OpenDialog1.FileName);
  328.         Try
  329.             Try
  330.                 Reset(FileInput);
  331.                 EditAmount.Text := GetSize(FileInput);
  332.                 if EditAmount.Text <> '' then
  333.                 Begin
  334.                     ButtonPoints.Click;
  335.                     InputPointsInMatrix(FileInput);
  336.                 End;
  337.             Finally
  338.                 CloseFile(FileInput);
  339.             End;
  340.         Except
  341.  
  342.         End;
  343.     End;
  344. end;
  345.  
  346. Function Open(): String;
  347. begin
  348.     with Form1 Do
  349.     begin
  350.         If SaveDialog1.Execute Then
  351.         begin
  352.             Path := SaveDialog1.FileName;
  353.             IsFileOpen := True;
  354.         end
  355.         Else
  356.             IsFileOpen := False;
  357.     end;
  358.     Open := Path;
  359. end;
  360.  
  361. procedure TForm1.N5Click(Sender: TObject);
  362. var
  363.     F: TextFile;
  364. begin
  365.     Path := Open;
  366.     If IsFileOpen Then
  367.     Begin
  368.         AssignFile(F, Path);
  369.         Rewrite(F);
  370.         Writeln(F, Memo1.Text);
  371.         Application.MessageBox('Данные успешно сохранены в файл',
  372.           'Результат', 0);
  373.         CloseFile(F);
  374.     End;
  375. end;
  376.  
  377. procedure TForm1.N7Click(Sender: TObject);
  378. begin
  379.     Form1.Close
  380. end;
  381.  
  382. procedure TForm1.StringGridPointsKeyPress(Sender: TObject; var Key: Char);
  383. begin
  384.     If not (Key in ['0'..'9', #8, #13]) Then
  385.         Key := #0;
  386.     if (Key = #13) And (ButtonFind.Enabled = True) then
  387.         ButtonFind.Click
  388. end;
  389.  
  390. procedure TForm1.StringGridPointsSetEditText(Sender: TObject; ACol,
  391.   ARow: Integer; const Value: string);
  392.  
  393. var
  394.     I, J: Integer;
  395.     N: Integer;
  396.     IsCorrect: Boolean;
  397.  
  398. begin
  399.     IsCorrect := True;
  400.     For I := 1 to StringGridPoints.RowCount - 1 do
  401.     Begin
  402.         for J := 1 to StringGridPoints.ColCount - 1 do
  403.         Begin
  404.             If StringGridPoints.Cells[I, J] <> '' Then
  405.             Try
  406.                 N := StrToInt(StringGridPoints.Cells[I, J]);
  407.             Except
  408.                 StringGridPoints.Cells[I, J] := '';
  409.                 Application.MessageBox('Проверьте корректность введенных данных', 'Ошибка', 0);
  410.             End;
  411.  
  412.             If Length(StringGridPoints.Cells[I, J]) > 2 Then
  413.             Begin
  414.                 StringGridPoints.Cells[I, J] := '';
  415.                 Application.MessageBox('Диапазон ввода [0; 99]', 'Ошибка', 0);
  416.             End;
  417.         End;
  418.     End;
  419.  
  420.  
  421.     For J := 1 to StringGridPoints.RowCount - 1 do
  422.         for I := 1 to StringGridPoints.ColCount - 1 do
  423.             If Length(StringGridPoints.Cells[I, J]) = 0 Then
  424.                 IsCorrect := False;
  425.     ButtonFind.Enabled := IsCorrect;
  426.     Memo1.Clear;
  427.     N5.Enabled := False
  428. end;
  429.  
  430. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement