|
Вопрос # 5 152/ вопрос открыт / |
|
Приветствую, уважаемые эксперты!
При построении четырехугольника возникла проблема, в некоторых случаях он вырисовывается в виде "конфеты". в чем может быть проблема? Для изображения фигур используется компонент Image. Смотреть код жирным шрифтом снизу.
Приложение: Переключить в обычный режим- unit Unit1;
-
- interface
-
- uses
- Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
- Dialogs, ExtCtrls, Menus;
-
- type
- TForm1 = class(TForm)
- Image1: TImage;
- MainMenu1: TMainMenu;
- N2: TMenuItem;
- N1: TMenuItem;
- N3: TMenuItem;
- N4: TMenuItem;
- N5: TMenuItem;
- N6: TMenuItem;
- N7: TMenuItem;
- N8: TMenuItem;
- N9: TMenuItem;
- procedure FormCreate(Sender: TObject);
- procedure N7Click(Sender: TObject);
- procedure N8Click(Sender: TObject);
- procedure N9Click(Sender: TObject);
- procedure Image1MouseDown(Sender: TObject; Button: TMouseButton;
- Shift: TShiftState; X, Y: Integer);
- private
- { Private declarations }
- public
- { Public declarations }
- end;
-
- var
- Form1: TForm1;
- xx,yy:integer;
- tr, rec, cer:boolean;
- Treangl:array[1..3,1..2] of integer;
- Rectangl:array[1..4,1..2] of integer;
- Elips:array[1..3,1..2] of integer;
- i:integer;
-
- implementation
-
- {$R *.dfm}
-
- procedure TForm1.FormCreate(Sender: TObject);
- begin
- xx:=round(Image1.Width/2);
- yy:=round(Image1.Height/2);
- Form1.Image1.Canvas.MoveTo(0,yy);
- Form1.Image1.Canvas.LineTo(Form1.Image1.Width,yy);//OX
- Form1.Image1.Canvas.MoveTo(xx,0);
- Form1.Image1.Canvas.LineTo(xx, Form1.Image1.Height);//OY
- //
- Form1.Image1.Canvas.MoveTo(Form1.Image1.Width,yy);
- Form1.Image1.Canvas.LineTo(Form1.Image1.Width-10, yy-7);
- Form1.Image1.Canvas.MoveTo(Form1.Image1.Width,yy);
- Form1.Image1.Canvas.LineTo(Form1.Image1.Width-10, yy+7);
- //
- Form1.Image1.Canvas.MoveTo(xx,0);
- Form1.Image1.Canvas.LineTo(xx-7,15);
- Form1.Image1.Canvas.MoveTo(xx,0);
- Form1.Image1.Canvas.LineTo(xx+7,15);
- //
- Image1.Canvas.TextOut(xx-20, yy+10, '0,0');
- Image1.Canvas.TextOut(2*xx-10, yy+15, 'X');
- Image1.Canvas.TextOut(xx-15,5,'Y');
- tr:=False;
- rec:=False;
- cer:=False;
- end;
-
- procedure TForm1.N7Click(Sender: TObject);
- begin
- i:=1;
- tr:=True;
- rec:=False;
- cer:=False;
- end;
-
- procedure TForm1.N8Click(Sender: TObject);
- begin
- i:=1;
- tr:=False;
- rec:=True;
- cer:=False;
- end;
-
- procedure TForm1.N9Click(Sender: TObject);
- begin
- i:=1;
- tr:=False;
- rec:=False;
- cer:=True;
- end;
-
- procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
- Shift: TShiftState; X, Y: Integer);
- begin
- if tr=true then
- begin
- if i<=3 then
- begin
- Treangl[i,1]:=x;
- Treangl[i,2]:=y;
- if i=3 then
- begin
- Form1.Image1.Canvas.MoveTo(Treangl[1,1], Treangl[1,2]);
- Form1.Image1.Canvas.LineTo(Treangl[2,1], Treangl[2,2]);
- Form1.Image1.Canvas.LineTo(Treangl[3,1], Treangl[3,2]);
- Form1.Image1.Canvas.LineTo(Treangl[1,1], Treangl[1,2]);
- end;
- i:=i+1;
- end;
- end;
-
- [B]if rec=true then
- begin
- if i<=4 then
- begin
- Rectangl[i,1]:=x;
- Rectangl[i,2]:=y;
- if i=4 then
- begin
- Form1.Image1.Canvas.MoveTo(Rectangl[1,1], Rectangl[1,2]);
- Form1.Image1.Canvas.LineTo(Rectangl[2,1], Rectangl[2,2]);
- Form1.Image1.Canvas.LineTo(Rectangl[3,1], Rectangl[3,2]);
- Form1.Image1.Canvas.LineTo(Rectangl[4,1], Rectangl[4,2]);
- Form1.Image1.Canvas.LineTo(Rectangl[1,1], Rectangl[1,2]);
-
- end;
- i:=i+1;
- end;
- end;
- end;[/B]
-
-
- end.
 |
Вопрос задала: Nostalgia (статус: Посетитель)
Вопрос отправлен: 4 апреля 2011, 17:16
Состояние вопроса: открыт, ответов: 1.
|
Ответ #1. Отвечает эксперт: Егор
Здравствуйте, Nostalgia!
мда... код - жесть...
вообще-то, вполне можно было выложить лишь процедуру TForm1.Image1MouseDown и объявление переменных. да и саму процедуру можно было порезать.
if rec=true then
эта конструкция ужасна. не надо так писать!
вот как надо:
if rec then
посмотрим код
var
...
tr, rec, cer:boolean;
Rectangl:array[1..4,1..2] of integer;
i:integer;
...
procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
...
if rec then
begin
if i<=4 then
begin
Rectangl[i,1]:=x;
Rectangl[i,2]:=y;
if i=4 then
begin
Form1.Image1.Canvas.MoveTo(Rectangl[1,1], Rectangl[1,2]);
Form1.Image1.Canvas.LineTo(Rectangl[2,1], Rectangl[2,2]);
Form1.Image1.Canvas.LineTo(Rectangl[3,1], Rectangl[3,2]);
Form1.Image1.Canvas.LineTo(Rectangl[4,1], Rectangl[4,2]);
Form1.Image1.Canvas.LineTo(Rectangl[1,1], Rectangl[1,2]);
end;
i:=i+1;
end;
end;
end;
ну и ответ на "в чем может быть проблема?"
смотря как щёлкать мышью. если щёлкать "правильно", по углам прямоугольника, получим прямоугольник. если щёлкать по "конфете", её и получим.
 |
Ответ отправил: Егор (статус: 10-ый класс)
Время отправки: 4 апреля 2011, 18:28
Оценка за ответ: 1
|
Мини-форум вопроса
Всего сообщений: 9; последнее сообщение — 4 апреля 2011, 21:04; участников в обсуждении: 3.
|
Nostalgia (статус: Посетитель), 4 апреля 2011, 18:57 [#1]:
я понимаю..
нужно чтоб даже если щелкать по "конфете" вырисовывался прямоугольник...
что для этого нужно??
могу скинуть весь архив чтоб было нагляднее...
|
|
Егор (статус: 10-ый класс), 4 апреля 2011, 19:04 [#2]:
нужен именно прямоугольник (с прямыми углами) или четырёхугольник (с любыми углами)?
Цитата (Nostalgia):
могу скинуть весь архив чтоб было нагляднее...
НЕЕЕЕТ!!! не надо!
))
Опасайтесь багов в приведенном выше коде; я только доказал корректность, но не запускал его.
— Donald E. Knuth.
|
|
Егор (статус: 10-ый класс), 4 апреля 2011, 19:20 [#3]:
почему единица? на вопрос ответ дан.
Опасайтесь багов в приведенном выше коде; я только доказал корректность, но не запускал его.
— Donald E. Knuth.
|
|
Nostalgia (статус: Посетитель), 4 апреля 2011, 19:28 [#4]:
нужен прямоугольник с любыми углами
|
|
Егор (статус: 10-ый класс), 4 апреля 2011, 19:37 [#5]:
пусть минай помогает. он тоже единицы за ответы обожает.
или вадим. он из одессы, земляк.
Опасайтесь багов в приведенном выше коде; я только доказал корректность, но не запускал его.
— Donald E. Knuth.
|
|
Nostalgia (статус: Посетитель), 4 апреля 2011, 19:38 [#6]:
каков ответ таков...
я так чувствую что мне никто здесь не поможет(((((((
|
|
Nostalgia (статус: Посетитель), 4 апреля 2011, 19:39 [#6]:
каков ответ таков...
я так чувствую что мне никто здесь не поможет(((((((
|
|
Мережников Андрей (статус: Абитуриент), 4 апреля 2011, 20:18 [#7]:
Цитата (Nostalgia):
нужен прямоугольник с любыми углами
прямоугольник, по определению, может быть только с ПРЯМЫМИ углами!
Самый простой вариант - по кликам мыши определять только две диагональные вершины, а дальше уже достраивать прямоугольник по ним, правда расположен он будет только горизонтально (вертикально), но не под произвольным углом к экрану. А если самостоятельно определять координаты всех вершин, то, уж извините, что "нащелкали", то и получите.
|
|
Nostalgia (статус: Посетитель), 4 апреля 2011, 20:27 [#8]:
прошу прощения, четырехугольник...
|
|
Мережников Андрей (статус: Абитуриент), 4 апреля 2011, 21:04 [#9]:
понятно. Тогда следующий алгоритм - сначала принимаем координаты вершин, затем сортируем, чтобы не было пересечений, а затем уже строим четырехугольник. Самое сложное из этого сортировка. Но здесь уже должна помочь математика. Уравнения прямых по двум точкам составлять умеем? Проверяем на взаимное пересечение отрезки (x1,y1)-(x2,y2) и (x3,y3)-(x4,y4), а также отрезки (x1,y1)-(x4,y4) и (x2,y2)-(x3,y3). Если есть пересечение первой пары отрезков, то меняем местами координаты, например, вершин 2 и 3. Если пересечение второй пары отрезков, то вершины 3 и 4. И все в "шоколаде". Правда надо добавить проверку когда три (получается треугольник) или все четыре точки лежат на одной прямой (тогда просто отрезок).
|
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|