Schöck
| Правила | Регистрация | Пользователи | Поиск | Сообщения за день | Все разделы прочитаны |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Тригонометрические функции и векторная алгебра

Тригонометрические функции и векторная алгебра

Ответ
Поиск в этой теме
Непрочитано 20.11.2009, 18:38
Тригонометрические функции и векторная алгебра
Supermax
 
Руководитель фирмы
 
Москва
Регистрация: 28.03.2007
Сообщений: 1,831

Решил переделать тему и собрать тут все, необходимое для вычислений в пространстве модели Автокада.

Вычисление расстояния от точки до точки:
(distance <точка1> <точка2>)
Аргуметы в виде списков (X Y Z)
В книге Н. Н. Полещука "AutoLISP и Visual Lisp в среде AutoCAD" в этой функции опечатка.
Цитата:
... Если точки трехмерные, то функция рассчитывает угол между осью Х и проекцией вектора, идущего из первой точки во вторую точку, на текущую плоскость построений. ...
Весь этот текст следует просто зачеркнуть. Остальное правильно.

Получение координат точки, лежащей на середине расстояния по прямой, между двумя точками:

Получение координат точки лежащей от точки P1 на расстоянии L в направлении точки P2:

Получение единичного вектора по двум точкам:

Функция EULER-XY
Вычисление углов Эйлера, определяющих разворот ПСК относительно МСК.
по двум векторам направления осей X и Y ПСК.

Функция EULER-Z
Вычисление углов Эйлера, определяющих разворот ПСК относительно МСК.
по направлением оси Z ПСК.

Функция ORT
Вычисляет орт двумерного или трехмерного вектора из точки 0,0,0 в указанную точку

Функция VXV
Вычисляет векторное произведения векторов.
Возврат: список из трех координат результирующего вектора.

Функция VAV.
Определяет взаимное направление 2х векторов. (к сожалению, вектора задаются как направление
из точки 0,0,0 в указанную точку)
Возврат: число - угол между векторами в радианах [0 ; Pi].


Функция GET-UCS-MATRIX
Вычисляет матрицу прямого или обратного преобразования для использования в ActiveX методе TransformBy.
Аргументы.
Функция получает в качестве 1-го аргумента точку начала мысленной ПСК (ПСК не обязана реально существовать).
В качестве второго и третьего аргументов - векторы осей X и Y ПСК.


Получение векторов Z, -Z, X, -X, Y и -Y ПСК объекта по его нормали и углу поворота

Функция по получению точки вставки и трех векторов объекта

Скалярное произведение векторов, однако!

Вычисление точки, лежащей на прямой, пересекающей плоскость.

Функция вычисления угла между векторами (в градусах и от 0 до 180).

Последний раз редактировалось Supermax, 07.12.2009 в 18:22.
Просмотров: 34995
 
Непрочитано 04.12.2009, 15:33
#121
Елпанов Евгений

программист
 
Регистрация: 20.12.2005
Москва
Сообщений: 1,440
Отправить сообщение для Елпанов Евгений с помощью Skype™


Код был примерно с таким смыслом:
Код:
[Выделить все]
(defun c:test ()
 (foreach a (mapcar (function cadr) (ssnamex (ssget "_X")))
  (entmod
   (mapcar
    (function
     (lambda (a)
      (cond ((member (car a) '(10 11 210)) (cons (car a) (subst 1e-8 0. (cdr a))))
            ((and (member (car a) '(40 50 51)) (= (cdr a) 0)) (cons (car a) 1e-8))
            (a)
      )
     )
    )
    (entget a)
   )
  )
 )
)
Только длина была в пару экранов и сложно понять, что именно делает этот код...
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны.
/Сунь Цзы/
Елпанов Евгений вне форума  
 
Автор темы   Непрочитано 04.12.2009, 15:36
#122
Supermax

Руководитель фирмы
 
Регистрация: 28.03.2007
Москва
Сообщений: 1,831
Отправить сообщение для Supermax с помощью Skype™


Я думаю 1/64 много? Да я думаю это очень-очень мало! Раз так в 100000
Supermax вне форума  
 
Непрочитано 04.12.2009, 16:08
#123
zamtmn

КИПиА
 
Регистрация: 21.03.2005
Tyumen
Сообщений: 1,429
<phrase 1=


>>Я думаю 1/64 много? Да я думаю это очень-очень мало! Раз так в 100000
т.е. надо (1\64)*100000=1562,5? или мало в смысле много)))?

кароче, пример расчета ox в цифрах

1) отклонение меньше 1\64,например нормаль = (-9,9999999995e-06, 0, 0,99999999995)
Код:
[Выделить все]
(abs (Nx) < 1/64) and (abs (Ny) < 1/64) ?
да,значит 0x=Wy X N
0x=(0,1,0)X(-9,9999999995e-06, 0, 0,99999999995)=(0,99999999995, -0, 9,9999999995e-06)

нормализуем 0x=(0,99999999995, -0, 9,9999999995e-06)

0y = N X 0x = (-9,9999999995e-06, 0, 0,99999999995)X(0,99999999995, -0, 9,9999999995e-06)=(0, 1, 0)
2) отклонение больше 1\64,например нормаль = (0,031234752378, 0, 0,99951207609)
Код:
[Выделить все]
(abs (Nx) < 1/64) and (abs (Ny) < 1/64) ?
нет,значит 0x=Wz X N
(0,0,1)X(0,031234752378, 0, 0,99951207609)=(0, 0,031234752378, 0)

нормализуем 0x=(0, 1, 0)

0y = N X 0x = (0,031234752378, 0, 0,99951207609)X(0, 1, 0)=(-0,99951207609, 0, 0,031234752378)
ну и чтобы учесть rotation, нужно повернуть полученый 0x на rotation вокруг нормали перед расчетом 0y

в каком месте 1\64 повлияла на точность? нормаль как была так и осталась, ниче не округрилось

Последний раз редактировалось zamtmn, 05.12.2009 в 00:50.
zamtmn на форуме  
 
Автор темы   Непрочитано 04.12.2009, 17:36
#124
Supermax

Руководитель фирмы
 
Регистрация: 28.03.2007
Москва
Сообщений: 1,831
Отправить сообщение для Supermax с помощью Skype™


Самое пресамое что у нас есть по перемножению векторов это
Код:
[Выделить все]
; V*V.
; Функция вычисления векторного произведения векторов.
; Возврат: список из 3х чисел: трех координат результирующего вектора.
; Если вектора коллинеарны - возвращает nil.
(defun v*v (v1 v2 / res )
  (setq res
	 (list
	   (- (* (cadr v1)(caddr v2)) (* (caddr v1)(cadr v2))); координата X (в МСК).
	   (- (* (caddr v1)(car v2)) (* (car v1)(caddr v2))); координата Y (в МСК).
	   (- (* (car v1)(cadr v2)) (* (cadr v1)(car v2))); координата Z (в МСК).
	 ); return.
  ); setq.
  (if (equal res '(0.0 0.0 0.0) 1e-12) nil res); return.
); end defun.
здесь установлена точность 1e-12, что хоть и не обосновано (ну, типа мне никто так и не обосновал), но жить можно. 0.0000000000001 это терпимо, да если учесть, что при такой точности еще и какие-то перемножения должны идти, то может и даст какой-то вектор с точностью 1е-16.
Но мне настойчиво предлагают не перемножать вектора если их координаты X Y отличаются от 0 на < 0.015625. Если последовать этому совету, то у меня на расстоянии в 1 метр уже не совпадут полученные координаты на 15,625 мм с требуемым значением.
Функция VVA C:TEST должна с моей точки зрения выглядеть так:
Код:
[Выделить все]
(defun C:TEST ()
  (setq FUZZ 1.0e-12) ; точность
  (setq vect '(100 100 10000)) ;_Вектор
  (setq ort (pl-geom-single-vector Vect)) ;_Орт
  (if (and ;_см zamtmn
	  (< (abs(car ort)) FUZZ)
	  (< (abs(cadr ort)) FUZZ)
       )
  (alert "Меньше точности 1.0e-12")
  (alert "OK")
    )
  )
Потом, если оставлять такую функцию, то nil в ней надо заменить на 0,0,0? Я думаю, что всем, кто захочет воспользоваться этой функцией все равно придется принемать решение о том, что делать с этим nil.
Далее, я конечно понимаю, что истина дороже, и длинна полученного вектора, хоть и близка по размерам к точке, но она натуральна, но стоит этот вектор вытянуть до орбиты единичной окружности и что? X Y уже могут и не попасть под шаблон 1е-12.
Я считаю, что надо забыть про формулировку "перемножение векторов" и принять формулировку "получение единичного вектора результата перемножения векторов".
В эту функцию по перемножению надо вставить функцию VVA pl-geom-single-vector и только после нее сравнивать на 1е-12.

Код:
[Выделить все]
; V*V.
; Функция вычисления векторного произведения векторов.
; Возврат: список из 3х чисел: трех координат результирующего вектора.
; Если вектора коллинеарны - возвращает nil.
(defun v*v (v1 v2 / res )
  (setq res
	 (list
	   (- (* (cadr v1)(caddr v2)) (* (caddr v1)(cadr v2))); координата X (в МСК).
	   (- (* (caddr v1)(car v2)) (* (car v1)(caddr v2))); координата Y (в МСК).
	   (- (* (car v1)(cadr v2)) (* (cadr v1)(car v2))); координата Z (в МСК).
	 ); return.
  ); setq.
  (if (equal (pl-geom-single-vector res) '(0.0 0.0 0.0) 1e-12) nil res); return.
); end defun.
Вот так!

Но это для Автокада! А для функции получения точки на прямой пересекающей плоскость, может надо оставить все как есть.

zamtmn , надо 1/6400000 если не больше (в смысле меньше)

Еще, вот есть у нас два вектора, их надо перемножить, от их длинны зависит результат перемножения? Я думаю да. А результат нам нужен для чего? Почему все время фигурирует понятие "вектор"? Если нам нужны длины отрезков, а не направления этих отрезков, так давайте так и говорить. А если нам нужны точные направления, так давайте умножим длины исходных векторов на миллион и потом посчитаем результат. Я бъюсь за точность направления, а за длинну имеет смысл биться только если она имеет значение при расчетах.

Взял функцию VVA parallelp и проверил на паралельность два отрезка длинной в 100000 мм один из которых повернут на 1 мм на 100м
и она ответила nil, что означает, что они не паралельны.
Все, мозг мой усох совсем.

Последний раз редактировалось Supermax, 04.12.2009 в 18:23.
Supermax вне форума  
 
Непрочитано 04.12.2009, 19:02
#125
zamtmn

КИПиА
 
Регистрация: 21.03.2005
Tyumen
Сообщений: 1,429
<phrase 1=


>>Самое пресамое что у нас есть по перемножению векторов это
вполне нормальная функция.
>>здесь установлена точность 1e-12, что хоть и не обосновано (ну, типа мне никто так и не обосновал)
а что тут обосновывать? принята и всё, в жизни с такими величинами работать редко приходится

>>Но мне настойчиво предлагают не перемножать вектора если их координаты X Y отличаются от 0 на < 0.015625.
так принято в автокаде с незапамятных времен, хочешь сам считать СК объекта придется делать также.

>>Еще, вот есть у нас два вектора, их надо перемножить, от их длинны зависит результат перемножения?
конечно зависят, насколько помню длина результата - площадь паралепипида образованного исходными векторами. но это используется очень редко, заметь результат всегда нормализуется, в данном и большинстве случаев нам важно только направление вектора
zamtmn на форуме  
 
Автор темы   Непрочитано 04.12.2009, 19:40
#126
Supermax

Руководитель фирмы
 
Регистрация: 28.03.2007
Москва
Сообщений: 1,831
Отправить сообщение для Supermax с помощью Skype™


zamtmn, ты говорил, что два вектора надо сначала сравнивать на паралельность, а затем перемножать. Ты еще так думаешь?
Supermax вне форума  
 
Непрочитано 04.12.2009, 19:49
#127
zamtmn

КИПиА
 
Регистрация: 21.03.2005
Tyumen
Сообщений: 1,429
<phrase 1=


Когда считаешь ск - да, делаешь по ARBITRARY AXIS ALGORITHM.
В других случаях - нет, умножаешь если =ноль паралельны, нет - всё ок, получили нормаль.

Когда считаешь плоскость по 3м точкам точки обычно заведомо берутся не на прямой. если уж получилось что точки на прямой - проверяй, не проверяй а однозначно плоскость через них никак не провести

Когда считаешь ск объекты часто выровнены по осям, соответственно нужно проверять. есть 2 варианта расчета 1 - через YWCS, 2 - через ZWCS + четко установлена граница - 1\64, когда какой использовать.

Последний раз редактировалось zamtmn, 05.12.2009 в 01:03.
zamtmn на форуме  
 
Автор темы   Непрочитано 06.12.2009, 16:58
#128
Supermax

Руководитель фирмы
 
Регистрация: 28.03.2007
Москва
Сообщений: 1,831
Отправить сообщение для Supermax с помощью Skype™


Вот так всегда. Ни да, ни нет. Для функции вычисления точки на прямой, пересекающей плоскость, надо векторы на паралельность проверять, или нет?
Сейчас попытаюсь ее доделать.

Мы, товарищи, пойдем своим путем!

Функция получения точки на отрезке (прямой), пересекающий плоскость.
Код:
[Выделить все]
(defun point-suppression-plane (a b c x y / n1 n2 n d dist1 p1 dist2 p2)
;a, b, c - точки определяющие плоскость в виде как у (endpoint)
;x, y - точки отрезка(прямой), пересекающего плоскость. 
;первый перпендикуляр к плоскости (проекция) от точки X
;получаем вектор одной грани треугольника, описывающего :-) плоскость.
(setq n1 (getvektor a b))
;вектор второй грани треугольника, описывающего плоскость 
(setq n2 (getvektor b c))
;нормаль плоскости
(setq n (v*v n1 n2))
;|
Вычисление расстояния от точки до плоскости 
 
Пусть Pa = (xa, ya, za) точка, расстояние от которой необходимо подсчитать. 
Плоскость можно задать нормалью n = (xn, yn, zn) и одной точкой Pb = (xb, yb, zb) 

Произвольная точка P = (xb,yb,zb) лежит на плоскости тогда и только тогда, когда 

xn*xb + yn*yb + zn*zb + D = 0 заметьте, не 0,0,0 а 0 значит все составляющие формулы - числа, а не x,y,z

отсюда следует: 
D = 0-(xn*xb + yn*yb + zn*zb )


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

(xn*xa + yn*ya + zn*za + D) / sqrt(xn*xn + yn*yn + zn*zn) 

Знак самого выражения дает расположение точки относительно плоскости: с какой она стороны
|;
;ну, это типа той самой D
(setq d (- 0 (apply '+ (mapcar '(lambda (f g) (* f g)) n c))))
;ну, а это, типа, вычисления расстояния
(setq dist1 (/ (+ d (apply '+ (mapcar '(lambda (f g) (* f g)) n x))) (sqrt (apply '+ (mapcar '(lambda (h) (* h h)) n)))))
;а это, координаты точки перпендикуляра к плоскости
(setq p1 (3d_polarpM n '(0.0 0.0 0.0) x  dist1))
;получение второго перпендикуляра (то же самое)
(setq dist2 (/ (+ d (apply '+ (mapcar '(lambda (f g) (* f g)) n y))) (sqrt (apply '+ (mapcar '(lambda (h) (* h h)) n)))))
(setq p2 (3d_polarpM n '(0.0 0.0 0.0) y  dist2))
;получение точки пересечения двух отрезков. Один образован отрезком, пересекающий плоскость, а второй - точками проекции
;первого отрезка на плоскость.
(inters x y p1 p2 nil);тут, типа, если nil убрать, то будет только отрезки сравнивать, 
;а так - прямые, указанные этими отрезками.
)
Функция отредактирована и надеюсь совсем стала понятна. Хотя ее может надо по человечески оформить. С аргументами надо разобраться и с назначением.

Принцип прост, до слез.
Немного пришлось функцию VVA покрамсать. Добавил один аргумент, чтобы вычислять координаты от любой, произвольной точки.

Код:
[Выделить все]
; Функция вычисления точки лежащей от точки P3 на расстоянии L в направлении указанном точками Р1и P2
;-----------------------------------------------------------------
;Параметры:
;p1 - первая точка от которой производится измерение направления
;p2 - точка в направлении которой производится измерение направления
;р3 - точка от которой производится откладка
;L  - расстояние
(defun 3d_polarpM (P1 P2 P3 L)
 (setq L (/ L (distance P1 P2)))
 (mapcar '+ P3 (mapcar '(lambda (V) (* V L)) (mapcar '- P2 P1)))
)

Последний раз редактировалось Supermax, 07.12.2009 в 14:32.
Supermax вне форума  
 
Непрочитано 07.12.2009, 01:54
#129
zamtmn

КИПиА
 
Регистрация: 21.03.2005
Tyumen
Сообщений: 1,429
<phrase 1=


>>Вот так всегда. Ни да, ни нет. Для функции вычисления точки на
>>прямой, пересекающей плоскость, надо векторы на паралельность
>>проверять, или нет?

какие? ты читаешь че тебе пишут?

>Мы, товарищи, пойдем своим путем!
своих путей в этой области нет. всё давно придумано до нас

сейчас ты плоскость задаешь нормалью и точкой. Т.е. ты автоматически считаешь что векторное произведение из задания плоскости тремя точками не равно 0. а проверить на перпендикулярность нормаль плоскости и направление прямой не помешает))

удобнее плоскость задавать нормалью и "высотой" т.е. стандартное уравнение Ax + By + Cz + D = 0. (A,B,C) - нормализованная нормаль плоскости. тогда процедура нахождения пересечения будет выглядеть примерно так:

Код:
[Выделить все]
p1-точка на прямой
d- направление прямой
plane -массив определяющий плоскость
         plane[0]-A
         plane[1]-B
         plane[2]-C
         plane[3]-D
point - возвращаемая точка
eps - точность
function PLIntersect(p1,d:GDBVertex;plane:DVector4D;var point :GDBVertex):GDBBoolean;
var
   td:GDBDouble;
begin
     td:=-plane[0]*d.x-plane[1]*d.y-plane[2]*d.z;//скалярное произведение нормали и направления
     if abs(td)<eps then
                               //если = 0 пересечения нет
                               result:=false;
                         else
                              begin                       
                                     //если <> 0 пересечение есть
                                     //считаем расстояние от точки на прямой до плоскости по прямой
                                     td:=(plane[0]*p1.x+plane[1]*p1.y+plane[2]*p1.z+plane[3])/td; 
                                     //возвращаем точку сдвинутую от p1 в направлении d на расстояние td
                                     point:=VertexDmorph(p1,d,td);
                                     result:=true;
                              end;
end;

Последний раз редактировалось zamtmn, 07.12.2009 в 02:03.
zamtmn на форуме  
 
Непрочитано 07.12.2009, 11:06
#130
Елпанов Евгений

программист
 
Регистрация: 20.12.2005
Москва
Сообщений: 1,440
Отправить сообщение для Елпанов Евгений с помощью Skype™


Цитата:
Сообщение от zamtmn Посмотреть сообщение
удобнее плоскость задавать нормалью и "высотой" т.е. стандартное уравнение Ax + By + Cz + D = 0. (A,B,C) - нормализованная нормаль плоскости. тогда процедура нахождения пересечения будет выглядеть примерно так:
Я всегда задаю плоскость нормалью и точкой - для меня плоскость является еще и системой координат...
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны.
/Сунь Цзы/
Елпанов Евгений вне форума  
 
Автор темы   Непрочитано 07.12.2009, 12:51
#131
Supermax

Руководитель фирмы
 
Регистрация: 28.03.2007
Москва
Сообщений: 1,831
Отправить сообщение для Supermax с помощью Skype™


zamtmn,
Цитата:
>>Вот так всегда. Ни да, ни нет. Для функции вычисления точки на
>>прямой, пересекающей плоскость, надо векторы на паралельность
>>проверять, или нет?

какие? ты читаешь че тебе пишут?
векторы, которые мы собрались перемножать. Опять какие?
У нас есть исходные данные, а именно:
Три точки, описывающие плоскость. (можно тупо заменить на нормаль и точку и оставить своим потомкам ломать голову как ее получить).
Эти точки могут все три иметь одно и то же значение, что, надо проверять, или нет? Если пользователь три раза ткнул в одну и ту же точку, то что должна выдать функция? Я думаю ЕГОР. Так она и так его выдаст.
Если две точки одинаковые, то значит, что пользователь или его тупой программный продукт два раза ткнул в одну и ту же точку. Что должна вернуть функция? - Конечно ЕГОР! Так она его и так выдаст в этом случае.

Все три точки разные, а если нет - ЕГОР. Вот и все.
А если точки разные - то мы можем смело перемножать АВ на ВС.
Далее:
Ваша функция хромает одним местом, а именно константой D. Ее надо вычислять, а если ее вычислять, то максимум на что мы можем расчитывать, так это на проекцию на плоскость, а не на пересечение.

Вот в моей функции есть хомут, но его никто пока не заметил. Я его сейчас подправлю. Подправил.

Функция, возвращающая угол между двумя векторами в градусах. (от точки 0,0,0)
Код:
[Выделить все]
(defun ugol-vektors (v1 v2 / p1 p2 p3 dist-p1-p2 dist-0-p3 sin-a cos-a ugol-1)
(setq p1 (3d_polarp '(0.0 0.0 0.0) v1 100.0))
(setq p2 (3d_polarp '(0.0 0.0 0.0) v2 100.0))
(setq dist-p1-p2 (distance p1 p2))
(setq p3 (cenr-point-line p1 p2))
(setq dist-0-p3 (distance '(0.0 0.0 0.0) p3))
(setq sin-a (/ dist-0-p3 100.0))
(if (= (setq cos-a (/ (/ dist-p1-p2 2) 100)) 0) 0.0 
(setq ugol-1 (atan (/ sin-a cos-a))))
(- 180 (* 2 (read (angtos ugol-1 0 15))))
)
Использует функции VVA из поста #2

Последний раз редактировалось Supermax, 07.12.2009 в 18:15.
Supermax вне форума  
 
Непрочитано 07.12.2009, 18:31
#132
zamtmn

КИПиА
 
Регистрация: 21.03.2005
Tyumen
Сообщений: 1,429
<phrase 1=


Елпанов Евгений
Тогда больше похоже на "я всегда задаю ск нормалью и точкой, она для меня еще и плоскость". почти во всех расчетах на плоскость D присутствует, ты так или иначе ее считаеш. если важна "точка начала коорбинат" то конечно, но в обычном понимании плоскости этой точки нет.

Supermax
>>векторы, которые мы собрались перемножать. Опять какие?
нет, вернет 0 или NIL что тебе удобней, вот и проверка - нормали для этих векторов нет.

>>Все три точки разные, а если нет - ЕГОР. Вот и все.
все 3 точки не лежат на одной прямой, а если нет - ЕГОР. Вот и все.


>>А если точки разные - то мы можем смело перемножать АВ на ВС.
можем смело перемножать даже одинаковые
zamtmn на форуме  
 
Непрочитано 07.12.2009, 18:46
#133
Елпанов Евгений

программист
 
Регистрация: 20.12.2005
Москва
Сообщений: 1,440
Отправить сообщение для Елпанов Евгений с помощью Skype™


zamtmn, все просто, у меня тоже, часто рождается эта плоскость из трех точек. Делаем из них два вектора и перемножаем их - получаем нормаль, потом берем любую из этих трех точек и называем ее базовой точкой - для случая нахождения пересечения линии и плоскости - достаточно...

ps. Появится немного свободного времени, оформлю для сайта несколько базовых функций для 3д преобразований, из своих частных запасов.
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны.
/Сунь Цзы/
Елпанов Евгений вне форума  
 
Непрочитано 08.12.2009, 09:23
#134
CB

Конструирование в области нефтеразведки
 
Регистрация: 10.02.2006
Гомель
Сообщений: 321


Цитата:
Функция получения точки на отрезке (прямой), пересекающий плоскость.
Код:
[Выделить все]
(defun int_line_plane (p1 p2 p3 p11 p12)
;;;  аргументы:
;;;  p1,p2,p3 - точки, определяющие плоскость
;;;  p11,p12  - точки на линии
  (apply
    '(lambda (x y z / lst d temp s int_pt)
       (setq lst
                 (list
                   (- (* (car y) (cadr z)) (* (car z) (cadr y)))
                   (- (* (car z) (cadr x)) (* (car x) (cadr z)))
                   (- (* (car x) (cadr y)) (* (car y) (cadr x)))
                 ) ;_ end of list
             d   (apply '+ (mapcar '* lst p2))
       ) ;_ end of setq
       (cond
         ((equal lst '(0.0 0.0 0.0) 1.e-012)
          (princ "\nПлоскость не определена...")
          (princ)
         )
         ((zerop (setq temp
                        (apply '+
                               (mapcar '* lst (mapcar '- p12 p11))
                        ) ;_ end of apply
                 ) ;_ end of setq
          ) ;_ end of zerop
          (princ "\nПрямая параллельна плоскости...")
          (princ)
         )
         (t
          (setq
            s      (/ (- d (apply '+ (mapcar '* lst p11))) temp)
            int_pt (mapcar '+
                           (mapcar '(lambda (x) (* s x))
                                   (mapcar '- p12 p11)
                           ) ;_ end of mapcar
                           p11
                   ) ;_ end of mapcar
          ) ;_ end of setq
         )
       ) ;_ end of cond
     ) ;_ end of lambda
    (mapcar '(lambda (a b c)
               (mapcar '(lambda (x) (- x a)) (list b c))
             ) ;_ end of lambda
            p1
            p2
            p3
    ) ;_ end of mapcar
  ) ;_ end of apply
) ;_ end of defun
CB вне форума  
 
Непрочитано 08.12.2009, 10:08
#135
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,798
<phrase 1= Отправить сообщение для VVA с помощью Skype™


Когда-то по этому адресу была выложена библиотека функций на lisp. 3d_polarp - одна из них. Вот еще одна (не проверял)
Код:
[Выделить все]
; Точка пересечения прямой и плоскости
;-------------------------------------
;Параметры:
;P1, P2 - точки на прямой
;Ppl - точка в плоскости
;WNorm - вектор нормали к плоскости
;Возвращает: точку пересечения прямой и плоскости или nil
(defun 3d_inters_lnpl (P1 P2 Ppl WNorm / A B C D L M N Tpr V)
 (mapcar 'set '(L M N) (mapcar '- P2 P1)) ; вектор прямой
 (mapcar 'set '(A B C) WNorm)
 (if (not (equal (setq V (+ (* A L) (* B M) (* C N))) 0.0 $Dopusk))
  (progn
   (setq D (- (+ (* A (car Ppl)) (* B (cadr Ppl)) (* C (caddr Ppl))))
	 Tpr (- (/ (+ (* A (car P1)) (* B (cadr P1)) (* C (caddr P1)) D) V))
   )
   (list (+ (car P1) (* Tpr L)) (+ (cadr P1) (* Tpr M)) (+ (caddr P1) (* Tpr N)))
  )
 )
)
***Добавлено
Во вложении все, что я скачал в свое время.
Вложения
Тип файла: rar func.RAR (6.8 Кб, 126 просмотров)
__________________
Как использовать код на Лиспе читаем здесь

Последний раз редактировалось VVA, 08.12.2009 в 16:52. Причина: Обновил readme.txt во вложении
VVA вне форума  
 
Непрочитано 08.12.2009, 11:45
#136
Vov.Ka


 
Регистрация: 21.07.2008
Луцьк
Сообщений: 169


вот описание всего, что было выложено по вышеуказанному адресу
Цитата:
Автор: Григорий Черевков
http://www.elecran.com.ua/
===========================
Никакой ответственности за использование этих текстов и возможных ошибок авторы не несут.

Общие комментарии
функции написаны на языке AutoLisp
Все вычисления произведены математическими методами (векторная алгебра, аналитическая геометрия) без построения вспомогательных примитивов Автокада и их разбора.
Глобальные переменные
Многие функции библиотеки ссылаются на две глобальные переменные
Переменная $P000 имеет значение ‘(0.0 0.0 0.0)
$Dopusk имеет значение 0.00001 – содержит величину погрешности используемую при различных сравнениях (например координат точек). Он просто необходим для борьбы с накопленной погрешностью при вычислениях.
Для инициализации переменных в стартовую часть Вашей программы нужно вставить строки
(setq $P000 ‘(0.0 0.0 0.0)
$Dopusk 0.00001
)

Соглашения об именах переменных-параметров
В параметрах функций часто используются следующие имена переменных.
P, P1, P2,P3…. – точки
Pc – центральная точка дуги или окружности
L, Lx, Ly, Lz – длины
Wekt, Wekt1, Wekt2, WektX, WektY, WektZ, W, W1, W2 –вектора (список из 3-х чисел)
WNorm – вектор нормали. В терминах Автокада речь идет о векторе направления выдавливания, который у всех примитивов хранится под 210 ассоциативным кодом.
Ang – угол
R, R1, R2 - радиус
======================================================================
Рассчеты дуг

1. Расстояние от точки, лежащей в плоскости дуги до дуги (1.zip)
2. Рассчет длины дуги (2.zip)
3. Рассчет центрального угла дуги (3.zip)
4. Вычисление средней точки дуги (4.zip)
5. Расчет центра дуги (дуга задана 2-мя точками и направлением
касательной в 1-й точке) (5.zip)

Функции анализа принадлежности и пересечения элементов

6. Принадлежность точки прямой, заданной точкой и вектором (15.zip)
7. Принадлежность точки отрезку (16.zip)
8. Принадлежность точки дуге (все точки в одной плоскости!) (17.zip)
9. Принадлежность точки дуге (точки в разных плоскостях!) (18.zip)
10. Принадлежность дуги дуге (19.zip)

Функции расчета пересечений объектов в пространстве

11. Пересечение 2-х окружностей заданных центром и радиусом,
лежащих в одной плоскости (10.zip)
12. Пересечение 2-х окружностей заданных центром и радиусом,
расположенных в заданной плоскости (11.zip)
13. Точка пересечения прямой и плоскости (12.zip)
14. Точки пересечения окружности с плоскостью (13.zip)
15. Расчет линии пересечения плоскостей (14.zip)
16. Пересечение прямой и окружности, лежащих в одной плоскости (8.zip)
17. Пересечение прямой и окружности, произвольно расположенных (9.zip)

Функции общего назначения

18. Векторное произведение векторов (20.zip)
19. Вектор нормали к плоскости. Плоскость задана 3-мя точкам (21.zip)
20. Вычисление орта (единичного вектора) (22.zip)
21. Приведение вектора к длине 1000 (длинному вектору) (23.zip)
22. Точка лежащая от точки P1 на расстоянии L в направлении точки P2 (24.zip)
23. Точка лежащая от P1 на расстоянии L по вектору Wekt (25.zip)
24. Точка, смещенная по 2-м векторам (26.zip)
25. Условие ортогональности векторов (27.zip)
26. Угол между векторами (29.zip)
27. Угол между векторами по часовой стрелке со стороны нормали (30.zip)
28. Вектор под углом относительно данного со стороны нормали (31.zip)
29. Ближайшая от заданной точки точка отрезка (32.zip)
30. Расстояние от точки до отрезка (33.zip)
31. Поворот точки вокруг оси (34.zip)
32. Проекция точки на прямую (прямая задана точкой и вектором) (35.zip)
33. Проекция точки на прямую (прямая задана двумя точками) (36.zip)
34. Проекция точки на плоскость (37.zip)
35. Расстояние между плоскостями (38.zip)

Функции пространственной геометрии

36. Расчет точки касания из точки к окружности (6.zip)
37. Расчет точек касания к 2-м окружностям (7.zip)
=========================================================================
Vov.Ka вне форума  
 
Автор темы   Непрочитано 08.12.2009, 11:53
#137
Supermax

Руководитель фирмы
 
Регистрация: 28.03.2007
Москва
Сообщений: 1,831
Отправить сообщение для Supermax с помощью Skype™


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

Ну где вы раньше были?
Supermax вне форума  
 
Непрочитано 08.12.2009, 13:07
#138
ShaggyDoc

Thượng Tá Quân Đội Nhân Dân Việt Nam
 
Регистрация: 14.03.2005
44d32'44"С, 33d26'51"В
Сообщений: 11,092


Если бы некий руководитель фирмы не угробил идею с dwgru-lib, то сотни две подобных функций там давно были бы.
ShaggyDoc вне форума  
 
Автор темы   Непрочитано 08.12.2009, 14:06
#139
Supermax

Руководитель фирмы
 
Регистрация: 28.03.2007
Москва
Сообщений: 1,831
Отправить сообщение для Supermax с помощью Skype™


Никто ничего не гробил. Просто шел себе, шел, случайно плечом задел, а она взяла и упала. Хлипкая была, без подпорок. Видать шабашники делали.
Supermax вне форума  
 
Непрочитано 08.12.2009, 14:21
#140
Елпанов Евгений

программист
 
Регистрация: 20.12.2005
Москва
Сообщений: 1,440
Отправить сообщение для Елпанов Евгений с помощью Skype™


Supermax, Во многих темах, тебе пытались объяснить, что библиотечные функции должны быть универсальными, а не такими, как тебе нужно в данный конкретный момент. И еще, универсальность, это не значит, что делает все кроме кофе. Универсальность, это когда выполняет одну операцию, но качественно.

ps. только без обид - я не хочу обидеть!
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны.
/Сунь Цзы/
Елпанов Евгений вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Тригонометрические функции и векторная алгебра

Размещение рекламы
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Рифмоплетство. Kryaker Разное 519 18.09.2019 18:52
Определение высот рельефа по близлежащим точкам dextron3 Программирование 21 10.11.2011 13:14
Интерполяция между двумя точками postbudka Программирование 27 21.05.2009 10:00
ЮМОР 2006 =) Perezz!! Разное 1122 04.01.2007 00:46
Координаты точки, лежащей на полилинии Al_Taron Программирование 1 27.11.2006 09:45