Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Проверить, принадлежит ли точка прямоугольнику [Delphi]


Страницы:   1 2

AlexanderMS ©   (2007-08-10 05:48:00) 

Известны координаты вершин прямоугольника (на плоскости), угол его поворота (относительно центра), и координаты точки. Как программно узнать, принадлежит ли точка прямоугольнику, или нет?

Нашёл в общем случае для полигона (можно обходить все вершины с суммированием углов между векторами "точка-вершина" (если +-360, то принадлежит)), но здесь как-то проще можно сделать.


@!!ex   (2007-08-28 09:51:00) [1]

> однако для построения уравнений придется делать вычисления
> для всех сторон, что излишне.
>
> в [5] описан более экономичный способ.

Зачем? парами считать, направляющие векторы то у парарельных прямых одинаквые.
А если это прямоугольник, то достаточно найти один, а второй будет под 90 градусов.


> [26] Darkwingg   (27.08.07 15:41)

Нееет. Все таки я туплю конкретно.
Нет там деления на ноль. Даже при вертикальной прямой.
Это же тупо компоненты вектора, ну равна одна из них нулю, там же умножение, а не деление!


@!!ex   (2007-08-28 09:51:00) [2]

> однако для построения уравнений придется делать вычисления
> для всех сторон, что излишне.
>
> в [5] описан более экономичный способ.

Зачем? парами считать, направляющие векторы то у парарельных прямых одинаквые.
А если это прямоугольник, то достаточно найти один, а второй будет под 90 градусов.


> [26] Darkwingg   (27.08.07 15:41)

Нееет. Все таки я туплю конкретно.
Нет там деления на ноль. Даже при вертикальной прямой.
Это же тупо компоненты вектора, ну равна одна из них нулю, там же умножение, а не деление!


Darkwingg   (2007-08-27 15:41:00) [3]

в том то и дело что с синусами, косинусами, углами и векторами не дожно возникать никаких проблем. там вообще нет никакого деления. что собсно и отражено в моем методе))). все заканчиваю флудить....последний пост в этой теме.


@!!ex   (2007-08-27 15:34:00) [4]

> [24] Darkwingg   (27.08.07 15:28)

Честно говоря я уже сейчас не помню, но нам объясняли как избегать случая, когда компонента направляющего вектора равно 0, вроде там както просто, но это было давно и я не помню.


Darkwingg   (2007-08-27 15:28:00) [5]


> @!!ex ©

угу согласен)) я тож щас понял, что пора бы заново пролистать кой-какие книжки...

только вот к этому виду уравнение тоже надо еще привести, здается мне что в этом методе от деления на ноль всерно никуда не деться. Прямая, проходящая через две точки, если не ошибаюсь, описывается такой формулой:

(x-x1)/(y-y1) = (x-x2)/(y-y2)

путем бубна и ктулху его можно привести к виду ax + by + c = 0, где всерно будет (x1 - x2) в знаменателе.


MBo   (2007-08-27 15:28:00) [6]

>@!!ex
однако для построения уравнений придется делать вычисления для всех сторон, что излишне.

в [5] описан более экономичный способ.


@!!ex   (2007-08-27 15:05:00) [7]

> [21] MBo ©   (27.08.07 15:01)

А! Точно. Протупил нафиг.
Ведь как раз именно это уравнение дает расстояние от прямой до точки и к тому же универсальное.

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

Darkwingg, вот оно - то самое уравнение.


MBo   (2007-08-27 15:01:00) [8]

>В данном случае нет смысла от такого описания
Если речь идет о том, с какой стороны от прямой находится точка, то это описание отлично подходит.


@!!ex   (2007-08-27 13:50:00) [9]

> [19] MBo ©   (27.08.07 13:37)

В данном случае нет смысла от такого описания, хоть оно и универсальное.. :(


> [18] Darkwingg   (27.08.07 13:03)

Хм. А я обычно наоборот избегаю вертикальных прямых именно применением прямой близкой к вертикальной, обычно точности хватает, даже на очень длинных прямых.


MBo   (2007-08-27 13:37:00) [10]

>Darkwingg
любую прямую можно описать,например, уравнением ax + by + c = 0


Darkwingg   (2007-08-27 13:03:00) [11]


> Вот не надо придираться к таким мелочам.


А это не совсем мелочи.... вот например что вы будете делать с прямой близкой к вертикальной?

подозреваю что ваша формула выглядит так y=x(y2-y1)/(x2-x1) + b, в таком случае при малом но не нулевом (x2-x1), что как раз имеет прямая, близкая к вертикальной, вы получите большую погрешность и можете промахнуться с положением точки, а кроме того может возникнуть деление на ноль.

канеш это всё зависит, от того с какой глубиной подходить к решению задачи. Для автора, я думаю, сойдет любой из вариантов.


@!!ex   (2007-08-27 12:18:00) [12]

> [16] Darkwingg   (27.08.07 12:00)

Вот не надо придираться к таким мелочам.
И идиоту известно, что вертикальная прямая не являеться обычной прямой, хотя бы потому, что не являеться графиком.
Соответственно и порверять ее нужно отдельно.
ИМХо проще проверить, чем воспользоваться вашим методом.
Да и работать будет быстрее.


Darkwingg   (2007-08-27 12:00:00) [13]

хм...хм) да через любые 2 несовпадающие точки можно провести прямую, однако не каждую прямую можно описать уравнениемy=f(x), то есть как раз в случае вертикальной прямой потребуется дополнительное условие, проверяющее вертикальна ли она.

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


@!!ex   (2007-08-27 11:34:00) [14]

> [14] Darkwingg   (27.08.07 10:59)

Вам в ВУЗе не преподавали свойства прямой? :)

Первое свойство:
Через любые две несовпадающие точки можно провести единственную прямую.

В данно мслучае уравнение прямой будет:
x = x1
и расстояние от прямой до точки будет находиться как разность x1 и x координаты точки.


Darkwingg   (2007-08-27 10:59:00) [15]


> А есть какие то проблемы? :))

хм)), ну напишите тогда уравнение прямой проходящей через точки

x1=1, y1=0, x2=1, y2=3.


Darkwingg   (2007-08-27 10:56:00) [16]

имхо самое правльное пересчитать координаты точки в систему координат, построенную на любой вершине и двух перпендикулярных сторонах прямоугольника, а затем сравнить координаты с длинами сторон. (суть процесса уже описана выше, привожу формулы)

выберем в качестве точки отсчета новой системы координат левую нижнюю точку прямоугольника.

pх, py - координаты точки в старой системе координат
newpx, newpy - координаты точки в новой системе координат
ax, ay - координаты левой нижней точки прямоугольника (естессно в ст. системе координат.)
la, lb - длины сторон прямоугольника

G - угол поворота прямоугольника по часовой стрелке, относительно его левой нижней точки.

1. newpx = (px - ax)*cos(G) - (py - ay)*sin(G)
2. newpy = (px - ax)*sin(G) + (py - ay)*cos(G)

если newpx <= la и newpy <= lb, то точка лежит внутри прямоугольника.

правда получится не совсем гуд, если длины сторон прямоугольника не известны, а известны только координаты вершин))) придется считать еще и их, на это нужно еще несколько операций.


@!!ex   (2007-08-27 10:35:00) [17]

> [11] Darkwingg   (27.08.07 10:02)

А есть какие то проблемы? :))


Darkwingg   (2007-08-27 10:02:00) [18]


> Если подставить координаты точки в  уравнение прямой то
> получиться расстояние от точки до прямой,


Мне интересно, как вы в этом случае определите уравнение для вертикальной прямой )))


Pa5ha   (2007-08-13 00:46:00) [19]

Хз накодил там автор чего или нет ) Показую свой код ) function tElement.CheckLinesUnderCur(x, y, w: Single): Boolean;
var i: integer;
a,b,c,l: Single;
flag:Boolean;
begin
Result:=False;
       for i:=0 to Length(lines)-1 do
         begin
           // x = (sqr(b)+sqr(c)-sqr(a))/(2*c);
           // h = sqrt(sqr(b)-sqr(x));
           a:=
             sqrt(
               sqr((lines[i].line[0].x)-x)+
               sqr((lines[i].line[0].y)-y));
           b:=
             sqrt(
               sqr((lines[i].line[1].x)-x)+
               sqr((lines[i].line[1].y)-y));
           c:=
             sqrt(
               sqr(
                 (lines[i].line[0].x)-
                 (lines[i].line[1].x)
                 )+
               sqr(
                 (lines[i].line[0].y)-
                 (lines[i].line[1].y)
                 ));
           flag:=false;
           if c>0 then
             begin
               l:=
                 (
                   sqr(b)+
                   sqr(c)-
                   sqr(a)
                 )/
                 (2*c);
               if
                 (sqr(b)>=(sqr(l)))and
                 ( sqr(a) <=( sqr(c)+sqr(w) ) )and
                 (sqr(b)<=(sqr(c)+sqr(w)))
                 then
                 begin
                   if sqrt(sqr(b)-sqr(l))<=w then
                     begin
                       flag:=true;
                     end;
                 end;
             end;

           if flag then
             begin
               // рядом с линией, в пределах w.
               // h (тут, наверно, l) - расстояние от точки до прямой.
             end;
         end;
end;

Короче если ещё подумать, то можно сделать то что надо )


AlexanderMS   (2007-08-11 15:59:00) [20]

Большое спасибо.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо