Тема: Как определить принадлежит ли точка отрезку или нет?

Как определить принадлежит ли точка отрезку или нет?

Re: Как определить принадлежит ли точка отрезку или нет?

Точка принадлежит отрезку, если сумма расстояний от этой точки до конечных точек отрезка равна длине отрезка.

Re: Как определить принадлежит ли точка отрезку или нет?

Очень интерестно проходит ли такая проверка.
Я в свое время для похожей задачи по двум точкам отрезка задавал уравнение прямой и подставлял в него координаты точки. Теоретически если точка на прямой уравнение обнуляется (aX+bY+c=0) на практике условие проходило если отрезок горизонтален или вертикален (точку получал указанием с привязкой к ближнему), ели нет погрешность приходилось учитывать (при конечной точности вычислений в данном случае это неизбежно) .

Re: Как определить принадлежит ли точка отрезку или нет?

Если устроит попробуйте использовать
функцию (vlax-curve-getParamatPoint <кривая> <точка>).
Если вернёт nil значит точка не лежит на кривой.
У Полещука написано <кривая>  - VLA-объект,
но как показывает практика можно и имя примитива.

Re: Как определить принадлежит ли точка отрезку или нет?

Когда-то (в AutoCAD10) выходил из положения так :
(setq Nabor (ssget "_C"  t1 t1))
,- где t1 - координаты точки [например, '(150 175 0)],
а затем, перебирал объекты, попавшие в набор "Nabor", на предмет наличия среди них того самого отрезка...

Re: Как определить принадлежит ли точка отрезку или нет?

Я в свое время точно также как и AY пытался решить эту задачу на основе линейных уравнений. Оказалось, что камнем преткновения является погрешность вычислений. В итоге, метод работает ненадежно и неустойчиво. По-видимому, сама постановка вопроса -Точка принадлежит линии - при переводе в практическую плоскость нуждается в переосмыслении. А что есть прямая (линия), ведь это не более чем выдумка античных математиков...ведь она не имеет толщины, и следовательно - не существует. Я понимаю, все это звучит несколько академически, однако вопрос надо решать!
Давайте считать линией полосу конечной ширины, и при постановке задачи указывать эту ширину. Интересно было бы услышать мнение профессиональных математиков, например, специалистов по теории множеств.

Re: Как определить принадлежит ли точка отрезку или нет?

Тоже недавно делал проверку принадлежности точки сфере. Естественно сравнение через EQUAL, смотря какая точность нужна...
Есть еще идея. Существует функция  vlax-curve-getDistAtPoint <кривая> <точка>  которая вычисляет расстояние между начальной точкой кривой (а в нашем случае отрезка) до точки на кривой. В случае если точка не лежит на кривой она возвратит Nil.

Re: Как определить принадлежит ли точка отрезку или нет?

Public Function ТочкаНаПрямой(dblСписокКоордПрямой As Variant, XCoordТочки As Double, YCoordТочки As Double) As Boolean
Dim РасстояниеДоТочки As Double, РасстояниеПослеТочки As Double, ДлинаПрямой As Double
   РасстояниеДоТочки = VBA.Sqr((XCoordТочки - dblСписокКоордПрямой(1)) ^ 2 + (YCoordТочки - dblСписокКоордПрямой(2)) ^ 2)
   РасстояниеПослеТочки = VBA.Sqr((dblСписокКоордПрямой(3) - XCoordТочки) ^ 2 + (dblСписокКоордПрямой(4) - YCoordТочки) ^ 2)
   ДлинаПрямой = VBA.Sqr((dblСписокКоордПрямой(3) - dblСписокКоордПрямой(1)) ^ 2 + (dblСписокКоордПрямой(4) - dblСписокКоордПрямой(2)) ^ 2)
   If VBA.Round(РасстояниеДоТочки + РасстояниеПослеТочки, 7) = VBA.Round(ДлинаПрямой, 7) Then
'Точка находится на прямой
      ТочкаНаПрямой = True
   Else
'Точка находится вне прямой (ответ = расстояние от конца прямой до точки)
'      ТочкаНаПрямой = (РасстояниеДоТочки + РасстояниеПослеТочки - ДлинаПрямой) / 2
      ТочкаНаПрямой = False
   End If
End Function
Эта функция работает без видимых и заметных сбоев уже долгое время. Весь секрет в том, что надо задавать как все нормальные люди точность своих вычислений, а не пытаться выполнить свою задачу с точностью до микрона там где требуется точность максимум до милиметра, и 7 знаков после запятой при единицах измерения мм вполне достаточно. Можете повысить точность до 12 чисел и выше, однако математические способности VBA уже начинают выдавать вместо 1 число 0,9999999999999999999999999999 и выражение 1=1 (при определёном задании и способах получения переменых) уже может не являться истиной. Прежде всего надо знать пределы математических возможностей программы с которой вы работаете и не тратить время на излишнюю точность а выдавать продукцию.

Re: Как определить принадлежит ли точка отрезку или нет?

Как уже писал, при теоретическом подходе учет пргрешности неизбежен, однако предположу, что функции (vlax-* могут контролировать и учитывать ее и выдавать достоверный результат. Может ли кто-нибудь подтвердить такое предположение?

Re: Как определить принадлежит ли точка отрезку или нет?

*1.2 Аналитическая геометрия на плоскости.*
_1.2.1 Основные формулы в Декартовой системе координат._
P1(x1, y1), P2(x2, y2), P3(x3, y3), P4(x4, y4)
- Расстояние:
     d(P1, P2) = sqrt((x1-x2)^2 + (y1-y2)^2)
- Угол между двумя веторами P1P2 P3P4:
                (x2-x1)(x4-x3) + (y2-y1)(y4-y3)       (P1P2, P3P4)
     cos(al) = --------------------------------- = -------------------
                      d(P1, P2)*d(P3, P4)          d(P1, P2)*d(P3, P4)
                (x2-x1)(y4-y3) - (x4-x3)(y2-y1)       [P1P2, P3P4]
     sin(al) = --------------------------------- = ------------------
                      d(P1, P2)*d(P3, P4)          d(P1, P2)*d(P3, P4)
                (x2-x1)(y4-y3) - (x4-x3)(y2-y1)       [P1P2, P3P4]
     tg (al) = --------------------------------- = ------------------
                (x2-x1)(x4-x3) + (y2-y1)(y4-y3)       (P1P2, P3P4)
- Координаты x, y точки P, делящей P1P2 в отношении m/n = p/1
      mx2 + nx1    x1 + qx2
  x = --------- = ---------;
        n + m       1 + p
      my2 + ny1    x1 + qx2
  y = --------- = ---------;
        m + n       1 + p
- Соответственно, если P - середина (n=m), то
      x2 + x1        y2 + y1
  x = -------;   y = -------;
         2              2

Re: Как определить принадлежит ли точка отрезку или нет?

- Координаты x, y точки P, делящей P1P2 в отношении m/n = p/1
      mx2 + nx1    x1 + qx2
  x = --------- = ---------;
        n + m       1 + p
      my2 + ny1    x1 + qx2
  y = --------- = ---------;
        m + n       1 + p
- Соответственно, если P - середина (n=m), то
      x2 + x1        y2 + y1
  x = -------;   y = -------;
         2              2

Re: Как определить принадлежит ли точка отрезку или нет?

- Координаты x, y точки P, делящей P1P2 в отношении m/n = p/1
x = (mx2 + nx1)/(n + m)=(x1 + qx2)/(1 + p)
y = (my2 + ny1)/(n + m)=(y1 + qy2)/(1 + p)
съезжают дроби...
- Соответственно, если P - середина (n=m), то
x = (x2 + x1)/2 ; y = (y2 + y1)/2

Re: Как определить принадлежит ли точка отрезку или нет?

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

Re: Как определить принадлежит ли точка отрезку или нет?

;| ф-ция проверяет принадлежит ли точка отрезку или нет;
возвращает t - если принадлежит и nil - если нет
аргументы: p - точка, lps - список из 2-х точек отрезка eps - допуск погрешности
1 - считаем расстояние (d) от точки до отрезка и сравниваем с eps
  расстояние меньше  eps
2 - Точка находиться между двумя перпендикулярами, проведенными
через концы отрезка (используется скалярное произведение)
создал - Уланов О. В. 6/16/04 10:21 PM дома;-) .
с помощью http://faqs.org.ru/science/geometry_faq.htm
|;
(defun pts (p lps)
(setq x (car p) y (cadr p)
       x1 (caar lps) y1 (cadar lps)
       x2 (caadr lps) y2 (cadadr lps)
       eps 10e-10
       d (/(sqrt(abs(-(*(- x x1)(- y2 y1))(*(- y y1)(- x2 x1)))))(sqrt(abs(+(- x2 x1)(sqrt(abs(- y2 y1)))))))
       2p (*(+(*(- x x1)(- x2 x1))(*(- y y1)(- y2 y1)))(+(*(- x x2)(- x2 x1))(*(- y y2)(- y2 y1))))
); setq   
(cond
   ((> d (sqrt eps)) nil)
   ((< 2p eps) t)
   (t nil)
); cond
); defun
(defun c:pbs (/)
(while
  (setq p (getpoint "\nВыдели точку!!!")
        en (entget(car(entsel "\nУкажи линию!!!")))
        lps (list(cdr(assoc 10 en))(cdr(assoc 11 en)))
  ); setq
   (cond
     ((eq(pts p lps)t)(print "\nТочка лежит на отрезке!!!"))
     ((eq(pts p lps)nil)(print "\nТочка не лежит на отрезке!!!"))
     (t nil)
   ); cond
); while
); defun

Re: Как определить принадлежит ли точка отрезку или нет?

(defun isOnLine (_начальная _конечная _точка _допуск)
 (apply
  '(lambda (_до_начальной _длина_отрезка _до_конечной)
    (equal (+ _до_начальной _до_конечной) _длина_отрезка _допуск))
   (mapcar 'distance (list _точка _начальная _точка) (list _начальная _конечная _конечная)))
)