Определить принадлежит ли точка выпуклому многогольнику, в данном случае - пятиугольнику. Алгоритм основан на проверке положения точки относительно каждой из сторон пятиугольника.
Предположим:
lp1,lp2 – точки задающие прямую(сторону)
tp – точка, положение которой выясняем.
Для определения положения необходимо построить два вектора:
из lp1 в lp2
из lp1 в tp
Далее найдем векторное произведение этих двух векторов, если оно положительно то точка слева от прямой, если отрицательно – справа, если равно 0 то вектора параллельны, следовательно, точка лежит на прямой.
Далее найдем векторное произведение этих двух векторов, если оно положительно то точка слева от прямой, если отрицательно – справа, если равно 0 то вектора параллельны, следовательно, точка лежит на прямой.
Векторное произведение двух векторов v1 × v2 = v1 x*v2 y - v1 y*v2 x.
Знак векторного произведения зависит от знака синуса угла между векторами, которым мы собственно и пользуемся чтобы определить относительное положение точки.
unit Unit1; {$mode objfpc}{$H+} interface uses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, Buttons, ExtCtrls, StdCtrls; type { TForm1 } TForm1 = class(TForm) BitBtn1: TBitBtn; BitBtn2: TBitBtn; Label1: TLabel; Label2: TLabel; Label3: TLabel; PaintBox1: TPaintBox; procedure BitBtn1Click(Sender: TObject); procedure BitBtn2Click(Sender: TObject); procedure PaintBox1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); private { private declarations } x1,y1,x2,y2,x3,y3,x4,y4,x5,y5 :Integer; Pointx,Pointy : Integer ; public { public declarations } end; var Form1: TForm1; implementation {$R *.lfm} { TForm1 } procedure TForm1.BitBtn1Click(Sender: TObject); begin x1:=40*5; y1:=40*5; x2:=60*5; y2:=20*5; x3:=80*5; y3:=40*5; //Определение координат пятиугольника по x и y x4:=70*5; y4:=60*5; x5:=50*5; y5:=60*5; //Построение пятиугольника Polygon'ом PaintBox1.Canvas.Brush.Color := clWhite; PaintBox1.Canvas.Polygon([Point(x1,y1), Point(x2,y2), Point(x3,y3), Point(x4,y4), Point(x5,y5)]); end; procedure TForm1.BitBtn2Click(Sender: TObject); // Кнопка "Очистить" очищает экран begin PaintBox1.Canvas.Brush.Color:=clDefault; //Цвет заливки PaintBox1.Canvas.Clear; //Очистка PaintBox1.Canvas.Brush.Color := clWhite; // Построение многоугоьника белым цветом //Построение пятиугольника Polygon'ом PaintBox1.Canvas.Polygon([Point(x1,y1), Point(x2,y2), Point(x3,y3), Point(x4,y4), Point(x5,y5)]); end; procedure TForm1.PaintBox1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin Pointx:= X; //Передаем параметры клика мышью X, Y процедуры MouseDown переменнным. Pointy:= Y; if((((x2-x1)*(Pointy-y1)-(y2-y1)*(Pointx-x1))>=0) and (((x1-x5)*(Pointy-y5)-(y1-y5)*(Pointx-x5))>=0) and (((x5-x4)*(Pointy-y4)-(y5-y4)*(Pointx-x4))>=0) and (((x4-x3)*(Pointy-y3)-(y4-y3)*(Pointx-x3))>=0) and (((x3-x2)*(Pointy-y2)-(y3-y2)*(Pointx-x2))>=0)) //Проверка лежит ли точка слева от каждой из прямых,если да то then begin label2.Caption:='YES' ; //Выводим ответ ДА PaintBox1.Canvas.Pen.Color := clGreen; //Т.к внутри п-ка то рисуем зеленым цветом PaintBox1.Canvas.Pen.Width:=5; PaintBox1.Canvas.Line(Pointx,Pointy,Pointx,Pointy); PaintBox1.Canvas.Pen.Width:=1; end else begin label2.Caption:='NO'; //Выводим ответ нет,если хотя бы 1 условие не выполняется PaintBox1.Canvas.Pen.Color := clRed; //Вне п-ка рисуем точку красной PaintBox1.Canvas.Pen.Width:=5; PaintBox1.Canvas.Line(Pointx,Pointy,Pointx,Pointy); PaintBox1.Canvas.Pen.Width:=1; PaintBox1.Canvas.Pen.Color := clGreen; //Возвращаем зеленый цвет end; end; end.
Прикрепленный файл | Размер |
---|---|
Mnogougolnik1.zip | 1.04 Мб |