| 
| 
 | Вопрос # 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);begini:=1;tr:=True;rec:=False;cer:=False;end; procedure TForm1.N8Click(Sender: TObject);begini:=1;tr:=False;rec:=True;cer:=False;end; procedure TForm1.N9Click(Sender: TObject);begini:=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         beginForm1.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         beginForm1.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. И все в "шоколаде". Правда надо добавить проверку когда три (получается треугольник) или все четыре точки лежат на одной прямой (тогда просто отрезок). |  Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте. |