;-----------------------------------------------------------------------------------
; Функция нахождения точки пересечения вертикальной бесконечной прямой с плоскостью,
; заданной тремя точками.
; (C)KAI, 2004 г. (413-2) 65-05-10 Магадан. http://geol-dh.narod.ru/
;-----------------------------------------------------------------------------------
(defun PLANE_VLINE_INTPOINT (pt1 pt2 pt3 pt4 pres / x1 x2 x3 x4 y1 y2 y3 y4 z1 z2 z3 z mx my mz mk)
; Параметры функции:
; pt1 pt2 pt3 - трехмерные координаты точек плоскости, не параллельной оси Z
; pt4 - координаты точки (2-х или 3-х мерной) от которой строится бесконечная вертикальная прямая
; pres - точность сравнения 2-х величин (рекомендуется 0.0000001)
; Ссылка на функции: MATRIX_DETERM (определитель матрицы 3 х 3)
; Пересечение с плоскостью ищется и том случае, когда точка лежит за пределами площади треугольника
; Благодарность за алгоритм моей дочери Филипповой Ольге.
; если плоскость не параллельна оси Z выполняем вычисление точки пересечения
(if (or (equal (- (angle pt1 pt2) (angle pt2 pt3)) 0 pres)
(equal (abs (- (angle pt1 pt2) (angle pt2 pt3))) PI pres))
(progn
(alert (strcat "Plane is parallel to Z axis. Can't calculate Z coordinate of point."))
(setq z nil)
)
(progn
; для точки 1 плоскости
(setq x1 (car pt1))
(setq y1 (cadr pt1))
(setq z1 (caddr pt1))
; для точки 2 плоскости
(setq x2 (car pt2))
(setq y2 (cadr pt2))
(setq z2 (caddr pt2))
; для точки 3 плоскости
(setq x3 (car pt3))
(setq y3 (cadr pt3))
(setq z3 (caddr pt3))
; для искомой точки, от которой строится бесконечная вертикальная прямая
(setq x4 (car pt4))
(setq y4 (cadr pt4))
; считаем определитель матрицы
(setq mx (MATRIX_DETERM y1 y2 y3 z1 z2 z3 1.0 1.0 1.0))
(setq my (MATRIX_DETERM z1 z2 z3 x1 x2 x3 1.0 1.0 1.0))
(setq mz (MATRIX_DETERM x1 x2 x3 y1 y2 y3 1.0 1.0 1.0))
(setq mk (MATRIX_DETERM x1 x2 x3 y1 y2 y3 z1 z2 z3))
; считаем искомую координату Z на бесконечной вертикальной линии от точки pt4
(setq z (* mx x4 -1))
(setq z (- z (* my y4)))
(setq z (+ z mk))
; проверяем на нулевое значение
(if (equal mz 0.0 pres)
(progn
(alert (strcat "Division by zero. Can't calculate Z coordinate of point."))
(setq z nil)
)
(setq z (/ z mz))
)
)
)
; Возврат значения: точка пересечения прямой и плоскости pt4 с вычисленной Z координатой
; или nil (при невозможности определения)
(if z
(setq pt4 (list x4 y4 z))
(setq pt4 nil)
)
);end of **** PLANE_VLINE_INTPOINT ****
|
|