Vanilla_Fury

laba_6_3_del

May 30th, 2021
664
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 13.84 KB | None | 0 0
  1. unit laba_6_3_UnitMainForm;
  2.  
  3. interface
  4.  
  5. uses
  6.   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  7.   Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls,
  8.   laba_6_3_UnitGraphic, laba_6_3_UnitTypes, laba_6_3_UnitCalculateBestLine,
  9.   Vcl.Menus;
  10.  
  11. type
  12.   TFormMain = class(TForm)
  13.     MemoCoordinates: TMemo;
  14.     ButtonBuildLine: TButton;
  15.     LabelAboveMemoCoordinates: TLabel;
  16.     ImageCanvas: TImage;
  17.     LabelToMeasureScreenOfUser: TLabel;
  18.     MainMenu1: TMainMenu;
  19.     NFile: TMenuItem;
  20.     NOpen: TMenuItem;
  21.     NHelp: TMenuItem;
  22.     NTask: TMenuItem;
  23.     NAuthor: TMenuItem;
  24.     OpenDialog1: TOpenDialog;
  25.     procedure FormCreate(Sender: TObject);
  26.     procedure MemoCoordinatesChange(Sender: TObject);
  27.     procedure ButtonBuildLineClick(Sender: TObject);
  28.     procedure NTaskClick(Sender: TObject);
  29.     procedure NAuthorClick(Sender: TObject);
  30.     procedure NOpenClick(Sender: TObject);
  31.   private
  32.         MultPix: Single;
  33.         ArrOfCoords: TArrCoord;
  34.   public
  35.         function MultPixels(PixQuant: Integer) : Integer;
  36.   end;
  37.  
  38. procedure MyMessageBoxInfo(Form: TForm; CaptionWindow, TextMessage: String; IsWarning: Boolean = False); external 'Dll_MyMessageBox.dll';
  39. function MyMessageBoxYesNo(Form: TForm; CaptionWindow, TextMessage: String; IsWarning: Boolean = False) : Boolean; external 'Dll_MyMessageBox.dll';
  40.  
  41. var
  42.   FormMain: TFormMain;
  43.  
  44. function FindRegEx(SInput, StrRegEx: String; StrIfNothingFound: String = '') : TArrStr; external 'FindRegExes.dll';
  45.  
  46. implementation
  47.  
  48. {$R *.dfm}
  49.  
  50. procedure TFormMain.ButtonBuildLineClick(Sender: TObject);
  51. var
  52.     KAndB: TKAndB;
  53.     LineIsVertical: Boolean;
  54.  
  55. begin
  56.     KAndB := GetKAndB(ArrOfCoords, LineIsVertical);
  57.     DrawGraphicWithDots(ArrOfCoords);
  58.  
  59.     if LineIsVertical then
  60.         DrawLineVertical(KAndB.B)
  61.     else
  62.         DrawLineNotVertical(KAndB.K, KAndB.B);
  63. end;
  64.  
  65. procedure TFormMain.FormCreate(Sender: TObject);
  66. begin
  67.     MultPix := LabelToMeasureScreenOfUser.Width / 100;
  68.  
  69.     MemoCoordinates.SelectAll();
  70.  
  71.     SetupCanvas();
  72. end;
  73.  
  74. procedure TFormMain.MemoCoordinatesChange(Sender: TObject);
  75. var
  76.     OneLine: String;
  77.     IsCorrect, IsUnique: Boolean;
  78.     i, j, X, Y, PairsFound: Integer;
  79.  
  80. begin
  81.     i := 0;
  82.     IsCorrect := True;
  83.     PairsFound := 0;
  84.     while i < MemoCoordinates.Lines.Count do
  85.     begin
  86.         OneLine := MemoCoordinates.Lines[i];
  87.         if StringReplace(OneLine, ' ', '', [rfReplaceAll]) <> '' then
  88.         begin
  89.             if FindRegEx(OneLine, '^\s*-?0*\d{1,2}\s+-?0*\d{1,2}\s*$')[0] = '' then
  90.                 IsCorrect := False
  91.             else
  92.             begin
  93.                 X := StrToInt(FindRegEx(OneLine, '-?0*\d{1,3}')[0]);
  94.                 Y := StrToInt(FindRegEx(OneLine, '-?0*\d{1,3}')[1]);
  95.  
  96.                 IsUnique := True;
  97.                 j := 0;
  98.                 while (j < PairsFound) and IsUnique do
  99.                 begin
  100.                     if (ArrOfCoords[j].X = X) and (ArrOfCoords[j].Y = Y) then
  101.                         IsUnique := False;
  102.                     Inc(j);
  103.                 end;
  104.  
  105.                 if IsUnique then
  106.                 begin
  107.                     Inc(PairsFound);
  108.                     SetLength(ArrOfCoords, PairsFound);
  109.                     ArrOfCoords[PairsFound - 1].X := X;
  110.                     ArrOfCoords[PairsFound - 1].Y := Y;
  111.                 end;
  112.             end;
  113.         end;
  114.         Inc(i);
  115.     end;
  116.  
  117.     ButtonBuildLine.Enabled := IsCorrect and (PairsFound > 1);
  118. end;
  119.  
  120. function TFormMain.MultPixels(PixQuant: Integer) : Integer;
  121. begin
  122.     Result := Round(PixQuant * MultPix);
  123. end;
  124.  
  125. procedure TFormMain.NAuthorClick(Sender: TObject);
  126. begin
  127.     MyMessageBoxInfo(FormMain, 'Автор', 'Панев Александр, гр. 051007' + #10#13 + 'Минск, 2021');
  128. end;
  129.  
  130. procedure TFormMain.NOpenClick(Sender: TObject);
  131. const
  132.     ErrorDuringInputOccured = 'Возникла ошибка при открытии файла.' + #10#13 +
  133.                 'Пожалуйста, выберите файл нужного формата(.datgrad) с ' +
  134.                 'корректными данными.';
  135.  
  136. var
  137.     FileInput : TextFile;
  138.     PathToFile, String1: String;
  139.  
  140. begin
  141.     if OpenDialog1.Execute then
  142.     begin
  143.         MemoCoordinates.Clear;
  144.         PathToFile := OpenDialog1.FileName;
  145.         try
  146.             AssignFile(FileInput, PathToFile);
  147.             Reset(FileInput);
  148.  
  149.             while not Eof(FileInput) do
  150.             begin
  151.                 Readln(FileInput, String1);
  152.                 MemoCoordinates.Lines.Add(String1);
  153.             end;
  154.  
  155.             CloseFile(FileInput);
  156.         except
  157.             ShowMessage(ErrorDuringInputOccured);
  158.         end;
  159.     end;
  160. end;
  161.  
  162. procedure TFormMain.NTaskClick(Sender: TObject);
  163. begin
  164.     MyMessageBoxInfo(FormMain, 'Задание', 'На плоскости заданы n точек своими координатами. ' +
  165.     'Найти уравнение прямой, которой принадлежит наибольшее число данных точек.');
  166. end;
  167.  
  168. end.
  169.  
  170.  
  171.  
  172.  
  173.  
  174.  
  175.  
  176.  
  177.  
  178. unit laba_6_3_UnitCalculateBestLine;
  179.  
  180. interface
  181.  
  182. uses
  183.     Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  184.     Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls, Math, laba_6_3_UnitTypes;
  185.  
  186. function GetKAndB(const ArrOfCoords: TArrCoord; var LineIsVertical: Boolean) : TKAndB;
  187.  
  188. implementation
  189.  
  190. function GetKAndB(const ArrOfCoords: TArrCoord; var LineIsVertical: Boolean) : TKAndB;
  191. var
  192.     KAndB: TKAndB;
  193.     Best_K, K, DY, Best_B, B, DX, X1, Y1: Single;
  194.     CountDots, MaxCountDots, i, j, iter3: Integer;
  195.     TempLineIsVertical: Boolean;
  196.  
  197. begin
  198.     Best_K := 0;
  199.     Best_B := 0;
  200.     MaxCountDots := 0;
  201.     K := 0;
  202.  
  203.     for i := 0 to High(ArrOfCoords) do
  204.         for j := i + 1 to High(ArrOfCoords) do
  205.         begin
  206.             x1 := ArrOfCoords[i].X;
  207.             y1 := ArrOfCoords[i].Y;
  208.             dx := ArrOfCoords[j].X - x1;
  209.             dy := ArrOfCoords[j].Y - y1;
  210.             TempLineIsVertical := DX = 0;
  211.             if not TempLineIsVertical then
  212.             begin
  213.                 k := dy / dx;
  214.                 b := y1 - x1 * dy / dx;
  215.             end
  216.             else
  217.                 b := x1;
  218.  
  219.             CountDots := 2;
  220.  
  221.             for iter3 := j + 1 to High(ArrOfCoords) do
  222.                 if TempLineIsVertical then
  223.                 begin
  224.                     if (ArrOfCoords[iter3].X = b) then
  225.                         Inc(countDots);
  226.                 end
  227.                 else
  228.                     if (ArrOfCoords[iter3].Y = ArrOfCoords[iter3].X * k + b) then
  229.                         Inc(countDots);
  230.             if CountDots > MaxCountDots then
  231.             begin
  232.                 MaxCountDots := CountDots;
  233.  
  234.                 LineIsVertical := TempLineIsVertical;
  235.                 best_b := b;
  236.                 best_k := k;
  237.             end;
  238.         end;
  239.  
  240.     KAndB.K := Best_K;
  241.     KAndB.B := Best_B;
  242.     Result := KAndB;
  243. end;
  244.  
  245. end.
  246.  
  247.  
  248.  
  249.  
  250.  
  251.  
  252.  
  253.  
  254. unit laba_6_3_UnitGraphic;
  255.  
  256. interface
  257.  
  258. uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  259.   Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls, Math, laba_6_3_UnitTypes;
  260.  
  261. procedure DrawGraphicWithDots(ArrCoords: TArrCoord);
  262. procedure DrawLineVertical(const XConstant: Single);
  263. procedure DrawLineNotVertical(const K, B: Single);
  264. procedure SetupCanvas();
  265.  
  266. implementation
  267.  
  268. uses laba_6_3_UnitMainForm;
  269.  
  270. const
  271.     WidthOfGraphicLine = 1;
  272.     WidthOfLine = 2;
  273.     WidthOfDots = 4;
  274.     BorderOfForm = 10;
  275.     BorderOfCanvas = 20;
  276.  
  277.     ColorOfAxis = clBlack;
  278.     BrushOfAxis = clWhite;
  279.     ColorOfDots = clBlue;
  280.     ColorOfLine = clRed;
  281.  
  282. var
  283.     PixelsPerOne: Byte;
  284.     XCenter, YCenter, Furthest: SmallInt;
  285.  
  286. procedure DrawAxis(); forward;
  287. function GetFurthestCoordinate(ArrCoords: TArrCoord): SmallInt; forward;
  288. procedure DrawDots(ArrCoords: TArrCoord); forward;
  289. procedure DrawCircle(XCentre, YCentre, Radius: SmallInt); forward;
  290.  
  291. procedure DrawGraphicWithDots(ArrCoords: TArrCoord);
  292. begin
  293.     with FormMain do
  294.     with ImageCanvas do
  295.     begin
  296.         with Canvas do
  297.         begin
  298.             Pen.Color := clWhite;
  299.             Brush.Color := clWhite;
  300.             Pen.Width := 1;
  301.             Rectangle(0, 0, Width, Height);
  302.         end;
  303.  
  304.         Furthest := GetFurthestCoordinate(ArrCoords);
  305.         PixelsPerOne := Trunc((Width - 2 * BorderOfCanvas) / (2 * Furthest + 3));
  306.  
  307.         DrawAxis();
  308.         DrawDots(ArrCoords);
  309.     end;
  310. end;
  311.  
  312. procedure SetupCanvas();
  313. begin
  314.     with FormMain do
  315.     with ImageCanvas do
  316.     begin
  317.         Left := MultPixels(BorderOfForm) + BorderWidth;
  318.         Top := MultPixels(BorderOfForm) + BorderWidth;
  319.         Height := FormMain.ClientHeight - 2 * (MultPixels(BorderOfForm) + BorderWidth);
  320.         Width := Height;
  321.  
  322.         XCenter := Round(Width / 2);
  323.         YCenter := Round(Height / 2);
  324.     end;
  325. end;
  326.  
  327. procedure DrawDots(ArrCoords: TArrCoord);
  328. var
  329.     Coord: TPairOfSmallInt;
  330.     TempWidthOfDots: Byte;
  331.  
  332. begin
  333.     With FormMain do
  334.     With ImageCanvas do
  335.     With Canvas do
  336.     begin
  337.         TempWidthOfDots := MultPixels(WidthOfDots);
  338.  
  339.         for Coord in ArrCoords do
  340.         begin
  341.             Pen.Color := ColorOfDots;
  342.             Brush.Color := ColorOfDots;
  343.             Pen.Width := 1;
  344.  
  345.             DrawCircle(XCenter + Coord.X * PixelsPerOne, YCenter - Coord.Y * PixelsPerOne, TempWidthOfDots)
  346.         end;
  347.     end;
  348. end;
  349.  
  350. procedure DrawLineVertical(const XConstant: Single);
  351. begin
  352.     With FormMain do
  353.     With ImageCanvas do
  354.     With Canvas do
  355.     begin
  356.         Pen.Color := ColorOfLine;
  357.         Pen.Width := MultPixels(WidthOfLine);
  358.  
  359.         MoveTo(Trunc(XCenter + XConstant * PixelsPerOne), 0);
  360.         LineTo(Trunc(XCenter + XConstant * PixelsPerOne), Height);
  361.     end;
  362. end;
  363.  
  364. procedure DrawLineNotVertical(const K, B: Single);
  365. var
  366.     XTemp: Single;
  367.  
  368. begin
  369.     With FormMain do
  370.     With ImageCanvas do
  371.     With Canvas do
  372.     begin
  373.         Pen.Color := ColorOfLine;
  374.         Pen.Width := MultPixels(WidthOfLine);
  375.  
  376.         XTemp := XCenter - (Furthest + 5) * PixelsPerOne;
  377.         MoveTo(Trunc(XTemp), Trunc(YCenter - (-(Furthest + 5) * K + B) * PixelsPerOne));
  378.         XTemp := XCenter + (Furthest + 5) * PixelsPerOne;
  379.         LineTo(Trunc(XTemp), Trunc(YCenter - ((Furthest + 5) * K + B) * PixelsPerOne));
  380.     end;
  381. end;
  382.  
  383. procedure DrawCircle(XCentre, YCentre, Radius: SmallInt);
  384. begin
  385.     With FormMain.ImageCanvas.Canvas do
  386.         Ellipse(XCentre - Radius, YCentre - Radius, XCentre + Radius, YCentre + Radius);
  387. end;
  388.  
  389. procedure DrawAxis();
  390. var
  391.     i: ShortInt;
  392.     ScaleOfGraphic, TempWidthOfGraphicLine: Byte;
  393.     XTemp, YTemp, ArrowSize: SmallInt;
  394.  
  395. begin
  396.     With FormMain do
  397.     With ImageCanvas do
  398.     With Canvas do
  399.         begin
  400.             TempWidthOfGraphicLine := MultPixels(WidthOfGraphicLine);
  401.  
  402.             Pen.Color := ColorOfAxis;
  403.             Brush.Color := BrushOfAxis;
  404.             Pen.Width := TempWidthOfGraphicLine;
  405.  
  406.             // Arrows
  407.                 ArrowSize := 5 * TempWidthOfGraphicLine;
  408.                 // Y axis
  409.                 MoveTo(XCenter, Height - MultPixels(BorderOfCanvas));
  410.                 YTemp := MultPixels(BorderOfCanvas);
  411.                 LineTo(XCenter, YTemp);
  412.                 LineTo(XCenter - ArrowSize, YTemp + ArrowSize);
  413.                 MoveTo(XCenter, YTemp);
  414.                 LineTo(XCenter + ArrowSize, YTemp + ArrowSize);
  415.                 // X axis
  416.                 MoveTo(MultPixels(BorderOfCanvas), YCenter);
  417.                 XTemp := Width - MultPixels(BorderOfCanvas);
  418.                 LineTo(XTemp, YCenter);
  419.                 LineTo(XTemp - ArrowSize, YCenter + ArrowSize);
  420.                 MoveTo(XTemp, YCenter);
  421.                 LineTo(XTemp - ArrowSize, YCenter - ArrowSize);
  422.  
  423.             if Furthest > 12 then
  424.                 if Furthest > 40 then
  425.                     if Furthest > 70 then
  426.                         ScaleOfGraphic := 20
  427.                     else
  428.                         ScaleOfGraphic := 10
  429.                 else
  430.                     ScaleOfGraphic := 5
  431.             else
  432.                 ScaleOfGraphic := 1;
  433.  
  434.             // Zero
  435.             TextOut(XCenter + TempWidthOfGraphicLine,
  436.                         YCenter + TempWidthOfGraphicLine, '0');
  437.  
  438.             for i := -Furthest to Furthest do
  439.                 if (i <> 0) and (i mod ScaleOfGraphic = 0) then
  440.                 begin
  441.                     // Y axis
  442.                     XTemp := XCenter + TempWidthOfGraphicLine;
  443.                     YTemp := YCenter - i * PixelsPerOne;
  444.                     TextOut(XTemp, YTemp, IntToStr(i));
  445.                     MoveTo(XCenter - 2 * TempWidthOfGraphicLine, YTemp);
  446.                     LineTo(XCenter + 2 * TempWidthOfGraphicLine, YTemp);
  447.  
  448.                     // X axis
  449.                     XTemp := XCenter + i * PixelsPerOne;
  450.                     YTemp := YCenter + TempWidthOfGraphicLine;
  451.                     TextOut(XTemp, YTemp, IntToStr(i));
  452.                     MoveTo(XTemp, YCenter - 2 * TempWidthOfGraphicLine);
  453.                     LineTo(XTemp, YCenter + 2 * TempWidthOfGraphicLine);
  454.                 end;
  455.         end;
  456. end;
  457.  
  458. function GetFurthestCoordinate(ArrCoords: TArrCoord): SmallInt;
  459. var
  460.     FurthestLocal: SmallInt;
  461.     Coord: TPairOfSmallInt;
  462.  
  463. begin
  464.     FurthestLocal := 0;
  465.     for Coord in ArrCoords do
  466.     begin
  467.         FurthestLocal := Max(FurthestLocal, Abs(Coord.X));
  468.         FurthestLocal := Max(FurthestLocal, Abs(Coord.Y));
  469.     end;
  470.     Result := FurthestLocal;
  471. end;
  472.  
  473. end.
  474.  
  475.  
  476.  
  477.  
  478.  
  479.  
  480.  
  481.  
  482. unit laba_6_3_UnitTypes;
  483.  
  484. interface
  485.  
  486. type
  487.     TArrStr = Array of String;
  488.  
  489.     TPairOfSmallInt = Record
  490.         X, Y: SmallInt;
  491.     End;
  492.  
  493.     TKAndB = Record
  494.         K: Single;
  495.         B: Single;
  496.     End;
  497.  
  498.     TArrCoord = Array of TPairOfSmallInt;
  499.  
  500. implementation
  501.  
  502. end.
Advertisement
Add Comment
Please, Sign In to add comment