Модераторы: Poseidon, Snowy, bems, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Пересечение прямых 
:(
    Опции темы
Sheff
Дата 4.12.2003, 21:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник Клуба
Сообщений: 503
Регистрация: 25.3.2002
Где: Зеленоград

Репутация: нет
Всего: 3



Люди, допустим у меня есть две прямые, известны их координаты, как найти координаты точки их пересечения, я решил эту задачу геометрически, но вышел слишком грамоздкий ответ, может как полегче можно ?


--------------------
--------------------------
Шеф всегда прав :)
PM MAIL WWW ICQ   Вверх
Полудненко Олег
Дата 5.12.2003, 18:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Українець
**


Профиль
Группа: Участник...
Сообщений: 556
Регистрация: 13.8.2003

Репутация: 1
Всего: -11



Находим уравнения прямой для обоих прямых, а именно k и b, далее приняв значения по y равными находим точку пересечения по x, подставляем точку пересечения по оси абсцисс в любое из двух уравнений прямых и подсчитываем точку пересечения по y.
PM MAIL   Вверх
Dmitry V.Abramov
Дата 5.12.2003, 21:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 177
Регистрация: 30.9.2003
Где: Saint-Petersburg

Репутация: 5
Всего: 4



Нечто древнее и не очень оптимальное, но рабочее. Есть простор для оптимизации.

Код
interface

type
 TIntersectStatus = (liNone, liParallel, liCombine, liEqual, liIntersect, liDot);

function LineIntersect(const A, B, C, D: TPoint; var I: TPoint): TIntersectStatus;
// Отрезок AB пересекает CD в точке I

implementation

function LineIntersect(const A, B, C, D: TPoint; var I: TPoint): TIntersectStatus;
{
           (YA-YC)(XD-XC)-(XA-XC)(YD-YC)
       r = -----------------------------  (1)
           (XB-XA)(YD-YC)-(YB-YA)(XD-XC)

           (YA-YC)(XB-XA)-(XA-XC)(YB-YA)
       s = -----------------------------  (2)
           (XB-XA)(YD-YC)-(YB-YA)(XD-XC)
}
var
 r, s: Double;
 ri, si, f: integer;

begin
 if ((A.X = C.X) and (A.Y = C.Y) and (B.X = D.X) and (B.Y = D.Y)) or
    ((A.X = D.X) and (A.Y = D.Y) and (B.X = C.X) and (B.Y = C.Y))
 then begin
   Result := liEqual;
   Exit;
 end;

 f := ((B.X - A.X)*(D.Y - C.Y)) - ((B.Y - A.Y)*(D.X - C.X));
 ri := ((A.Y - C.Y)*(D.X - C.X)) - ((A.X - C.X)*(D.Y - C.Y));
 if f = 0 then begin
   if ri = 0 then begin
     Result := liCombine;
     Exit;
   end;
   Result := liParallel;
   Exit;
 end;
 si := ((A.Y - C.Y)*(B.X - A.X)) - ((A.X - C.X)*(B.Y - A.Y));

 r := ri / f;
 s := si / f;

 if (r < 0.0) or (r > 1.0) or
    (s < 0.0) or (s > 1.0)
 then begin
   Result := liNone;
   Exit;
 end;

 if (r = 0.0) or (r = 1.0) or (s = 0.0) or (s = 1.0) then
   Result := liDot
 else
   Result := liIntersect;

 I.X := A.X + Round(r*(B.X - A.X));
 I.Y := A.Y + Round(r*(B.Y - A.Y));
end;

--------------------
/DVA
PM MAIL WWW   Вверх
Sheff
Дата 6.12.2003, 00:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник Клуба
Сообщений: 503
Регистрация: 25.3.2002
Где: Зеленоград

Репутация: нет
Всего: 3



Не пробовал, но уверен что правильно, спасибо !


--------------------
--------------------------
Шеф всегда прав :)
PM MAIL WWW ICQ   Вверх
oleg1973
Дата 6.12.2003, 03:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


asm fanat
****


Профиль
Группа: Экс. модератор
Сообщений: 3283
Регистрация: 16.7.2003
Где: Italy

Репутация: 1
Всего: 34



гы а если так
рисуем прямую номер 1
потом прямую номер 2
и проверяем
а не совпадают ли у нас там гдето координаты точек? а? smile.gif
будет быстро работать


--------------------
SST 465555
icq 200-512-712
PM MAIL WWW ICQ   Вверх
Black_Joker
Дата 6.12.2003, 10:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 212
Регистрация: 9.11.2002
Где: Таганрог

Репутация: нет
Всего: нет



Есть и такой вариант.
Создаем массивы с элементами обеих кривых (+ массивы индексов),
Переписываем массивы в 1-н, смотрим, а не совпадут ли где нибудь массивы типа
..., i, i, ...
В смысле 2-а одинаковых индекса будут стоять рядом.

Применимо для любого числа кривых.
PM   Вверх
Полудненко Олег
Дата 6.12.2003, 16:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Українець
**


Профиль
Группа: Участник...
Сообщений: 556
Регистрация: 13.8.2003

Репутация: 1
Всего: -11



oleg1973 а на каком помежутке будем искать пересеченме? Ведь если прямые практически паралельно, то енто будет НЕМНОГО долго!!! Black_Joker аналогично с массивом, тока тут ещё всё завязывается на размере массива!
PM MAIL   Вверх
Полудненко Олег
Дата 6.12.2003, 16:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Українець
**


Профиль
Группа: Участник...
Сообщений: 556
Регистрация: 13.8.2003

Репутация: 1
Всего: -11



Dmitry V.Abramov Чем тебе не нравится мой способ? Ведь он намноге меньше
PM MAIL   Вверх
oleg1973
Дата 6.12.2003, 17:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


asm fanat
****


Профиль
Группа: Экс. модератор
Сообщений: 3283
Регистрация: 16.7.2003
Где: Italy

Репутация: 1
Всего: 34



Полудненко Олег
интересно чеж там долгово?
рисуеш одновременно две прямые (алгоритм не важен хоть любимым брезенхамом)
и сравниваеш тут же координаты точки от 1 прямой и от 2
прямые то в любом случае рисовать нада smile.gif


--------------------
SST 465555
icq 200-512-712
PM MAIL WWW ICQ   Вверх
Sheff
Дата 6.12.2003, 21:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник Клуба
Сообщений: 503
Регистрация: 25.3.2002
Где: Зеленоград

Репутация: нет
Всего: 3



По-моему, самый оптимальный алгоритм, предложенный Dmitry V.Abramov, быстрее всего работает


--------------------
--------------------------
Шеф всегда прав :)
PM MAIL WWW ICQ   Вверх
Полудненко Олег
Дата 7.12.2003, 16:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Українець
**


Профиль
Группа: Участник...
Сообщений: 556
Регистрация: 13.8.2003

Репутация: 1
Всего: -11



oleg1973 кода ты расиуеш прямые, то ты указываеш только две точки (я надеюсь), а не рисуеш их поточечно. Енто раз. Два, и самое главное!!!, пересечение этих двух прямых может и не наблюдаться визуально, имхо оно может оказаться высоко в небе или под землёй, но не у тя на мониторе!!!
PM MAIL   Вверх
Полудненко Олег
Дата 7.12.2003, 16:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Українець
**


Профиль
Группа: Участник...
Сообщений: 556
Регистрация: 13.8.2003

Репутация: 1
Всего: -11



Имеем 8 координат 4-х точек, которые пренадлежат исходным прямым: (x1,y1),(x2,y2),(x3,y3) & (x4,y4).
Вся наёбка идёт по ур-нию прямой вида y=k*x+b.
Находим k1:=(y1-y2)/(x2-x1); k2:=(y3-y4)/(x4-x3);
Находим b1:=(Form1.Image1.Height-y2-x2*k1); b2:=(Form1.Image1.Height-y4-x4*k2);
Далее находим отчку пересечения по x= (b2-b1)/(k1-k2);
Далее подставляем полученный х в y=k1*x+b1 откуда находим у.
Так в четыре строки находим координаты точки пересечения!!!!
PM MAIL   Вверх
oleg1973
Дата 7.12.2003, 18:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


asm fanat
****


Профиль
Группа: Экс. модератор
Сообщений: 3283
Регистрация: 16.7.2003
Где: Italy

Репутация: 1
Всего: 34



Цитата
то ты указываеш только две точки (я надеюсь), а не рисуеш их поточечно.

хаха
интересная теория
знаеш когда оно само рисуется? когда хардварно (vesa по стандарту поддерживает)
ну а так в любом случае любой алгоритм будет просчитывать каждую точку прямой и не важно где на экране или в бэк буфере
канешно если ты используеш там супер пупер компоненты или либы которым на входе даеш 2 точки и получаеш прямую то оно может и показатся что все так просто
так что не вижу смысла сначало рисовать линии
а потом пытатся определить пересикаемость их
если можно сделать все за 1 раз непосредственно во время рисования



--------------------
SST 465555
icq 200-512-712
PM MAIL WWW ICQ   Вверх
Sheff
Дата 7.12.2003, 19:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник Клуба
Сообщений: 503
Регистрация: 25.3.2002
Где: Зеленоград

Репутация: нет
Всего: 3



oleg1973 а кто сказал, что их вообще надо рисовать, допустим у тебя массив из 100 прямых, нужно определить все точки пересечения, ты что будешь по всему этому массиву поточечно проходить ?


--------------------
--------------------------
Шеф всегда прав :)
PM MAIL WWW ICQ   Вверх
oleg1973
Дата 7.12.2003, 21:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


asm fanat
****


Профиль
Группа: Экс. модератор
Сообщений: 3283
Регистрация: 16.7.2003
Где: Italy

Репутация: 1
Всего: 34



Sheff
ну так с этого и надо было начинать smile.gif


--------------------
SST 465555
icq 200-512-712
PM MAIL WWW ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0575 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.