Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 21.02.2010, 14:22
Аватар для SerginhoLD
SerginhoLD SerginhoLD вне форума
Новичок
 
Регистрация: 19.11.2009
Сообщения: 73
Репутация: 12
Восклицание пересекает ли отрезок луч?

есть луч(красный) и много отрезков, если отрезок пересекает луч то он одного цвета(например зеленый), если НЕ пересекает то другого цвета(например черный)


я сделал так
Код:
if (luch.x <= a.x) and (luch.x <= b.x) then   // если точка начала луча слева от точек начала и конца отрезка то
    begin
      if ((a.y <= luch.y) and (luch.y <= b.y))       // если точка начала отрезка выше луча и точка конца ниже
        or ((b.y <= luch.y) and (luch.y <= a.y))    // или наоборот
      then line(a,b,cllime)               // то рисуем зеленым
      else line(a,b,clblack);             // иначе черным
    end

но есть проблема, например когда начало отрезка слева от точки луча и конец справа

при этом отрезок может пересекать луч, а может и НЕ пересекать

как здесь реализовать проверку на пересечение?
Ответить с цитированием
  #2  
Старый 21.02.2010, 16:20
malekskv malekskv вне форума
Прохожий
 
Регистрация: 13.11.2009
Сообщения: 44
Репутация: 14
По умолчанию

Попиксельно проверить отрезок. Если пиксель.x>=luch.x и если пиксель.у=luch.y то меняем цвет на зеленый, если нет то оставляем черным.

Это так, теоретически.
Ответить с цитированием
  #3  
Старый 21.02.2010, 16:26
Аватар для SerginhoLD
SerginhoLD SerginhoLD вне форума
Новичок
 
Регистрация: 19.11.2009
Сообщения: 73
Репутация: 12
По умолчанию

короче здесь нашел ответ и написал так:
Код:
function peresechenie(p1,p2,p3,p4: Points): boolean;
  // p1 - начало 1ого отрезка, p2 - конец 1ого отрезка
  // p3 - начало 2ого отрезка, p4 - конец 2ого отрезка
var ua,ub: double;
begin                                         
  ua:=((p4.x-p3.x)*(p1.y-p3.y)-(p4.y-p3.y)*(p1.x-p3.x))/((p4.y-p3.y)*(p2.x-p1.x)-(p4.x-p3.x)*(p2.y-p1.y));
  ub:=((p2.x-p1.x)*(p1.y-p3.y)-(p2.y-p1.y)*(p1.x-p3.x))/((p4.y-p3.y)*(p2.x-p1.x)-(p4.x-p3.x)*(p2.y-p1.y));
  // если 'ua' и 'ub' принадлежат [0,1] то отрезки пересекаются
  if ((ua>=0) and (ua<=1)) and ((ub>=0) and (ub<=1)) then result:=true else result:=false;
end;


-----------------------------------------------------------------------

Теперь еще есть вопрос, как через две точки провести прямую? именно прямую а не линию, чтобы от точек было продолжение до конца формы, по идее можно это сделать по пиксельно, но может еще какой-нить вариант есть?

Последний раз редактировалось SerginhoLD, 21.02.2010 в 17:03.
Ответить с цитированием
  #4  
Старый 21.02.2010, 18:22
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,087
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Вообще-то задача состоит из 2-х частей.
Часть первая - чистая математика.
Тебе надо вычислить коэф. уравнений y = ax + b для луча и отрезка. Далее берем и приравниваем уравнения, т.е. y1 = y2 => a1x+ b1 = a2x + b2. Решение этого уравнения есть точка пересечения. Ну и останется проверить, что эта точка находится в пределах отрезка и луча - это простые if'ы по координате x.

Рисовать можно с помощью следующего кода:
Код:
With Form1.Canvas Do
  Begin
    Pen.Color := clBlack;
    MoveTo(x1,y1);
    LineTo(x2,y2);
  End;

И не забывай, что экранный y направлен вниз, т.е. (0,0) находится в левом верхнем углу экрана.
Ответить с цитированием
  #5  
Старый 21.02.2010, 19:35
Аватар для SerginhoLD
SerginhoLD SerginhoLD вне форума
Новичок
 
Регистрация: 19.11.2009
Сообщения: 73
Репутация: 12
По умолчанию

я еще вот это спрашивал
Цитата:
Сообщение от SerginhoLD
Теперь еще есть вопрос, как через две точки провести прямую? именно прямую а не линию, чтобы от точек было продолжение до конца формы, по идее можно это сделать по пиксельно, но может еще какой-нить вариант есть?
---

вот то что я еще спросил я все таки сделал, я тупо копировал отрезок далее до краев формы
но у меня получился просто здоровый огромный код
Код:
procedure pryamaya(p1,p2:Points; mycolor:TColor);// рисуем прямую через две точки
var ax,ay,bx,by,prx,pry: integer; // экранные координаты точек и разница в пикселях между точками                               
begin
  otrezok(p1,p2,mycolor); // это своя процедура рисования отрезка через две точки
  ax:=xs(p1.x); bx:=xs(p2.x); ay:=ys(p1.y); by:=ys(p2.y); // xs,ys - свои процедуры перевода точек в экранные координаты
  prx:=abs(bx-ax); pry:=abs(by-ay);
  if (p1.x < p2.x) and (p1.y > p2.y) then
  begin // если p1 выше и левее p2 (это на обычной плоскости)
    while ax > 0 do
    begin // продолжаем наш отрезок влево
      Form_serginho_geometry.Canvas.MoveTo(ax,ay);
      ax:=ax-prx; ay:=ay-pry;
      Form_serginho_geometry.Canvas.LineTo(ax,ay);
    end;
    while bx < Form_serginho_geometry.ClientWidth do
    begin // продолжаем наш отрезок вправо
      Form_serginho_geometry.Canvas.MoveTo(bx,by);
      bx:=bx+prx; by:=by+pry;
      Form_serginho_geometry.Canvas.LineTo(bx,by);
    end;
  end else                                               // и т.д. и т.п.
  if (p1.x > p2.x) and (p1.y > p2.y) then
  begin // если p1 выше и правее p2
    while ax < Form_serginho_geometry.ClientWidth do
    begin
      Form_serginho_geometry.Canvas.MoveTo(ax,ay);
      ax:=ax+prx; ay:=ay-pry;
      Form_serginho_geometry.Canvas.LineTo(ax,ay);
    end;
    while bx > 0 do
    begin
      Form_serginho_geometry.Canvas.MoveTo(bx,by);
      bx:=bx-prx; by:=by+pry;
      Form_serginho_geometry.Canvas.LineTo(bx,by);
    end;
  end else
  if (p1.x > p2.x) and (p1.y < p2.y) then
  begin // если p1 ниже и правее p2
    while ax < Form_serginho_geometry.ClientWidth do
    begin
      Form_serginho_geometry.Canvas.MoveTo(ax,ay);
      ax:=ax+prx; ay:=ay+pry;
      Form_serginho_geometry.Canvas.LineTo(ax,ay);
    end;
    while bx > 0 do
    begin
      Form_serginho_geometry.Canvas.MoveTo(bx,by);
      bx:=bx-prx; by:=by-pry;
      Form_serginho_geometry.Canvas.LineTo(bx,by);
    end;
  end else
  if (p1.x < p2.x) and (p1.y < p2.y) then
  begin // если p1 ниже и левее p2;
    while ax > 0 do
    begin
      Form_serginho_geometry.Canvas.MoveTo(ax,ay);
      ax:=ax-prx; ay:=ay+pry;
      Form_serginho_geometry.Canvas.LineTo(ax,ay);
    end;
    while bx < Form_serginho_geometry.ClientWidth do
    begin
      Form_serginho_geometry.Canvas.MoveTo(bx,by);
      bx:=bx+prx; by:=by-pry;
      Form_serginho_geometry.Canvas.LineTo(bx,by);
    end;
  end;
end;
Мож кто-нить посоветует че попроще, всмысле поменьше ?

Последний раз редактировалось SerginhoLD, 21.02.2010 в 19:51.
Ответить с цитированием
  #6  
Старый 21.02.2010, 20:52
malekskv malekskv вне форума
Прохожий
 
Регистрация: 13.11.2009
Сообщения: 44
Репутация: 14
По умолчанию

Код:
n,k:Tpoint;   // n - первая точка, k - вторая 
Angle:real; // Это будет тангенс кое какого угла..


Angle:=(k.y-n.y)/(k.X-n.x); //вычисляем тангенс.
Canvas.MoveTo(0, Round(k.y-k.X*Angle)); //(перемешаемся..)
Canvas.LineTo(Form6.Width, Round(Form6.Width*Angle-k.X*Angle+k.y)) // ну и собственно рисуем

Если сделать нормальный рисуночек в тетрадке то можно все сделать, через подобие треугольников...
Ответить с цитированием
  #7  
Старый 21.02.2010, 21:04
malekskv malekskv вне форума
Прохожий
 
Регистрация: 13.11.2009
Сообщения: 44
Репутация: 14
По умолчанию

http://s002.radikal.ru/i198/1002/d0/47dbca0979df.jpg - приблизительный рисунок.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 09:54.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025