![]() |
|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
||||
|
||||
![]() есть луч(красный) и много отрезков, если отрезок пересекает луч то он одного цвета(например зеленый), если НЕ пересекает то другого цвета(например черный)
![]() я сделал так Код:
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
|
|||
|
|||
![]() Попиксельно проверить отрезок. Если пиксель.x>=luch.x и если пиксель.у=luch.y то меняем цвет на зеленый, если нет то оставляем черным.
Это так, теоретически. |
#3
|
||||
|
||||
![]() короче здесь нашел ответ и написал так:
Код:
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
|
|||
|
|||
![]() Вообще-то задача состоит из 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
|
||||
|
||||
![]() я еще вот это спрашивал
![]() Цитата:
вот то что я еще спросил я все таки сделал, я тупо копировал отрезок далее до краев формы но у меня получился просто здоровый огромный код Код:
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
|
|||
|
|||
![]() Код:
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
|
|||
|
|||
![]() http://s002.radikal.ru/i198/1002/d0/47dbca0979df.jpg - приблизительный рисунок.
|