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

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

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

Ответ
Поиск в этой теме
Непрочитано 20.11.2009, 18:38 #1
Тригонометрические функции и векторная алгебра
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.
Просмотров: 34993
 
Непрочитано 20.11.2009, 21:35
#2
VVA

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


Так покрасивше будет
Код:
[Выделить все]
(defun cenr-point-line (pt1 pt2)
  (mapcar '* (mapcar '+ pt1 pt2) '(0.5 0.5 0.5))
  )
Вот еще одна ф-ция.
Код:
[Выделить все]
; Точка лежащая от точки P1 на расстоянии L в направлении точки P2
;-----------------------------------------------------------------
;Параметры:
;p1 - первая точка
;p2 - точка в направлении которой производится откладка
;L  - расстояние
(defun 3d_polarp (P1 P2 L)
 (setq L (/ L (distance P1 P2)))
 (mapcar '+ P1 (mapcar '(lambda (V) (* V L)) (mapcar '- P2 P1)))
)
Цитата:
3d_lib.zip
posted http://www.theswamp.org/index.php?topic=37319.0
http://www.cadtutor.net/forum/showth...858#post634858
http://www.cad.dp.ua/progs/program2.php

Author: Gregory Cherevko
http://www.elecran.com.ua/
===========================
No liability for the use of these texts and the possible errors the authors did not carry.


General comments
functions are written in AutoLisp
All calculations are made by mathematical methods (vector algebra, analytic geometry) without using auxiliary AutoCAD entities and their analysis.
Global variables
Many library functions refer to two global variables
The variable $ P000 has the value '(0.0 0.0 0.0)
$ Dopusk has a value of 0.00001 - contains the error value is used for various comparisons (such as coordinates of points). He just needed to cope with the accumulated error in the calculations.
To initialize variables in the start of your program to insert the line
(Setq $ P000 '(0.0 0.0 0.0)
$ Dopusk 0.00001
)

Naming of variables, parameters
In the parameters of these functions are frequently used variable names.
P, P1, P2, P3 .... - Points
Pc - the central point of an arc or a circle
L, Lx, Ly, Lz - length
Wekt, Wekt1, Wekt2, WektX, WektY, WektZ, W, W1, W2-vector (the list of 3 numbers)
WNorm - normal vector. In terms of AutoCAD it comes to squeezing the direction vector, which all primitives stored under 210 associative code.
Ang - angle
R, R1, R2 - radius
================================================== ====================
Calculations of the arcs

1. Distance from a point in the plane of the arc to arc (1.zip)
2. Calculating the arc length (2.zip)
3. Calculation of the central angle of arc (3.zip)
4. Computation of the mid-point arc (4.zip)
5. Calculation of the center of the arc (the arc is defined by 2 points and the direction
tangent to the 1-th point) (5.zip)

Analysis functions belonging and intersection elements

6. Accessory points on the line, set point and the vector (15.zip)
7. Affiliation point interval (16.zip)
8. Affiliation point arc (all points in the same plane!) (17.zip)
9. Affiliation point arc (points in different planes!) (18.zip)
10. Affiliation arc arc (19.zip)

Function calculating the intersection of objects in space

11. The intersection of 2 circles given center and radius,
coplanar (10.zip)
12. The intersection of 2 circles given center and radius,
located in a given plane (11.zip)
13. Point of intersection of the line and plane (12.zip)
14. Point of intersection of the circle with the plane (13.zip)
15. Calculation of the intersection line of planes (14.zip)
16. Intersection of line and circle, lying in one plane (8.zip)
17. Intersection of line and circle, randomly located (9.zip)

General purpose functions

18. Vector product of vectors (20.zip)
19. Vector normal to the plane. The plane defined by 3 points (21.zip)
20. Calculation of the unit vector (unit vector) (22.zip)
21. Reduction of the vector to the length of 1000 (long vector) (23.zip)
22. Point lying on the point P1 at a distance L in the direction of the point P2 (24.zip)
23. Point lying on P1 at a distance L along the vector Wekt (25.zip)
24. Point, offset by a 2-m vectors (26.zip)
25. The condition of orthogonality (27.zip)
26. The angle between the vectors (29.zip)
27. The angle between the vectors in a clockwise direction from the normal (30.zip)
28. Vector angle with respect to this part of the normal (31.zip)
29. The nearest point from a given point of the segment (32.zip)
30. The distance from the point to the segment (33.zip)
31. Rotate the point around the axis (34.zip)
32. Projection of a point on the line (line set-point vector) (35.zip)
33. Projection of a point on the line (line given two points) (36.zip)
34. Projection of a point on the plane (37.zip)
35. The distance between the planes (38.zip)

Function of spatial geometry

36. Calculation of the point of contact from the point of the circle (6.zip)
37. The calculation of the points of contact to the 2-m circles (7.zip)
================================================== =======================
Вложения
Тип файла: zip 3d_lib.zip (22.2 Кб, 17 просмотров)
__________________
Как использовать код на Лиспе читаем здесь

Последний раз редактировалось VVA, 14.06.2015 в 12:18.
VVA вне форума  
 
Автор темы   Непрочитано 21.11.2009, 14:03
#3
Supermax

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


VVA, ты гений, ты это знаешь?
Так на основе последней функции можно сделать единичный вектор.
Делаем L=1 и пересчитываем ту точку, от которой делали отсчет в 0,0,0.
Функцию можно назвать points-vector.
Supermax вне форума  
 
Непрочитано 21.11.2009, 19:54
#4
zamtmn

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


>>Делаем L=1 и пересчитываем ту точку, от которой делали отсчет в 0,0,0.
чтоб получить единичный вектор, достаточно разделить каждую координату на длинну этого вектроа, ненадо ничего никуда переносить
>>Функцию можно назвать points-vector.
вообщето это называется - нормализация
Почитайте чтонибудь по геометрии, например http://algolist.ru/maths/geom/index.php, подобных вопросов возникать не будет
zamtmn вне форума  
 
Автор темы   Непрочитано 21.11.2009, 21:32
#5
Supermax

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


zamtmn,
"Чукча не читатель, Чукча - писатель!"
Цитата:
... чтоб получить единичный вектор, достаточно разделить каждую координату на длинну этого вектроа ...
Ну так раздели. Сделай доброе дело, напиши функцию.
Видишь, я функции граблями пишу, а люди (VVA) - душою.
Или у тебя тоже грабли?
Supermax вне форума  
 
Непрочитано 21.11.2009, 22:03
#6
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,843


Честно говоря прочитал через строку - если нужна функция получения единичного вектора - "моя бибилиотечная":
Код:
[Выделить все]
(defun getvektor (pt1 pt2 / tmp); единичный вектор направления заданный точками pt1 pt2.
(setq tmp (mapcar '- pt1 pt2))
(if (not (equal tmp '(0.0 0.0 0.0)))
(mapcar '(lambda (x) (/ (float x) (apply 'max (mapcar 'abs tmp)))) tmp)
);end of if
);end of getvektor
получаеться единичный вектор (типа того что лежит в 210 DXF'e)
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Автор темы   Непрочитано 22.11.2009, 12:45
#7
Supermax

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


О! Укуси меня пчела!
Ну, наверное надо тему переименовать в "Тригонометрические функции"
Мне еще надо превращать единичный вектор оси Z объекта, который 210 парой показывается в:
1: Его атипод (-Z)
2: Вектор абсцисс (Х)
3: Антипод абсцисс (-Х)
4: Вектор ординат (Y)
5: Антипод ординат (-Y)

Вот в MTEXT-е 11 пара - вектор абсцисс объекта MTEXT. А в других объектах его нет, надо вычислять.

Нужна функция, которая по начальной точке, вектору и длинне дает координаты точки.

Нужны еще несколько функций и в Автокаде можно будет крутить-вертеть все, что угодно.

Дима_, только надо pt1 и pt2 местами поменять. первая точка должна быть "из", а вторая "в", а не наоборот.

Последний раз редактировалось Supermax, 22.11.2009 в 13:02.
Supermax вне форума  
 
Непрочитано 22.11.2009, 14:28
#8
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,843


Возможно - я его писал когда нужно было смоделировать плоскую модель тела при просмотре с некого вектора - видимо поэтому и получилось "наоборот" - это просто с какой стороны смотреть.
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 22.11.2009, 18:10
#9
zamtmn

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


>>Ну, наверное надо тему переименовать в "Тригонометрические функции"
тригонометрия - sin, cos и т.д., такчто переименовать лучше чтоб в названии векторная алгебра фигурировала

>>Или у тебя тоже грабли?
к сожалению на лиспе ни граблями ни чем другим не умею))

>>Вот в MTEXT-е 11 пара - вектор абсцисс объекта MTEXT. А в других объектах его нет, надо вычислять.
в других объектах есть угол поворота, вычисление 0x в этом случае описано в разделе arbitrary axis algorithm DXF Reference
zamtmn вне форума  
 
Автор темы   Непрочитано 22.11.2009, 18:20
#10
Supermax

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


Чую и синусы понадобятся.
А про песчет векторов с учетом угла поворота - ссылочку плииз!
В MTEXT и угол поворота есть и х-вектор и z-вектор. А нужны все, и не для коллекции.
Supermax вне форума  
 
Непрочитано 22.11.2009, 18:44
#11
VVA

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


DwgRuLispLib: Тригонометрические функции
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Непрочитано 22.11.2009, 19:01
#12
zamtmn

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


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

>>А про песчет векторов с учетом угла поворота - ссылочку плииз!
ссылочки нету, но если нужно получить 0x из угла поворота(u):
0x=(cos(u),sin(u),0) это если 0z=0,0,1
если нет, сначала нужно получить 0x используя arbitrary axis algorithm, потом повернуть его на угол u вокруг 0z

>>В MTEXT и угол поворота есть и х-вектор и z-вектор. А нужны все, и не для коллекции.
насколько помню, в MTEXT - угол поворота и ox - одно и тоже
если есть 0x,0z, то 0y - векторное произведение 0x и 0z (нужно промнить что векторное произведение зависит от мерестановки мест, какая последовательность 0x*0z или 0z*0x я не помню)

>>Нужны еще несколько функций и в Автокаде можно будет крутить-вертеть все, что угодно.
чтобы крутить всё что угодно нужно:

векторное произведение
скалярное произведение
умножение вектора на матрицу
умножение матрицы на матрицу
создание матрицы поворота вокруг 0x
создание матрицы поворота вокруг 0y
создание матрицы поворота вокруг 0z
создание матрицы поворота вокруг произвольного вектора

лисп насколько понимаю - очень неудобный для этого язык

Последний раз редактировалось zamtmn, 22.11.2009 в 19:26.
zamtmn вне форума  
 
Автор темы   Непрочитано 22.11.2009, 20:23
#13
Supermax

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


Ну зачем так сложно? В Автокаде все уже почти есть.
Воспользуемся услужливо нам даденным MTEXT-ом.
Создаем временный объект с точкой вставки 0,0,0 и задаем ему угол поворота и вектор, получаем из 11 пары вектор Х. Крутим вокруг него на 90 гр. и получаем Y. антиподы делаются простой сменой знаков.
Supermax вне форума  
 
Непрочитано 22.11.2009, 20:27
#14
zamtmn

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


>>Ну зачем так сложно? В Автокаде все уже почти есть.
>>Воспользуемся услужливо нам даденным MTEXT-ом.

Ну я бы не сказал что создать объект проще чем сделать несколько векторных произведений, такой подход с добру не приведет
zamtmn вне форума  
 
Автор темы   Непрочитано 22.11.2009, 20:33
#15
Supermax

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


Так дай пару формул. В лиспе есть и синусы косинусы. Все есть.
И завязывай цитировать, раздрожает.
Supermax вне форума  
 
Непрочитано 22.11.2009, 20:35
#16
zamtmn

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


пару формул для чего?
zamtmn вне форума  
 
Непрочитано 22.11.2009, 20:40
#17
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 36,741


не очень понимаю, чем trans не угодил? Или это вообще не в теме?
__________________

---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 22.11.2009, 20:40
#18
Supermax

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


Ну, типа, дан единичный вектор Z и угол поворота вокруг него. Надо найти координату оси Х и т.д.
Ясно дело, если угол = 0, то Х= (1,0,0), а если не нулю?

Кулик Алексей aka kpblc , не, не угодил. Он переводит пользовательские координаты в мировые и обратно, ну еще экранные. А тут речь идет о том, в какую сторону откладывать расстояние, если тебе дана не та ось, что тебе надо.
Вот сделай MTEXT, поверни его в нескольких плоскостях и попробуй сделать вокруг него рамку.
И GetBoundingBox тебе не поможет.
Supermax вне форума  
 
Непрочитано 22.11.2009, 21:08
#19
zamtmn

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


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

>>Ясно дело, если угол = 0, то Х= (1,0,0), а если не нулю?
нет, 0x зависит не только от угла но и от нормали (группа 210 помоему)
zamtmn вне форума  
 
Непрочитано 22.11.2009, 21:10
#20
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 36,741


Можно, конечно Векторное произведение я как-то делал (да и так, если порыскать, думаю, найти можно). А преобразование координат можно выполнять либо через trans, либо через TransformationMatrix (кажется, так).
__________________

---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 22.11.2009, 21:43
#21
zamtmn

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


ок. на входе имеем Local.oz - нормаль, rotate - угол поворота. расчитываем Local.ox, Local.oy и матрицу перевода мировых координат в систему координат блока. матрицы приняты 4х мерными.

используя arbitrary axis algorithm считаем неповернутые Local.ox, Local.oy, тут YWCS и ZWCS соответственно равны 0,1,0 и 0,0,1
Код:
[Выделить все]
     if (abs (Local.oz.x) < 1/64) and (abs (Local.oz.y) < 1/64) then
                                                                    Local.ox:=CrossVertex(YWCS,Local.oz)
                                                                else
                                                                    Local.ox:=CrossVertex(ZWCS,Local.oz);
     Local.oy:=CrossVertex(Local.oz,Local.ox);
затем учитываем точку вставки блока (формируем матрицу поворота и умножаем ее на матрицу перемещения):
Код:
[Выделить все]
     rotmatr:=onematrix;
     PGDBVertex(@rotmatr[0])^:=Local.ox;
     PGDBVertex(@rotmatr[1])^:=Local.oy;
     PGDBVertex(@rotmatr[2])^:=Local.oz;

     dispmatr:=onematrix;
     PGDBVertex(@dispmatr[3])^:=Local.p_insert;
     objmatrix:=MatrixMultiply(dispmatr,rotmatr);
objmatrix - матрица перехода от wcs к ocs, но она пока не учитывает rotate. формируем матрицу поворота и домножаем на нее

Код:
[Выделить все]
  m1:= OneMatrix;
  m1[0,0]:=cos(rotate*pi/180);
  m1[1,1]:=cos(rotate*pi/180);
  m1[1,0]:=-sin(rotate*pi/180);
  m1[0,1]:=sin(rotate*pi/180);
  objMatrix:=MatrixMultiply(m1,objMatrix);
выдергиваем оси системы координат объекта из матрицы
Код:
[Выделить все]
     Local.ox:=PGDBVertex(@rotmatr[0])^;
     Local.oy:=PGDBVertex(@rotmatr[1])^;
     Local.oz:=PGDBVertex(@rotmatr[2])^;
zamtmn вне форума  
 
Автор темы   Непрочитано 22.11.2009, 21:49
#22
Supermax

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


Вообще-то проще 6 раз перейти из одного пользовательского пространства в другое и списать значения 210 пары переведенные в ПСК.
Чего голову морочить?
Правда если модель перегружена объектами могут тормоза начаться, но можно попытаться.
Можно из линий ежика сделать, объединить их в блок, развернуть и взорвать, получив координаты концов линий.
Что-то чую я, трудно будет математикой это сделать.
Supermax вне форума  
 
Непрочитано 22.11.2009, 22:03
#23
zamtmn

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


математикой это сделать просто, а вот на лиспе возможно трудно если матриц нет
хотя по любому должны быть уже готовые методы без создания объектов
zamtmn вне форума  
 
Автор темы   Непрочитано 22.11.2009, 23:18
#24
Supermax

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


Вот, сделано через Ж, но работает.
Код:
[Выделить все]
(vl-load-com)
(defun vektor-translate (vect ugol / actdoc modeltxt blockkoll blc-obj-txt blc-obj-3
o-point spis-var blk-ins spis-line spis-vekt a) 
(setq actdoc (vla-get-ActiveDocument (vlax-get-acad-object)))
(setq modeltxt (vla-get-ModelSpace actdoc))
(setq blockkoll (vla-get-Blocks actdoc))

(setq blc-obj-1 (vla-Add blockkoll (vlax-3D-point '(0.0 0.0 0.0)) "temp-block-txt"))
(setq blc-obj-2 (vla-Add blockkoll (vlax-3D-point '(0.0 0.0 0.0)) "temp-block-2"))
(vla-InsertBlock blc-obj-1 (vlax-3D-point '(0.0 0.0 0.0)) "temp-block-2" 1 1 1 0.0)
(vlax-for x (vla-Item blockkoll "temp-block-txt") (setq blc-obj-3 x))


(setq o-point (vlax-3D-point '(0.0 0.0 0.0)))
(setq spis-var (mapcar 'vlax-3D-point '((0.0 0.0 1.0) (0.0 0.0 -1.0) 
                                        (1.0 0.0 0.0) (-1.0 0.0 0.0) 
                                        (0.0 1.0 0.0) (0.0 -1.0 0.0))))

(mapcar '(lambda (a) (vla-AddLine blc-obj-2 o-point a)) spis-var)

(vla-put-Rotation blc-obj-3 ugol)
(vla-put-Normal blc-obj-3 (vlax-3D-point vect))
;сначала надо поворачивать, а уж потом менять нормаль
(setq spis-line (vlax-safearray->list (vlax-variant-value (vla-Explode blc-obj-3))))
(setq spis-vekt (mapcar '(lambda (a) (vlax-safearray->list (vlax-variant-value (vla-get-EndPoint a)))) spis-line))
(mapcar 'vla-Delete spis-line)
(vla-Delete blc-obj-3)
(vla-Delete blc-obj-1)
(vla-Delete blc-obj-2)
(setq a spis-vekt)
)
Даем единичный вектор (нормаль) и угол
Получаем (z (то есть то, что дали) -Z X -X Y -Y)
Пример
(vektor-translate '(-0.34202 0.0 0.939693) 1.91986)
Получаем:
((-0.34202 0.0 0.939693) (0.34202 0.0 -0.939693) (0.883023 0.342018 0.321394) (-0.883023 -0.342018 -0.321394) (-0.321392 0.939693 -0.116977) (0.321392 -0.939693 0.116977))

Чуток подправил функцию. Теперь она просто летает, поскольку не прорисовывает.
Создаем блок, в нем другой блок, там его крутим и все удаляем. Все происходит чисто в памяти, без вывода графики на экран, как раньше.

Последний раз редактировалось Supermax, 23.11.2009 в 03:31.
Supermax вне форума  
 
Непрочитано 23.11.2009, 09:15
#25
Елпанов Евгений

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


Supermax, Привет!

Я честно пытался понять, что же необходимо получить. Прочел тему полтора раза, но не понял. Нахождение векторов, их преобразование и вращение, можно делать гораздо проще. Как уже говорилось, либо по формулам аффинных преобразований, либо через векторы и функцию trans. Поясните для меня, что именно необходимо получить...
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны.
/Сунь Цзы/
Елпанов Евгений вне форума  
 
Непрочитано 23.11.2009, 10:00
#26
VVA

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


Я дочитал еще те 0.5 раза, которые не смог Евгений и так же не понял
По поводу trans, OCS и 3D у меня в закладках потрясающая и исчерпывающая тема gile. Там требуется регистрация, но советую почитать.
About trans and OCS in 3D
Пример оттуда. Получет вектор, который пишется в 210 поле
Код:
[Выделить все]
(setq ucszdir (trans '(0 0 1) 1 0 T))
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Автор темы   Непрочитано 23.11.2009, 10:19
#27
Supermax

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


Поясняю (ну как смогу, конечно).
Что такое 210 пара? Можно много красивых слов находить, но по детски очень трудно сформулировать. 210 пара - ось Z объекта в сторону положительных значений.
Берем любой примитив, лучше МTEXT, поворачиваем его туда-сюда и наигравшись смотрим куда смотрит его ось Z, тобишь, читаем значение нормали (210 пары). Что такое единичная сфера и единичный вектор смотрим в википидии.
Но положение тела в пространстве определяется не только точкой вставки и ориентацией Z оси объекта, а еще и углом поворота вокруг этой оси. Хотя можно задавать просто две точки, как в MTEXT-е (210 и 11 пары).

Мне надо отложить по оси Y объекта необходимую длинну. Для этого мне надо определить, куда смотрит ось Y объекта. Имея единичный вектор, который соответствует оси ординат объекта я могу строить вокруг него нужные мне геометрические фигуры, как бы он не был повернут в пространстве.

Да я тупо сделал функцию. Нарисовал "ежик" с 6-ю лучами и задавая ему поворот и направление нормали получаю все 6 векторов.
Есть один вектор и угол поворота вокруг него, надо найти все остальные вектора.
Да гляньте вы на список, что возвращается. если Z = первой координате, то -Z - второй и все остальные тоже отличаются только знаками.
Миниатюры
Нажмите на изображение для увеличения
Название: ежик.JPG
Просмотров: 105
Размер:	14.4 Кб
ID:	29414  

Последний раз редактировалось Supermax, 23.11.2009 в 10:46.
Supermax вне форума  
 
Непрочитано 23.11.2009, 10:55
#28
zamtmn

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


кстати отрицательные значения не нужны, они автоматом получатся при откладывании отрицательной длины в нужном направлении
имеем единичный вектор dir нужного направления, нужно отложить 5 едениц в обе стороны
dir*5 в положительном
dir*(-5) в отрицательном
zamtmn вне форума  
 
Непрочитано 23.11.2009, 11:23
#29
Елпанов Евгений

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


Цитата:
Сообщение от Supermax Посмотреть сообщение
Что такое 210 пара?
Это вектор, причем ничего не мешает использовать "длинный" вектор, т.е. его длина не обязательно должна равняться единице! Это верно для всех примитивов акада...
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны.
/Сунь Цзы/
Елпанов Евгений вне форума  
 
Автор темы   Непрочитано 23.11.2009, 11:45
#30
Supermax

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


Цитата:
причем ничего не мешает использовать "длинный" вектор, т.е. его длина не обязательно должна равняться единице! Это верно для всех примитивов акада...
Ты хочешь сказать, что в 210 пару или свойство Normal можно записывать значения не единичной сферы?
Для ручного указания направления сойдет что угодно, а для изменения ориентации объекта? Допустим, мне надо повернуть объект вокруг его оси X на 90 градусов по часовой стрелке.

Лишние направления не лишни. Даже первый список, который вегда равен тому, который задаешь аргументом не грех сравнивать с исходным.
Вот кто мне скажет почему надо сначала поворачивать, а потом менять нормаль?
В свойстве "Rotation" ведь указан поворот вокруг оси, которая задана нормалью. Если нормаль крутишь-вертишь он не меняется, а стоит его поменять - нормаль летит к чертям.
Вот переставьте в моей функции вот эти две строчки местами.
Код:
[Выделить все]
(vla-put-Rotation blc-obj-3 ugol)
(vla-put-Normal blc-obj-3 (vlax-3D-point vect))
Supermax вне форума  
 
Непрочитано 23.11.2009, 12:03
#31
zamtmn

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


>>Вот кто мне скажет почему надо сначала поворачивать, а потом менять нормаль?

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

Последний раз редактировалось zamtmn, 23.11.2009 в 12:16.
zamtmn вне форума  
 
Непрочитано 23.11.2009, 12:18
#32
Елпанов Евгений

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


Цитата:
Сообщение от Supermax Посмотреть сообщение
Ты хочешь сказать, что в 210 пару или свойство Normal можно записывать значения не единичной сферы?
Да, я именно это и говорю!
Попробуй для любого объекта задать длинный вектор или как вариант - удлинить его..
Как пример - удлиняем вектор в 11 раз:
Код:
[Выделить все]
(if (setq e (car (entsel)))
 (entmod (subst (cons 210 (mapcar '* (cdr (assoc 210 (entget e))) '(11. 11. 11.)))
                 (assoc 210 (entget e))
                 (entget e)
         ) ;_  substr
 ) ;_  entmod
)
Кстати, при следующем запросе, автокад сам даст единичный вектор.
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны.
/Сунь Цзы/
Елпанов Евгений вне форума  
 
Автор темы   Непрочитано 23.11.2009, 12:44
#33
Supermax

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


zamtmn, не, "ты Борис не прав". Угол, что значится в свойстве Rotation ни к каким пространствам отношения не имеет. Он (по идее) всегда обозначает поворот вокруг нормали. То есть вокруг оси Z объекта.
В какую ты систему не пересчитывай нормаль, а угол всегда один и тот же. Но процесс установки угла и нормали, если это делать путем замены точечных пар, у блока, к примеру, сбивает настройку точки вставки. Причем в 10 паре указано одно, а vla-get-InsertionPoint показывает совсем другое. И врет при этом 10 пара. Если сделать vla-put... то блок становится на свое место, а 10 пара, угол поворота и нормаль остаются прежними.
Глюки, короче.
Тут тоже видимо глюк. Этот Rotation, ведет себя так, буд-то объект вращают вокруг оси Z пространства, где расположен объект.
Я правда только на блоках и MTEXT-ах практиковался.

Елпанов Евгений, ценная инфа, могет пригодиться. Правда в свете глюковатости самого када, как бы глюков не прибавилось.
Supermax вне форума  
 
Непрочитано 23.11.2009, 12:55
#34
zamtmn

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


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

Не знаю как в лиспе а в dxf файле значение точки вставки хранится в системе координат объекта, такчто ее тоже нужно пересчитывать в мировую систему, приведеные мной выше куски кода работают при чтении dxf файла, возможно в лиспе точка вставки автоматом переведена в МСК
zamtmn вне форума  
 
Непрочитано 23.11.2009, 13:04
#35
Елпанов Евгений

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


Supermax, Есть одна тонкость, но ее необходимо учитывать и при передаче единичного вектора. Если ты присваиваешь одинаковый вектор нормали нескольким объектам и для каждого объекта вычисляешь этот вектор заново, может оказаться, что объекты лежат в разных плоскостях и соответственно не могут пересекаться, объединяться и.т.д... А всему виной точность. Т.е. в одном месте будет 0.0 а в другом 1е-16. и уже разные вектора.

Я, обычно, использую небольшое округление векторов. Это позволяет меньше зависеть от точности акада...
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны.
/Сунь Цзы/
Елпанов Евгений вне форума  
 
Непрочитано 23.11.2009, 13:19
#36
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,843


То Supermax - 10 пара не врет ее надо пересчитывать trans'ом.
p.s. Посмотри внимательно в dxf reference line ... 10 WCS circle 10 - OCS
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 23.11.2009, 13:33
#37
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 36,741


point -> WCS
insert -> OCS

Я у себя на сайте по этому вопросу развлекался...
__________________

---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 23.11.2009, 14:41
#38
Sleekka

-
 
Регистрация: 24.07.2005
Москва
Сообщений: 1,455


to Supermax
если тебе надо сделать boundingBox для повернутого mtexta то оно вот, спасибо VVA. - это функция из экспресс тулз, что подается ей на вход остается только гадать, но вот так работает:
Код:
[Выделить все]
(acet-geom-textbox (entget (vlax-vla-object->ename x)) 1e-3)
если тебе нужны функции векторного произведения, то опубликую здесь коды Gile с Theswamp.org:
Код:
[Выделить все]
;;; VEC1 Returns the single unit vector from p1 to p2
(defun vec1 (p1 p2)
  (if (not (equal p1 p2 1e-009))
    (mapcar
      '(lambda (x) (/ x (distance p1 p2)))
      (mapcar '- p2 p1)
    )
  )
)


;;; NORM_3PTS Returns the normal vector of the plane defined by 3 points
;;; Respects the "right hand rule" with p0 as origin
(defun norm_3pts (p0 p1 p2 / norm)
  (cond
    ((inters p0 p1 p0 p2)
     (foreach p	'(p1 p2)
       (set p (mapcar '- (eval p) p0))
     )
     (setq norm	(list (- (* (cadr p1) (caddr p2)) (* (caddr p1) (cadr p2)))
		      (- (* (caddr p1) (car p2)) (* (car p1) (caddr p2)))
		      (- (* (car p1) (cadr p2)) (* (cadr p1) (car p2)))
		)
	   norm	(mapcar	'(lambda (x) (* x (/ 1 (distance '(0 0 0) norm))))
			norm
		)
     )
    )
  )
)


;;; UCSZDIR Returns the Normal Unit Vector of the current UCS
(defun ucszdir  ()
  (trans '(0 0 1) 1 0 T)
)


;;; ASIN Returns the arcsinus of a number in radians
(defun ASIN (num)
  (if (<= -1 num 1)
    (atan num (sqrt (- 1 (expt num 2))))
  )
)

;;;ACOS Returns the arccosinus of a number in radians
(defun ACOS (num)
  (if (<= -1 num 1)
    (atan (sqrt (- 1 (expt num 2))) num)
  )
)

;;; ANGLE_3PTS Returns the angle (in radians) defined by its summit and two points
;;; Returned angle is always positive and less than or equal to pi radians.

;; Using vector calculus
(defun angle_3pts (sum p1 p2 / v1 v2)
  (if (and
	(setq v1 (vec1 sum p1))
	(setq v2 (vec1 sum p2))
      )
    (cond
      ((equal v1 v2 1e-009) 0.0)
      ((equal v1 (mapcar '- v2) 1e-009) pi)
      (T (* 2 (asin (/ (distance v1 v2) 2))))
    )
  )
)

;; Using the "Theoreme de Carnot"
(defun angle_3pts (sum p1 p2 / d1 d2 d3)
  (setq	d1 (distance sum p1)
	d2 (distance sum p2)
	d3 (distance p1 p2)
  )
  (if (and (not (zerop d1)) (not (zerop d2))
    (ACOS (/ (+ (* d1 d1) (* d2 d2) (- (* d3 d3)))
	     (* 2 d1 d2)
	  )	
    )
  )
)
  )


;;; ELEV Returns the elevation of point pt from the plane defined by p1 p2 p3

(defun elev (pt p1 p2 p3)
  (* (cos (angle_3pts p1 (mapcar '+ p1 (norm_3pts p1 p2 p3)) pt))
     (distance p1 pt)
  )
)


;;; PROJ_PT Returns the coordinates of the projection of point pt
;;; on the plane defined by the points p1 p2 p3.

(defun proj_pt (pt p1 p2 p3)
  (mapcar '-
	  pt
	  (mapcar '(lambda (x) (* x (elev pt p1 p2 p3)))
		  (norm_3pts p1 p2 p3)
	  )
  )
)
Sleekka вне форума  
 
Непрочитано 24.11.2009, 11:50
#39
Pastor

это только кличка
 
Регистрация: 22.10.2006
Москва
Сообщений: 252


Может кому пригодится.
http://www.caduser.ru/forum/index.ph...D=44&TID=41129
http://www.caduser.ru/forum/index.ph...D=44&TID=27943
__________________
...в шее моей жилы железные, и лоб мой - медный...
Pastor вне форума  
 
Автор темы   Непрочитано 24.11.2009, 18:11
#40
Supermax

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


zamtmn,
Цитата:
...в системе координат блока угол это поворот вокруг 0,0,1, а в мировой системе системе поворот вокруг нормали блока. при переходе между системами значение угла не меняется...
А я очем?, Я о том же. Только маленькая поправка
Изменение этого параметра никоим образом не должно изменять значение нормали объекта. Куда ось Z объекта была направлена, туда и должна остаться быть направленной. А она рушиться. И точка вставки блока порою улетает. Во!

Sleekka,

Функция acet-geom-textbox написана без учета глючности Автокада. Если объект не повернут - она работает, а если повернут в двух плоскостях - рамка улетает черт знает куда (при объекте MTEXT).
Код:
[Выделить все]
(vl-load-com)
(setq modelsp (vla-get-ModelSpace (vla-get-ActiveDocument (vlax-get-acad-object))))
(setq ramka (acet-geom-textbox (entget (car (entsel))) 0))
(setq ramka (append ramka (list (car ramka))))
(setq ramka (mapcar '(lambda (a) (trans a 1 0)) ramka))
(vla-Add3DPoly modelsp (vlax-safearray-fill (vlax-make-safearray vlax-vbDouble '(0 . 14)) (apply 'append ramka)))
Второй аргумент функции - offset контура текста в виде множителя к шрифта, которым набран текст. Если height текста = 2,5 мм, то при значении 1 второго аргумента функции, рамка будет больше на 2,5мм по контуру.

Немного размерность массива подправил.

Причем! Если объект TEXT - все тип топ. А если MTEXT - и в 2006, и в 2007, и в 2010 - рамка улетает вниз.
Уж от типа объекта все никак не должно зависить.

Еще малость изменил, чтобы рамку рисовало из любой ПСК. Надо наверное и в функцию оформить.

Sleekka, будь добр, переведи на русский язык функции и укажи значения аргументов. Я в первом посте ссылку дам. Сам я все понял, но "надо Федя, надо".

Pastor, спасибо за вклад.

Последний раз редактировалось Supermax, 24.11.2009 в 19:42.
Supermax вне форума  
 
Непрочитано 24.11.2009, 18:57
#41
zamtmn

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


>>Изменение этого параметра никоим образом не должно изменять >>значение нормали объекта. Куда ось Z объекта была направлена,
>>туда и должна остаться быть направленной. А она рушиться.
>>И точка вставки блока порою улетает. Во!

Не факт, но я думаю:
Положение тела в 3D однозначно задоется 3мя базисными векторами, 0x,0y,0z (вернее сказать 2мя, т.к. третий всегда можно посчитать по 2 изза взаимоортогональности)
Угол - это угол между 0x фактической 0x расчитаной по arbitrary axis algorithm, когда ты меняешь нормаль - угол может поменяться, а ты ему присваиваешь старое значение - вот всё и летит.
Угол нужен только в 2д, там с ним всё понятно, в 3д - он только мешает, т.к. не матрица преобразования расчитывается по углу, а угол расчитывается из матрицы преобразований.
zamtmn вне форума  
 
Непрочитано 24.11.2009, 19:13
#42
Елпанов Евгений

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


На этом форуме, встречается мой код, для вставки блока с поворотом вокруг произвольной оси. Вставка выполняется с отслеживанием курсора, через grread. Создавая этот код я столкнулся с проблемой - при указании угла поворота в произвольной системе координат, угол отличается от подразумевавшегося. т.е. если блок находится в точке не лежащей на XY мировой и нормаль отличается от мировой, то указывая точку на экране не так просто вычислить действительный угол поворота в плоскости блока. Для этой цели, я переводил указанную точку в систему координат экрана, далее вычислял еще одну точку, в которой z была другой, но xy в экранной системе координат совпадали. Далее, находил точку пересечения плоскости блока с линией, заданной этими двумя точками. Угол в системе координат блока, относительно оси Х и вектором из точки вставки и найденной точкой и давали искомый угол.
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны.
/Сунь Цзы/
Елпанов Евгений вне форума  
 
Непрочитано 24.11.2009, 19:30
#43
zamtmn

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


А почему вообще есть только угол? совместимость со старыми версиями?
Мтекст сравнительно новый приметив - у него всё ок
Если на лиспе можно получить матрицу трансформации объекта, из нее легко можно выдрать базисные вектора
zamtmn вне форума  
 
Непрочитано 24.11.2009, 19:55
#44
Елпанов Евгений

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


Цитата:
Сообщение от zamtmn Посмотреть сообщение
Если на лиспе можно получить матрицу трансформации объекта, из нее легко можно выдрать базисные вектора
матрица трансформации не хранится в объекте, а услужливо вычисляется при запросе.

хотя...
Контура подрезки xclip хранят в своих dxf кодах матрицы, причем сразу две матрицы 4х4, одна для подрезаемого объекта, вторая для самого контура подрезки.

ps. Конечно, матрицы хранятся не в самих объектах, а в словарях, как впрочем и контура...
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны.
/Сунь Цзы/
Елпанов Евгений вне форума  
 
Непрочитано 24.11.2009, 20:01
#45
zamtmn

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


>>матрица трансформации не хранится в объекте, а услужливо вычисляется при запросе.
ИМХО Это угол не хранится, а услужливо вычисляется (под объектом я подразумеваю не то что видно в лисп, а то что действительно лежит в закрамах автокада), без матриц в 3d графике шагу ни ступить.
zamtmn вне форума  
 
Автор темы   Непрочитано 24.11.2009, 20:31
#46
Supermax

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


zamtmn,
Цитата:
Положение тела в 3D однозначно задоется 3мя базисными векторами, 0x,0y,0z (вернее сказать 2мя, т.к. третий всегда можно посчитать по 2 изза взаимоортогональности)
Или одним и углом поворота вокруг него, что собственно в Автокаде и присутствует.

Цитата:
Угол - это угол между 0x фактической 0x расчитаной по arbitrary axis algorithm, когда ты меняешь нормаль - угол может поменяться, а ты ему присваиваешь старое значение - вот всё и летит.
Не, ты о другом угле говоришь. В свойствах объектов типа MTEXT Rotation - это угол поворота вокруг нормали. Там вообще кроме вектора нормали, точки вставки и угла поворота вокруг нормали ничего нет. Хотя вру, в MTEXT есть еще вектор оси абсцисс.

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

Цитата:
И кто мне объяснит, почему в 3D полилинии свойства Normal нет, а в простой линии и в 2D полилинии есть? Какого фига ее туда запихнули? Если объект можно описать расположением точек в пространстве МСК, зачем ему нормаль?
Устарело. В 3D полилинии нет свойства Normal, зато 210 точечная пара есть!

Цитата:
Мтекст сравнительно новый приметив - у него всё ок
Ага, а почему на нем не работает acet-geom-textbox корректно?
И почему изменение свойства Rotation в объекте TEXT нормаль не меняет, а в MTEXT меняет?

Елпанов Евгений, о, как я тебя понимаю! Через экран? Это круто!

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

Вот не только MTEXT страдает глюком, блоки тоже не хотят крутится вокруг нормали, еще и труднопредсказуемым перемещением страдают.

Люди! Если вы, по случайности, залезли в свойство Rotation объектов Автокада, не забудьте после этого восстановить нормаль и точку вставки.

Последний раз редактировалось Supermax, 24.11.2009 в 20:52.
Supermax вне форума  
 
Непрочитано 24.11.2009, 20:57
#47
zamtmn

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


>>Или одним и углом поворота вокруг него, что собственно в Автокаде и присутствует.
Да елки палки, чтоб этот угол применить надо:
знать вокруг чего вращат - знаем (нормаль);
исходное состояние которое вращаем - его не знаем!
тут вся хитрость - исходное состояние это расчет оси 0x описаный а dxf справке. меняем нормаль - меняется эта расчетная 0х - соответственно угол если его не пересчитать становится пальцем в небо;

Почувствуй разницу между окружностью и блоком
окружность симетрична вокруг нормали - для описания хватает одной оси z
блок не симетричен, нужно 2(3) оси, во времена доса память экономили - придумали этот хитрый способ с осью и углом (экономия 40 байт на объект)
еще пример - допустим нормаль равна 1,0,0 - чему равна исходная ось x которую надо повернуть на извесный угол?

>>И кто мне объяснит, почему в 3D полилинии и в 2D полилинии свойства Normal нет, а в простой линии есть?
в 2d полилинии есть (у нее своя соординаиная система), в линии и 3д полилинии нет (они в wcs)

ИМХО:
при 3д повороте блока в автокаде (при черчении) блок трансформируется матрицей - одновременно меняются базисные оси, точка вставки, потом считается угол.
ты пытаешся воспроизвести это пошагово,
1. 3Д вращательные операции не комутативны - результат зависит от порядка применения
2. нет гарантий что на каждом шаге умный автокад не пересчитывает чтото за тебя - типа точки вставки при изменении нормали
отсюда "глюки"

Последний раз редактировалось zamtmn, 24.11.2009 в 21:17.
zamtmn вне форума  
 
Автор темы   Непрочитано 24.11.2009, 21:42
#48
Supermax

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


zamtmn, опять не-е-е.
Цитата:
Да елки палки, чтоб этот угол применить надо:
знать вокруг чего вращат - знаем (нормаль);
исходное состояние которое вращаем - его не знаем!
тут вся хитрость - исходное состояние это расчет оси 0x описаный а dxf справке. меняем нормаль - меняется эта расчетная 0х - соответственно угол если его не пересчитать становится пальцем в небо;
А про точку вставки забыл? Положение объекта в Автокаде определено точкой вставки, нормалью и углом поворота вокруг нее. Это что касается сложных объектов, а простые - описанием точек объекта. Повернул - описание изменилось. Только в 2D полилинии и линии с нормалью перестарались, хотя можно узнать в какой плоскости объект был создан изначально.

Цитата:
при 3д повороте блока в автокаде (при черчении) блок трансформируется матрицей - одновременно меняются базисные оси, точка вставки, потом считается угол.
ты пытаешся воспроизвести это пошагово,
1. 3Д вращательные операции не комутативны - результат зависит от порядка применения
2. нет гарантий что на каждом шаге умный автокад не пересчитывает чтото за тебя - типа точки вставки при изменении нормали
отсюда "глюки"
Да ничего я пошагово не пытаюсь изменить. Мне доступны всего три свойства объекта, при помощи которых я могу изменить положение и ориентацию объекта. А в некоторых случаях и их нет. В какой последовательности их менять по всем законам математики не имеет значение, а на деле - имеет.

Маленькая функция на основе моей vektor-translate:
Возвращает точку вставки объекта и три его единичных вектора (X Y Z) (естественно в МСК).
Если точки вставки нет, то за точку вставки принимается (0.0 0.0 0.0)
Если угла нет, то при расчете угол равен 0.0
(может так станет всем понятно что мне надо)
Применение: (vectors-x-y-z (car (entsel)))
Код:
[Выделить все]
(vl-load-com)
(defun vectors-x-y-z (obj / a norm ugol inspoint listvect)
(setq norm (cdr (assoc 210 (entget obj))))
(if (vlax-property-available-p (vlax-ename->vla-object obj) 'Rotation)
(setq ugol (vla-get-Rotation (vlax-ename->vla-object obj))) (setq ugol 0.0))
(if (vlax-property-available-p (vlax-ename->vla-object obj) 'InsertionPoint)
(setq inspoint (vlax-safearray-list (vlax-variant-value (vla-get-InsertionPoint (vlax-ename->vla-object  obj)))))
(setq inspoint  '(0.0 0.0 0.0)))
(setq listvect (vektor-translate norm ugol))
(setq a (append (list  inspoint (caddr listvect) (car (cddddr listvect)) (car listvect))))
)

Последний раз редактировалось Supermax, 24.11.2009 в 21:54.
Supermax вне форума  
 
Непрочитано 24.11.2009, 22:03
#49
zamtmn

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


>>А про точку вставки забыл? Положение объекта в Автокаде определено точкой вставки, нормалью и углом поворота вокруг нее

Нет, не забыл. я имел ввиду поворотную ориентацию объекта.
еще пример неоднозначности нормали и угла и зависимость угла от нормали:
Втыкаем вилку в монитор - это будет нормаль
1 - поворачиваем вилку чтоб смотрела вертикально вверх, не вращая
2 - поворачиваем вилку чтоб смотрела влево , не вращая
3 - поворачиваем вилку в исходное положение (чтоб смотрела вперед) , не вращая
вилка в исходном положении, вращения вокруг вилки небыло, почему монитор набоку и вилка повернута?

edit:
вот еще цитата про X-axis dir из описания мтекста в OpenDWG R13/R14/R2000/R2004/R2007 File Format Specification
Цитата:
Apparently the text x-axis vector. (Why not just a rotation?) ACAD maintains it as a unit vector.
т.е. люди тоже не догнали зачем автодеск отступил в этом примитиве от своих традицый

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

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


Э! Ты меня так просто не поймаешь! Ты его поворачиваешь сначала вокруг оси X МСК, затем вокруг оси Z МСК, а потом вокруг оси Y МСК, так чего ты хочешь? Ты на него сначала смотришь в фас, затем снизу, затем опять снизу, затем опять в фас, но с поворотом.

Если поворачивать монитор не от себя вертикально, а от себя влево под 45 градусов, то он должен (если нет поворота) стать на угол, а у тебя при прохождении 45 градусов, во время поворота влево он все время смотрит на тебя боком. Вот тут он у тебя и вращается!

Последний раз редактировалось Supermax, 24.11.2009 в 23:18.
Supermax вне форума  
 
Непрочитано 24.11.2009, 22:57
#51
zamtmn

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


в чем прикол? у меня всё ок, накопилась небольшая ошибка

-2.44921e-016 - погрешность, обычное дело
zamtmn вне форума  
 
Автор темы   Непрочитано 24.11.2009, 23:05
#52
Supermax

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


Ага, за один поворот 2 миллиметра по оси Y
за еще один поворот на 360
(210 0.0 -4.89843e-016 1.0)
Возьми и построй линию из этих координат в точку 0,0,0
А по тексту не скажешь, что он повернут.

В этой паре вообще не должно быть цифр выходящих за диапазон от -1 до 1
Елпанов Евгений устанавливал большие значения, но говорит, что машина сама потом единичный вектор устанавливает. А тут по оси Z 1 мм а по оси Y аж 2 это поворот больше 45 градусов! А я что-то не наблюдаю этого в живье.

Последний раз редактировалось Supermax, 24.11.2009 в 23:11.
Supermax вне форума  
 
Непрочитано 24.11.2009, 23:08
#53
zamtmn

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


-2.44921e-016=-0.000000000000000244921
такое на глаз не увидишь, а в программах всегда надо эту погрешность учитывать при сравнении чисел с плавающей запятой. тут куча тем на эту тему была
zamtmn вне форума  
 
Автор темы   Непрочитано 24.11.2009, 23:17
#54
Supermax

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


А, пардон по е забыл!

Только что проверил. в 2007 каде функция entmod при замене 50 пары сбивает точку вставки у текста, а у мтекста не сбивает. И сбивает она потому, что список сформирован с нарушением порядка расположения точечных пар.
А про порядок расположения точечных пар в списках для функций entmod b entmakex вообще, нигде, ни гу гу.

Последний раз редактировалось Supermax, 25.11.2009 в 15:00.
Supermax вне форума  
 
Непрочитано 25.11.2009, 15:34
#55
zamtmn

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


Гляжу справку
TEXT:
10 First alignment point (in OCS)
DXF: X value; APP: 3D point
MTEXT:
10 Insertion point
DXF: X value; APP: 3D point

может в этом всё дело? хотя и там и там ocs былоб логичнее и в книжке и там и там ocs.
Ты че добиваешся? разные примитивы - разное поведенье. глюки надо у себя искать, а не у автокада))
zamtmn вне форума  
 
Автор темы   Непрочитано 25.11.2009, 17:25
#56
Supermax

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


zamtmn, я ничего не добиваюсь, и если ты думаешь, что я днями напролет ползаю по объектам Автокада и ищу в нем глюки, так я тебе отвечу - делать мне больше нечего, как заниматься такой ерундой.

Тут тема, про ориентацию объектов, и управление этой ориентацией. Это понятно?

Из всех доступных способов это сделать, только один - установить объекту угол поворота, направление нормали и точку вставки. Это надеюсь понятно?

Реализовать можно это либо заменой точечных пар в списке описания объекта, либо установкой через ActiveX функции этих свойств. Это понятно?

То, что при этом с некоторыми объектами происходят нехорошие вещи не моя вина, но тем, ради кого я эту тему открыл, знать это необходимо. Это понятно?

Если ты хочешь на собственном опыте убедиться в этом - изучай AutoLISP.
Supermax вне форума  
 
Непрочитано 25.11.2009, 17:44
#57
zamtmn

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


Да не кипятись ты, мне эти нормали повороты также интересны как и тебе.
Я с ними поковырялся выше крыши, и сделал вывод:
Это огрызок внутреннего представления объектов автокада, пригодный для экономного хранения объектов на диске, но практически не причодный для переориентации объекта.

>>Реализовать можно это либо заменой точечных пар в списке описания объекта, либо установкой через ActiveX функции этих свойств. Это понятно?
не, не понятно. хочешь просто и понятно крутануть объект на произвольные углы в 3D - применяй к ниму матрицу преобразования (посчитаную тобой), если это возможно в лиспе. автокад заботливо вернет тебе новый, посчитаный "угол" и нормаль.

Последний раз редактировалось zamtmn, 25.11.2009 в 17:50.
zamtmn вне форума  
 
Автор темы   Непрочитано 25.11.2009, 18:01
#58
Supermax

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


Цитата:
>>Реализовать можно это либо заменой точечных пар в списке описания объекта, либо установкой через ActiveX функции этих свойств. Это понятно?
не, не понятно. хочешь крутануть объект на произвольные углы в 3D - применяй к ниму матрицу преобразования (посчитаную тобой) если это возможно в лиспе, автокад заботливо вернет тебе новый, посчитаный "угол" и нормаль.
А! Так все таки вернулись опять у углу и нормали?
Ну посчитал я нужный мне угол и нормаль, а что дальше? А дальше - надо их установить! А как? - А вот так:

Скопируй вот это в буфер и вставь в командную строку Автокада.
(entget (car (entsel)))
И жми ентер.
Тебя попросят указать объект - ткни в него.
Подними планку окна просмотра событий и ты увидишь распечатку точечных пар объекта.
Этот список передается аргументом функции (entmod '(список точечных пар)) и если в нем есть отличие от того, которое есть в натуре - объект модифицируется в соответствии с новыми данными. Можно заменить 50 точечную пару (это угол поворота) на новую и модифицировать объект.
Только вот такой метод модификации приводит к сбоям если точечная пара стоит не на своем месте в списке (а в конце, так проще ее к списку приаттачить).
Есть тема про обучение на Лиспе, там и тряси народ на инфу.
Supermax вне форума  
 
Непрочитано 25.11.2009, 18:32
#59
zamtmn

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


1. из угла и нормали можно восстановить векторы.
2. из векторов можно посчитать угол.
3. получить нужное положение присвоив нормаль и угол можно только при гарантии что между каждым присвоением автокад ничего не пересчитывает, ты же говоришь что всё летит - значит пересчитывает, или ты чтото делаешь не так((

>>Скопируй вот это в буфер и вставь в командную строку Автокада...
У нас разговор слепого с глухим))
Скажи:
в лиспе можно преобразовывать объекты матрицами? чтонибудь наподобии TransformBy в ARX. если есть то ими и нужно пользоваться для переориентации.
В лиспе можно для блока получить его матрицу трансформации? если можно то из нее можно вынуть нужные тебе 0x, 0y без лишних вычислений

Последний раз редактировалось zamtmn, 25.11.2009 в 18:46.
zamtmn вне форума  
 
Автор темы   Непрочитано 25.11.2009, 18:44
#60
Supermax

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


Цитата:
У нас разговор слепого с глухим
Я только что хотел написать то же самое.
Цитата:
Скажи, в лиспе можно преобразовывать объекты матрицами? чтонибудь наподобии TransformBy в ARX
Нет. Можно посчитать матрицу, но преобразовывать объекты можно только меняя их свойства, или заменяя в списке распечатки entget точечные пары.
Supermax вне форума  
 
Непрочитано 25.11.2009, 20:06
#61
zamtmn

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


TransformBy таки в лиспе есть -
http://www.technopark.spb.ru/files/i...sp/tmatrix.lsp

ну и матрицу получить тоже должно быть можно
zamtmn вне форума  
 
Непрочитано 25.11.2009, 20:12
#62
Елпанов Евгений

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


zamtmn, Supermax,
Хватит ругаться! Вы оба неправы...
Во первых, матрицу можно применить к любому объекту, через лисп. Во вторых, все объекты автокада, в том числе блоки, корректно вращаются и изменяют нормали. В третьих, действительно, многострочный текст имеет дополнительные настройки, в отличии от остальных объектов, для него всегда автоматом вычисляется вектор нормали и оценивается его направление. Отсюда и глюк! Попробуйте написать многострочник и отзеркалить его. Текст будет автоматически перевернут для правильного отображения...

ps. Если необходимо это исправить, есть специальная переменная, на память не помню и акад не запущен - ищите сами, она с давних пор запротоколирована.
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны.
/Сунь Цзы/
Елпанов Евгений вне форума  
 
Непрочитано 25.11.2009, 20:27
#63
zamtmn

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


Елпанов Евгений
>>Хватит ругаться! Вы оба неправы...
я не ругаюсь. и думаю никто не прав, включая Вас.

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

>>Во вторых, все объекты автокада, в том числе блоки, корректно вращаются и изменяют нормали.
смотря что подразумевать под корректным вращением: установите объекту нормаль 1,0,0 он повернется, но вдобавок либо повернется вокруг оси, либо изменится rotatin хотя мы его не меняли (rotate3d - меняется rotation, в лиспе не проверял)
Вы кстати выше описывали пример вращения с использованием экранных координат - это корректно?

Последний раз редактировалось zamtmn, 25.11.2009 в 20:34.
zamtmn вне форума  
 
Непрочитано 25.11.2009, 20:37
#64
Елпанов Евгений

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


Цитата:
Сообщение от zamtmn Посмотреть сообщение
Вы кстати выше описывали пример вращения с использованием экранных координат - это корректно?
конечно корректно.
я менял все через лисп, прямым редактированием dxf...

Цитата:
Сообщение от zamtmn Посмотреть сообщение
установите объекту нормаль 1,0,0 он повернется, но вдобавок либо повернется вокруг оси, либо изменится rotatin хотя мы его не меняли (rotate3d - меняется rotation, в лиспе не проверял)
При изменении вектора нормали, ничего подобного не происходит - меняется система координат объекта, точнее, только вектор нормали - направление по Z у объекта... Если перевести пользовательскую систему координат в полученную для объекта, то и направление угла поворота будет корректным.
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны.
/Сунь Цзы/
Елпанов Евгений вне форума  
 
Непрочитано 25.11.2009, 20:47
#65
zamtmn

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


>>При изменении вектора нормали, ничего подобного не происходит - меняется система координат объекта.

Вращаю мтекст c нормалью 0,0,1 rotation 0 командой 3drotate вокруг оси Y на 90 градусов, в результате нормаль 1,0,0, rotation 270. объясните пожалуйста
тоже самое на 1 градус, снова rotation 270.

Последний раз редактировалось zamtmn, 25.11.2009 в 21:09.
zamtmn вне форума  
 
Непрочитано 25.11.2009, 21:00
#66
Елпанов Евгений

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


Цитата:
Сообщение от zamtmn Посмотреть сообщение
Вращаю мтекст c нормалью 0,0,1 поворотом 0 командой 3drotate вокруг оси Y на 90 градусов, в результате нормаль 1,0,0, угол 270. объясните пожалуйста
я же писал о многострочнике...
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны.
/Сунь Цзы/
Елпанов Евгений вне форума  
 
Непрочитано 25.11.2009, 21:05
#67
zamtmn

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


А есть разница? с блоком тоже самое
zamtmn вне форума  
 
Непрочитано 25.11.2009, 21:38
#68
Елпанов Евгений

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


zamtmn, ты мне все время говоришь о команде 3drotate, а здесь раздел форума по программированию. Я все объяснения делал применительно к программному редактированию объектов, т.е. без использования командной строки и стандартных команд автокада. Я редактирую объекты автокада через объектные методы либо через описания dxf объекта и его словарей. Математику пересчитываю сам...
Исходя из этого, ответственно заявляю, я активно использую блоки в 3д, в том числе вращаю и преобразую углы и нормали. Еще ни одного раза не наталкивался на ошибки автокада.
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны.
/Сунь Цзы/
Елпанов Евгений вне форума  
 
Непрочитано 25.11.2009, 21:56
#69
zamtmn

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


Елпанов Евгений
Я понимаю почему так происходит. и максу пытась объясняю почему так - повернули на градус а rotation уже не тот, или тот а выглядит не так
>>Математику пересчитываю сам...
а никто за тебя ее не пересчитает)), но матрицами математика в разы проще и наглядней
zamtmn вне форума  
 
Непрочитано 25.11.2009, 22:19
#70
Елпанов Евгений

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


Цитата:
Сообщение от zamtmn Посмотреть сообщение
но матрицами математика в разы проще и наглядней
Мне уже все равно... Когда много последовательных преобразований, я накапливаю их в матрице. Если же надо просто повернуть или сдвинуть - обхожусь без них...
Как пример, если нужно сделать отражение одной точки относительно произвольной плоскости - проще обойтись без матриц. Но когда необходимо вычислить серию отражений, те. положение нескольких точек после десятка отражений от произвольных плоскостей - здесь проще накапливать положение в одной матрице и потом применить матрицу к серии точек и вычислить новое положение. То же относится к объектам автокада...

ps. кстати, матрица отражения в автокаде не запротоколирована...
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны.
/Сунь Цзы/
Елпанов Евгений вне форума  
 
Непрочитано 25.11.2009, 22:36
#71
zamtmn

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


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

Последний раз редактировалось zamtmn, 25.11.2009 в 22:42.
zamtmn вне форума  
 
Непрочитано 25.11.2009, 22:46
#72
Елпанов Евгений

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


zamtmn, поворот вокруг произвольной оси, все равно будет описываться как перевод в систему координат, где ось поворота направлена в верх, потом поворот на нужный угол и перевод в исходную систему координат. Описать сразу поворот вокруг произвольной оси, не проходящей через центр координат в текущей системе, это слишком сложно и не универсально - проще делать в три действия, т.е. три матрицы и перемножить. Либо, как вариант, если это единичные вычисления для единственной точки, можно сделать такие же преобразования без матрицы, например через trans для поворота, смены системы координат и обычные смещения через mapcar...
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны.
/Сунь Цзы/
Елпанов Евгений вне форума  
 
Непрочитано 25.11.2009, 23:44
#73
zamtmn

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


поворот вокуг произвольной оси: перенос оси в начало координат, поворот вокруг произвольной оси проходящей через 0 - перенос обратно. да 3 дейстрия. - одна матрица и один унифицированный метод для всех объектов, помоему очень удобно

формирование матрицы поворота вокруг произвольной оси проходящей через 0 - формирование 9ти ее элементов примерно по 3 умножения на каждый. но чаще повернуть нужно нацелив ось (не обязательно чтоб это была нормаль) на точку, тогда матрицу сформировать проще.

нет такого математического апарата - задание ориентации осью и углом - это надстройка над матрицами

Сразу не обратил внимание:
>>Если перевести пользовательскую систему координат в полученную для объекта
Эту матрицу перехода систем координат можно получить на лиспе?, если да - проблема Supermax решена

Последний раз редактировалось zamtmn, 25.11.2009 в 23:57.
zamtmn вне форума  
 
Непрочитано 26.11.2009, 00:09
#74
Pastor

это только кличка
 
Регистрация: 22.10.2006
Москва
Сообщений: 252


Цитата:
нет такого математического апарата - задание ориентации осью и углом - это надстройка над матрицами
Есть такой математический аппарат. Называется углы Эйлера.
В основе лежит вектор с началом в 000 МСК и некоторым направлением. С этим вектором однозначно связаны три угла: нутации, прецессии и чистого вращения. Подробности можно узрить в любом справочнике по математике ( у меня старенький для инженеров, авторы Бронштейн и Семендяев). Где то выше я приводил ссылку на готовую функцию вычисления этих углов. Один раз разобраться, и все проблемы с СКО отпадут навсегда.
__________________
...в шее моей жилы железные, и лоб мой - медный...
Pastor вне форума  
 
Непрочитано 26.11.2009, 00:27
#75
zamtmn

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


Нет, углы Эйлера - это 3 угла, тут вектор и один угол. Конечно автокадовскую систему можно привести к углам Эйлера, также как к матрицам или кватернионам.
zamtmn вне форума  
 
Автор темы   Непрочитано 26.11.2009, 16:34
#76
Supermax

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


Елпанов Евгений,
Цитата:
... Исходя из этого, ответственно заявляю, я активно использую блоки в 3д, в том числе вращаю и преобразую углы и нормали. Еще ни одного раза не наталкивался на ошибки автокада.
Вот скажи, ты функциям Kpblc-а доверяешь?
Вот тут, в библиотеке функций, лежат две функции
_dwgru-conv-ent-to-ename
и _dwgru-ent-modify-autoregen
(первая нужна для работы второй).

Не поленись, сделай милость, и все кто это читает, повторите то, что я сейчас напишу, и скажите что получилось. Плииз.

Открываем чистый файл. Переходим в вид сверху (Top).
По центру экрана ваяем любой текст (MTEXT).
Набиваем в ком. строку или копируем через буфер прямо от сюда

(entget (car (entsel)))

должно вернуть что-то типа такого:

Код:
[Выделить все]
Select object: ((-1 . <Entity name: 7ed45640>) (0 . "MTEXT") (330 . <Entity name: 7ed43cf8>) (5 . "238") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (100 . "AcDbMText") (10 1543.13 1270.98 0.0) (40 . 2.5) (41 . 25.326) (46 . 0.0) (71 . 1) (72 . 5) (1 . "dghdghdghdghdgh") (7 . "Standard") (210 0.0 0.0 1.0) (11 1.0 0.0 0.0) (42 . 28.779) (43 . 3.23499) (50 . 0.0) (73 . 1) (44 . 1.0))
копируем себе в блокнотик
точку вставки (10 1543.13 1270.98 0.0)
нормаль (210 0.0 0.0 1.0)
ось абсцисс (11 1.0 0.0 0.0)
угол поворота вокруг нормали (50 . 0.0)

Теперь, поворачиваем командой _Rotate наш текст вокруг его точки вставки на 20 градусов по часовой. смотрим что получилось

Код:
[Выделить все]
Command: (entget (car (entsel)))
Select object: ((-1 . <Entity name: 7ed45640>) (0 . "MTEXT") (330 . <Entity name: 7ed43cf8>) (5 . "238") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (100 . "AcDbMText") (10 1543.13 1270.98 0.0) (40 . 2.5) (41 . 25.326) (46 . 0.0) (71 . 1) (72 . 5) (1 . "dghdghdghdghdgh") (7 . "Standard") (210 0.0 0.0 1.0) (11 0.939693 0.34202 0.0) (42 . 28.779) (43 . 3.23499) (50 . 0.349066) (73 . 1) (44 . 1.0))
точка вставки (10 1543.13 1270.98 0.0) не изменилась
нормаль (210 0.0 0.0 1.0) осталась прежней
абсцисса (11 0.939693 0.34202 0.0) повернулась
поворот (50 . 0.349066) в радианах

Далее: переходим в вид спереди (Front)
Командой _Rotate крутим наш текст (он еле заметная линия) по часовой на 20 градусов и возвращаемся в план (вид сверху).

Смотрим что получилось
Код:
[Выделить все]
Select object: ((-1 . <Entity name: 7ed45640>) (0 . "MTEXT") (330 . <Entity name: 7ed43cf8>) (5 . "238") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (100 . "AcDbMText") (10 1543.13 1270.98 0.0) (40 . 2.5) (41 . 25.326) (46 . 0.0) (71 . 1) (72 . 5) (1 . "dghdghdghdghdgh") (7 . "Standard") (210 -0.34202 0.0 0.939693) (11 0.883022 0.34202 0.321394) (42 . 28.779) (43 . 3.23499) (50 . 1.91986) (73 . 1) (44 . 1.0))
Точка вставки (10 1543.13 1270.98 0.0) не изменилась
Нормаль (210 -0.34202 0.0 0.939693) наклонилась влево
Абсцисса (11 0.883022 0.34202 0.321394) тоже изменилась
Угол поворота вокруг нормали (50 . 1.91986) а был (50 . 0.349066)

Но это еще не все.
Переписываем в блокнотик функции Kpblc-a
_dwgru-conv-ent-to-ename и _dwgru-ent-modify-autoregen
загружаем их и меняем угол поворота вокруг нормали на 0.0.

(_dwgru-ent-modify-autoregen (car (entsel)) 50 0.0 T)

Не знаю как у всех, но у меня в 2010 текст стал вертикально

Код:
[Выделить все]
Command: (entget (car (entsel)))
Select object: ((-1 . <Entity name: 7ed45640>) (0 . "MTEXT") (330 . <Entity name: 7ed43cf8>) (5 . "238") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (100 . "AcDbMText") (10 1543.13 1270.98 0.0) (40 . 2.5) (41 . 25.326) (46 . 0.0) (71 . 1) (72 . 5) (1 . "dghdghdghdghdgh") (7 . "Standard") (210 -0.34202 0.0 0.939693) (11 0.0 -1.0 0.0) (42 . 28.779) (43 . 3.23499) (50 . 0.0) (73 . 1) (44 . 1.0))
Точка вставки (10 1543.13 1270.98 0.0) не изменилась
нормаль (210 -0.34202 0.0 0.939693) как была наклонена влево, так и осталась.
Абсцисса (11 0.0 -1.0 0.0) смотрит строго вниз
угол поворота (50 . 0.0)

Если вернуть нормаль на место (перейти в вид Front и повернуть текст на -20 градусов)
то мы увидим
(10 1543.13 1270.98 0.0) (210 -1.11022e-016 0.0 1.0) (11 0.0 -1.0 0.0) (50 . 4.71239)
в нормали это - -1.11022e-016 почти 0, а угол стал правильным 4.71239 радиан, то есть 270 градусов.

А теперь посмотрите что у вас.

Последний раз редактировалось Supermax, 26.11.2009 в 16:51.
Supermax вне форума  
 
Непрочитано 26.11.2009, 17:33
#77
Александр Ривилис

программист, рыцарь ObjectARX
 
Регистрация: 09.05.2005
Киев
Сообщений: 2,273
Отправить сообщение для Александр Ривилис с помощью Skype™


К чему это все? Тебе кажется уже выше объяснили, что в ряде случаев изменение одного dxf-кода ведет к пересчету другого (других). Правильнее пользоваться матрицей преобразования или vla-методами.
Александр Ривилис вне форума  
 
Автор темы   Непрочитано 26.11.2009, 18:09
#78
Supermax

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


Что мне объяснили? Кто объяснил? Никто ничего толком сказать не может.

Вот вы мне скажите, что такое 50 пара?
Вот прямо, что за угол такой, что при наклоне текста осью нормали влево на один градус резко начинает показывать 1.5708 радиан, что означает 90 градусов и так стоит пока нормаль не повернется на 180 градусов.

Что вы все, мне матрицами мозг забиваете. Да какая в ж разница чем этот угол вычислять? почему, когда нормаль строго вертикально, этот угол четко вращает объект вокруг нормали, а стоит чуть-чуть нормаль наклонить, даже не во всех плоскостях, а только вокруг Y и этот угол-не угол показывает а черте-что.

Я по малоопытности и недалекости считал, что это угол поворота вокруг нормали, но в Автокаде творится что-то совсем мне не понятное.

Я хотел всего лишь по нормали и этому углу вычислить оси X и Y, тут все матрицы, матрицы! Ну и где ваши матрицы? Математики?
Где продвинутые в мат отношении функции? Что слабо? Я тоже в аптеку за лекарствами могу посылать, и книжек у меня хоть библиотеку открывай, и Интернет весь до дыр в мозгу исходил.

Хоть бы с углом этим ... разобраться помогли.
Supermax вне форума  
 
Непрочитано 26.11.2009, 18:41
#79
zamtmn

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


Supermax
>>Вот вы мне скажите, что такое 50 пара?
Это еденичный вектор оси 0x объекта.
>>Что вы все, мне матрицами мозг забиваете. Да какая в ж разница чем этот угол вычислять?
есть разница, с матрицами его вообще вычислять ненадо
>>Я хотел всего лишь по нормали и этому углу вычислить оси X и Y, тут все матрицы, матрицы! Ну и где ваши матрицы? Математики?
Я выше приводил расчет осей из нормали и угла. математика что на лиспе что на паскале одинакова.
>>Хоть бы с углом этим ... разобраться помогли.
выше всё написано, почему угол скачит
zamtmn вне форума  
 
Автор темы   Непрочитано 26.11.2009, 19:17
#80
Supermax

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


Цитата:
>>Вот вы мне скажите, что такое 50 пара?
Это еденичный вектор оси 0x объекта.
Чего, чего?

Как вектор может быть определен одной цифрой?
И в описании DXF кодов что написано?

Цитата:
50 - Rotation angle in radians
Цитата:
..выше всё написано, почему угол скачит
Это где выше? Ссылочку плииз.

Я краем своих извилин что-то припоминаю, что на практике, чтобы избежать операций связанных то ли с умножением на 0, то ли с делением, в каждом случае положения нормали дают прибавку к углу поворота. Эта прибавка потом вычитается при необходимости.
Я покрутил текст и вычислил. Если нормаль двигать строго по осям X или Y - нижняя дуга - 0, левая - 90 градусов, правая - 270 и верхняя 180. А вот в промежутках - пока не догнал принцип.

Последний раз редактировалось Supermax, 26.11.2009 в 19:37.
Supermax вне форума  
 
Непрочитано 26.11.2009, 19:26
#81
Елпанов Евгений

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


Supermax,
1. без матриц нельзя описать поворот в 3д.
2. а если все это проделать не с многострочным текстом, а с другим примитивом, например блоком?

Цитата:
Далее: переходим в вид спереди (Front)
Командой _Rotate крутим наш текст (он еле заметная линия) по часовой на 20 градусов и возвращаемся в план (вид сверху).
А как бы ты сам описал углы поворота и вектор нормали для примитива, который повернут вокруг оси Y в мировой системе координат, а потом еще и вокруг оси Z причем сам примитив создан не в мировой системе координат и второй поворот был вообще не соосен ни с какими ортами внутренней системы координат примитива?

По поводу многострочного текста, я уже говорил, сначала сделай, чтоб при зеркалировании, текст отображался зеркально, а потом рассказывай про эксперименты с текстом - автокад пытается правильно отобразить текст...
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны.
/Сунь Цзы/

Последний раз редактировалось Елпанов Евгений, 26.11.2009 в 19:33.
Елпанов Евгений вне форума  
 
Непрочитано 26.11.2009, 19:29
#82
zamtmn

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


>>Чего, чего?
вру, это угол))
>>Это где выше? Ссылочку плииз.
пост №47 + разде arbitrary axis algorithm из dxf reference
zamtmn вне форума  
 
Непрочитано 26.11.2009, 19:34
#83
Pastor

это только кличка
 
Регистрация: 22.10.2006
Москва
Сообщений: 252


DXF пара 50 - это угол чистого вращения (тот самый "от Эйлера").
Система координат объекта (СКО, она же OCS) представляет собой следующее:
1. Начало совпадает с 000 МСК.
2. Направление Z совпадает с вектором нормали из 210 пары.
3. Ось X всегда лежит в плоскости XY МСК, а её направление вычисляется, как векторное произведение оси Z МСК и вектора нормали объекта. Т.е мысленно вращаем кратчайшим образом Z МСК до совпадения с вектором нормали и по правилу правого винта получаем направление X СКО.
4. Ось Y CКО однозначно определяется через Z и X так, чтобы образовалась правая тройка векторов.
Вот и вся математика.
Теперь пример. Возьмем текст, лежащий в плоскости XY МСК с нулевым углом поворота (чистого вращения). Если его "взять" за конец нормали и слегка "наклонить влево" то оси СКО изменят свое направление. Ось Z - это нормаль, которую мы "слегка наклонили влево". Ось X вычисляется как векторное произведение (Z МСК * нормаль) и смотрит в данном случае строго вниз ( -Y МСК). В этой новой системе координат объекта текст оказывается повернут относительно оси X СКО на 90 градусов. Поэтому и в паре 50 оказывается новое значение согласованное с новой СКО.
__________________
...в шее моей жилы железные, и лоб мой - медный...
Pastor вне форума  
 
Непрочитано 26.11.2009, 19:43
#84
zamtmn

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


>>3. Ось X всегда лежит в плоскости XY МСК, а её направление вычисляется, как векторное произведение оси Z МСК и вектора нормали объекта
не совсем так, используется arbitrary axis algorithm.
углы Эйлера удобны когда надо делать интерполяцию вращения. всерано когда надо конкретно считать - их прибется переводить в матричную форму

Последний раз редактировалось zamtmn, 26.11.2009 в 19:54.
zamtmn вне форума  
 
Непрочитано 26.11.2009, 20:25
#85
Pastor

это только кличка
 
Регистрация: 22.10.2006
Москва
Сообщений: 252


Цитата:
чему равно векторное произведение (0,0,1)*(0,0,1)?
В этом особом случае СКО принимается совпадающим с МСК и считать ничего не требуется. Так же особым является случай, когда нормаль противонаправлена оси Z МСК. Тогда ось X СКО надо принять (-1, 0, 0) .

Цитата:
углы Эйлера удобны когда надо делать интерполяцию вращения. всерано когда надо конкретно считать - их прибется переводить в матричную форму
Углы Эйлера я использовал в приложении под названием QProfile для подзадачи переноса вхождений блоков из пространства модели в пространство листа. Это приложение есть здесь на сайте в архиве и возможно вам даже о нем известно. Там как раз надо было "конкретно считать" и углы Эйлера оказались очень к месту. Код приложения открытый и можно посмотреть, если интересно (конкретно - это файл SolProfiler.lsp).
__________________
...в шее моей жилы железные, и лоб мой - медный...
Pastor вне форума  
 
Автор темы   Непрочитано 26.11.2009, 21:00
#86
Supermax

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


Pastor, О! Это уже конкретный базар пошел! Жму пять!
Буду завтра разбираться и тщательно вникать.

zamtmn, с твоими мат. примерами тоже. Тебе тоже спасибо за помощь.

Елпанов Евгений,
Цитата:
... По поводу многострочного текста, я уже говорил, сначала сделай, чтоб при зеркалировании, текст отображался зеркально, а потом рассказывай про эксперименты с текстом - автокад пытается правильно отобразить текст...
Ну че ты с этим отзеркаливанием пристал? Текст тут совсем не причем. Это команда его обратно переворачивает. А текст можно как угодно перевернуть. Только если это делать тупо, прямо через изменение Rotation, надо учитывать, что Автокад, получая указание нормали, в зависимости от того, какое это указание, вращает ПСК объекта. Чтобы наклонить нормаль чуть-чуть влево не меняя расположения объекта надо оказывается задать ему при этом угол 90 градусов! Слава богу при изменении нормали, из-за этих наворотов Автокад сам углы пересчитывает.
Всегда, поворачивая объект вокруг нормали, надо считывать существующий угол и прибавлять к нему нужное значение поворота, а не заменять тупо одно на другое.

Ладно, на сабантуй прийду с ноутбуком. Там и пообщаемся. 19-00 буду.
Supermax вне форума  
 
Непрочитано 27.11.2009, 13:06
#87
zamtmn

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


>>В этом особом случае СКО принимается совпадающим с МСК и считать
>>ничего не требуется. Так же особым является случай, когда нормаль
>>противонаправлена оси Z МСК. Тогда ось X СКО надо принять (-1, 0, 0) .

А если нормаль чуть чуть отличается от 0,0,1 ну совсем чуток чуть больще чем погрешность. Получится что Вы перемножите почти паралельные вектора и результат будет неверным.
поэтому делается так:
Цитата:
If (abs (Nx) < 1/64) and (abs (Ny) < 1/64) then
Ax = Wy X N (where “X” is the cross-product operator).
Otherwise,
Ax = Wz X N.
Scale Ax to unit length.
цитата из acad_dxf.chm
zamtmn вне форума  
 
Непрочитано 27.11.2009, 23:11
#88
Pastor

это только кличка
 
Регистрация: 22.10.2006
Москва
Сообщений: 252


Цитату не понял. Равно как и не понял проблему.
Вот функция, вычисляющая векторное произведение.
Если результат слишком близок к (0 0 0), то функция принимает решение, что вектора коллинеарны и возвращает nil.
Код:
[Выделить все]
; 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.
В данном случае точность сравнения принята 1е-12.
__________________
...в шее моей жилы железные, и лоб мой - медный...
Pastor вне форума  
 
Непрочитано 28.11.2009, 12:21
#89
zamtmn

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


>>Цитату не понял. Равно как и не понял проблему.
Вы говорите что:
Цитата:
3. Ось X всегда лежит в плоскости XY МСК, а её направление вычисляется, как векторное произведение оси Z МСК и вектора нормали объекта.
Это не совсем так, если и X и Y нормали < 1/64 то ось x - векторное произведение YМСК и нормали, если это не учесть - вращение будет глючить при нормали близкой 0,0,+-1.
"близкой" = X и Y нормали < 1/64. конечно в жизни такие нормали бывают не часто, но бывают
zamtmn вне форума  
 
Непрочитано 29.11.2009, 16:48
#90
Pastor

это только кличка
 
Регистрация: 22.10.2006
Москва
Сообщений: 252


Признаю свою ошибку.
AutoCAD вводит четко определенные правила при вычислении СКО для векторов нормали близких к оси Z МСК. Как указывал выше zamtmn, всё описано в acad_dxf.chm.
Кстати, число 1/64 не такое уж и маленькое. В пересчете на градусы отклонения от Z МСК это между 0.8 и 0.9.

>>zamtmn
Спасибо за вашу настойчивость. Лоб то у меня медный
__________________
...в шее моей жилы железные, и лоб мой - медный...
Pastor вне форума  
 
Автор темы   Непрочитано 29.11.2009, 21:48
#91
Supermax

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


Вставлю свои пять копеек.
Замечу, что функция перемножения векторов никогда, подчеркивю НИКОГДА не должна возвращать nil!
Если вектора практически слились в одну линию, то надо чтобы функция все равно возвращала какой-то вектор.
В частности, если мы перемножаем нормаль на вектор Z МСК, то функция вырождается в:

Код:
[Выделить все]
(defun v*z (v1 / res )
  (setq res
	 (list
	  (cadr v1); координата X (в МСК).
	   (- 0 (car v1)); координата Y (в МСК).
	   0.0; координата Z (в МСК).
	 ); return.
  ); setq.
  (if (equal res '(0.0 0.0 0.0) 1e-12) nil res); return.
); end defun.
Остается вместо nil вставить вектор. (1.0 0.0 0.0)?

Результирующий вектор должен быть перпендикулярен нормали. То есть он лежит в плоскости XY МСК, но перпендикулярен и оси Z МСК и нормали одновременно. Тогда мне понятно как отложить угол от этого вектора к оси X СКО.

Y равна перевернутому X нормали, а X - Y нормали. Получается 90 градусов.
Вот так - правильно!

Смущает одно, надо продлевать значения X и Y результирующего вектора до точки на единичной окружности. Чтобы функция не бесконечно малые числа возвращала, а путевый единичный вектор.

Последний раз редактировалось Supermax, 29.11.2009 в 22:30.
Supermax вне форума  
 
Непрочитано 29.11.2009, 22:04
#92
Елпанов Евгений

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


Цитата:
Сообщение от Supermax Посмотреть сообщение
Остается вместо nil вставить вектор. (1.0 0.0 0.0)?
тогда уж лучше:
Код:
[Выделить все]
(list (cadar vl)(caddar vl)(caar vl))
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны.
/Сунь Цзы/
Елпанов Евгений вне форума  
 
Автор темы   Непрочитано 29.11.2009, 22:10
#93
Supermax

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


Код:
[Выделить все]
(list (cadar vl)(caddar vl)(caar vl))
Это ты как (cadar vl) сделаешь? Ты сначала car делаешь, а потом cdr? Изчего? и все остальное - издеваешься?
Supermax вне форума  
 
Непрочитано 29.11.2009, 22:53
#94
Елпанов Евгений

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


Supermax, Действительно, невнимательно смотрел код...
В данном случае, я хотел сказать - если необходимо всегда давать вектор - значит надо давать, но это не значит, что при ошибке всегда давать какой то заранее заданный. Такой подход, в будущем приведет к очень сложно находимым ошибкам...
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны.
/Сунь Цзы/
Елпанов Евгений вне форума  
 
Непрочитано 30.11.2009, 09:39
#95
zamtmn

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


>>Остается вместо nil вставить вектор. (1.0 0.0 0.0)?
вообщето для паралельных векторов результат долженбыть (0.0 0.0 0.0) по определению векторного произведения. разруливать паралельность нужно вызывающей программой, а не программой умножения.
zamtmn вне форума  
 
Автор темы   Непрочитано 03.12.2009, 14:38
#96
Supermax

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


Я считаю, что надо сначала сравнивать векторы на паралельность, а потом решать что с этим делать. И как узнать при каких обстаятельствах и как определить паралельны они или нет?
Функция не доработана. А надо.

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

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

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


универсальный способ проверить на паралльность - посчитать векторное произведение

>>Очень надо вычислять точку пересечения прямой и плоскости. Плоскость по трем точкам, а прямая по двум.
вся необходимая математика: http://algolist.ru/maths/geom/index.php
перекатать это на лиспе думаю труда не составть

Последний раз редактировалось zamtmn, 03.12.2009 в 15:40.
zamtmn вне форума  
 
Автор темы   Непрочитано 03.12.2009, 16:25
#98
Supermax

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


Чтобы туда-сюда не лазить сюда перенес суть.
Цитата:
Пересечение: Прямая(или отрезок) и плоскость

Плоскость задана тремя точками, прямая( или отрезок) начальной и конечными точками.

Очевидно, эта задача, как и многие подобные ей, может быть решена путем составления системы. Хотелось бы предложить более геометричный метод, который гораздо удобней в большинстве случаев.

Будем обозначать A,B,C - точки плоскости, X,Y - точки прямой(концы отрезка), SP - скалярное произведение, VP - векторное произведение. O - искомое множество точек пересечения

N = VP ( B - A, C - A )
N = N / | N | - нормаль к плоскости // в принципе это можно и не делать
V = A - X
// расстояние до плоскости по нормали
d = SP ( N, V )
W = Y - X
// приближение к плоскости по нормали при прохождении отрезка
e = SP ( N, W )

if( e!=0 )
O = X + W * d/e; // одна точка
else if( d==0)
O =X + W * (anything) // прямая принадлежит плоскости
else
O = empty; // прямая параллельна плоскости


Если хочешь быть уверен, что плоскость пересекает не только прямая, но и отрезок, можно проверить условие SP ( X - O, Y - O ) <=0
И так:
Код:
[Выделить все]
(defun point-suppression-plane (a b c x y)
(setq b-a (mapcar '(lambda (w r) (- w r)) b a))
(setq c-a (mapcar '(lambda (w r) (- w r)) c c))
(setq n (v*v b-a c-a))
(setq n (mapcar '(lambda (w) (sgrt (* w w))) n) ; хотя, как говорят этого можно и не делать
(setq v (mapcar '(lambda (w r) (- w r)) a x))
(setq d (3d_angw1w2 n v))
(setq w (mapcar '(lambda (w r) (- w r)) y x))
(setq e (3d_angw1w2 n w))

дальше потом допишу
А вот тут проблема с перемножением векторов. Существующая функция в случае паралельности векторов должна выдавать что? (0.0 0.0 0.0)?

Ладно, переделываем функцию перемножения на классику.
Код:
[Выделить все]
; 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) '(0.0 0.0 0.0) res); return.
); end defun.
А если для ПСК объектов считать придется, то:

Код:
[Выделить все]
(if (= (v*v a1 b1) '(0.0 0.0 0.0)) '(1.0 0.0 0.0) (v*v a1 b1))

Последний раз редактировалось Supermax, 03.12.2009 в 17:57.
Supermax вне форума  
 
Непрочитано 03.12.2009, 16:58
#99
Елпанов Евгений

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


проверить параллельность двух плоскостей можно проще, по векторам:
Код:
[Выделить все]
(setq v1 '(0. 0. 1.) v2 '(0. 1. 2.))
(and(inters '(0. 0. 0.) v1 '(0. 0. 0.) v2))
короче, если вектора пересекаются в общей точке - значит и плоскости пересекаются...
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны.
/Сунь Цзы/
Елпанов Евгений вне форума  
 
Непрочитано 03.12.2009, 17:28
#100
zamtmn

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


>>дальше застрял. Угол между векторами надо найти.
дальше не нужно угол искать. нужно поюзать гугл и посмотреть определение скалярного произведения.
можно вот так посчитать:
Цитата:
function scalardot(var v1,v2:GDBVertex):GDBDouble;
begin
result:=v1.x * v2.x + v1.y * v2.y +v1.z*v2.z;
end;
zamtmn вне форума  
 
Автор темы   Непрочитано 03.12.2009, 17:29
#101
Supermax

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


О! Штангенциркуль в ход пошел! (...inters...) Зачем в самом деле париться, если Автокад может пособить.

Но я вот по поводу угла между векторами хочу спросить, я правильно функцию наваял?

Код:
[Выделить все]
(defun ugol-vector (a b)
(/ 10 (* (sqrt (apply '+ (mapcar '(lambda (f) (* f f)) a))) (sqrt (apply '+ (mapcar '(lambda (f) (* f f)) b)))))
)
вот формулы cos(a^b) в самом низу.
http://www.bymath.net/studyguide/alg/sec/alg25.html

Гугл уже поюзал и именно скалярное произведение требует косинуса угла между векторами.

Немного недоглядел. Исправил. Хорошо, что атомную станцию не считаю.

Последний раз редактировалось Supermax, 03.12.2009 в 17:49.
Supermax вне форума  
 
Непрочитано 03.12.2009, 17:43
#102
zamtmn

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


>>Гугл уже поюзал и именно скалярное произведение требует косинуса угла между векторами.
нет,
если в руках транспортер а на ватмане 2 вектора - считают через косинус.
если извесны координаты, то x1*x2 + y1*y2+z1*z2, а заодно потом через него (скалярное произведение) и угол между векторами найти можно
zamtmn вне форума  
 
Непрочитано 03.12.2009, 17:43
#103
VVA

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


Цитата:
Сообщение от Supermax Посмотреть сообщение
И как узнать при каких обстаятельствах и как определить паралельны они или нет?
Код:
[Выделить все]
;;; PARALLELP
;;; Evaluates if p1 p2 segment is parallel to p3 p4 segment
;;;
;;; Arguments = 4 points
(defun parallelp (p1 p2 p3 p4)
  (and
    (not (inters p1 p2 p3 p4 nil))
    (or    (inters p1 p4 p3 p2 nil)
    (inters p1 p3 p4 p2 nil)
    )
  )
)

;;; PERPENDICULARP
;;; Evaluates if p1 p2 segment is perpendicular to p3 p4
;;;
;;; Arguments = 4 points
(defun perpendicularp (p1 p2 p3 p4)
  (equal (vxv (vec1 p1 p2) (vec1 p3 p4)) 0 1e-8)
)
Добавлено
Код:
[Выделить все]
; Угол между векторами (скалярное произведение векторов)
;---------------------
;Параметры:
;Wekt1, Wekt2 - вектора
;Возвращает  угол между векторами
;http://www.elecran.com.ua/index.php?pagename=programer.php
(defun 3d_angw1w2 (Wekt1 Wekt2 / CosA)
 (if (equal (setq CosA (/ (apply '+ (mapcar '* Wekt1 Wekt2))
			  (distance '(0 0 0) Wekt1) (distance '(0 0 0) Wekt2))) -1.0 1e-6)
  Pi
  (if (equal CosA 0.0 1e-6) (* 0.5 PI)(atan (sqrt (- 1 (* CosA CosA))) CosA))
 )
)
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Автор темы   Непрочитано 03.12.2009, 18:05
#104
Supermax

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


VVA, про паралельность я спрашиваю с точки зрения требуемой точности для автокада. Вот какие две, якобы паралельные линии считаются таковыми в Автокаде? Скажем на расстоянии в километр какая дельта х y z может быть?
Вот при каких значениях нормали Автокад автоматически разворачивает ось ПСК объекта в 1,0,0?
Я считаю, что именно такое значение расхождения в паралельности и нужно закладывать в функцию как "крайний рубеж".
Ну что такое -12 степень? А может -16 сглотнет? Нет точных данных.
Supermax вне форума  
 
Непрочитано 03.12.2009, 21:53
#105
zamtmn

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


>>с точки зрения требуемой точности для автокада
В автокаде точность настраивается, такчто или получить ее значение, или забить и использовать свою точность
цитата из "дубового" перевода документации по arx:
Цитата:
Допуски
Много методов принимают значение допуска как один из их параметров. Это значение имеет AcGeTol класс и всегда имеет значение по умолчанию, как определено в AcGeContext:: gTol. Функции типа isClosed () и isPlanar () вычисляют,являются ли точки начала и оконечные точки в пределах определенного допуска перед возвращением Булева значения. Вы можете изменять допуск для одного специфического функционального запроса, или Вы можете изменять глобальное значение допуска.
AcGeTol класс обеспечивает две функции для установки допуска для точек и векторов:

void
setEqualPoint(double);

void
setEqualVector(double);

AcGeTol класс также обеспечивает две функции для получения допуска для точек и векторов:

double equalPoint() const;
double equalVector() const;

EqualPoint и equalVector значения допуска используются следующим образом:
 Две точки, p1 и p2, являются равным если
( p1 - p2) .length () < = equalPoint
 Два вектора, v1 и v2, являются равным если
( v1 - v2) .length () < = equalVector
 Два вектора, v1 и v2, являются параллельным если
( v1/v1.length () - v2/v2.length ()) .length () < equalVector
ИЛИ (v1/v1.length () + v2/v2.length ()) .length () < equalVector
 Два вектора, v1 и v2, являются перпендикулярным если
abs((v1.dotProduct(v2))/(v1.length()*v2.length())) < = equalVector
 Две линии или лучи - параллельный (перпендикуляр), если их направленные векторы - параллельный (перпендикуляр)
 Две линии равен, если точки в параметре 0 равны, и их направления равны

ОБРАТИТЕ ВНИМАНИЕ, что эти правила подразумевают, что две линии - близко к друг другу как точечные множества в части пространства моделирования диаметра diam только, если допуск equalVector установлен более плотным чем equalPoint/diam.
zamtmn вне форума  
 
Автор темы   Непрочитано 04.12.2009, 11:34
#106
Supermax

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


Я это понимаю, но ответ на мой вопрос
Цитата:
Вот при каких значениях нормали Автокад автоматически разворачивает ось ПСК объекта в 1,0,0?
так и не получен. Допустим я могу загрубить точность расчета (неплохо бы узнать как) это повлияет на этот разворот?
Вы понимаете, что надо насильно в функцию перемножения векторов вставлять это дело?
Потом, результат перемножения укорачивает результирующий вектор и дальнейшее использование этих данных вынуждает работать с очень маленькими значениями, что ухудшает погрешность дальнейших вычислений.
В функцию надо вставить вычисление точки отложенной от 0,0,0 в строну результирующего вектора длинною 1мм. Это и будет возвращаемое значение функции. И это функция уже не перемножения векторов, а определение вектора оси Х ПСК (промежуточной системы координат).
Люди, VVA, ну граблями я функции пишу. Что вам стоит пару строчек черкнуть?
И функцию пересечения плоскости прямой тоже надо дописать, ведь все уже есть!

Я чего бъюсь? - мне надо подрезать слейсом 3Dсолид и восстанавливать, а точнее переписывать историю. Чтобы всегда можно было узнать длинну объекта, не зависимо от того, сколько дырок вы в нем насверлили или как подрезали.
Изначально считаем, что все 3D солиды имеют свои истории. Читам историю, смотрим осевую 3Dсолида, вычисляем точку пересечения с плоскостью реза, замеряем длинну, которая остается и после реза записываем новые данные точки вставки, длинны осевой и координат.

Хочу чтобы слейс и мувфасес не убивали историю.
Supermax вне форума  
 
Непрочитано 04.12.2009, 12:00
#107
zamtmn

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


>>Вы понимаете, что надо насильно в функцию перемножения векторов вставлять это дело?

зачем? надо заранее смотреть и не перемножать паралельных векторов
используя
Цитата:
If (abs (Nx) < 1/64) and (abs (Ny) < 1/64) then
Ax = Wy X N (where “X” is the cross-product operator).
Otherwise,
Ax = Wz X N.
Scale Ax to unit length.
ты гарантированно не перемножишь паралельные вектора при расчете ск объекта

Последний раз редактировалось zamtmn, 04.12.2009 в 12:14.
zamtmn вне форума  
 
Непрочитано 04.12.2009, 12:21
#108
VVA

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


То же что сказал и zamtmn (если я правильно понял)
1. Вычисляешь единичный вектор
2. Сравниваешь точность по X,Y,Z
Код:
[Выделить все]
(defun pl-geom-single-vector (Vekt)
;;; Вычисление орта (единичного вектора)
;;;-------------------------------------
;;;;Параметр: Vekt - любой вектор
;;; Возвращает: Единичный вектор
((lambda (l)
     (if (not(equal 0.0 l 1e-6))
       (mapcar (function (lambda (x) (/ x l))) Vekt)
     )
   )
    (distance '(0 0 0) Vekt)
  )
  )
Пример
Код:
[Выделить все]
(defun C:TEST ()
  (setq FUZZ (/ 1. 64)) ; точность
  (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/64")
  (alert "OK")
    )
  )
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Автор темы   Непрочитано 04.12.2009, 13:40
#109
Supermax

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


Кто-то из нас видимо что-то не понимает.
zamtmn, я с тобою полностью согласен, что надо проверять на паралельность ДО того. Но как проверять. Функции VVA на паралельность может и подойдут, если они действуют в соответствии с
Цитата:
If (abs (Nx) < 1/64) and (abs (Ny) < 1/64) then
Ax = Wy X N (where “X” is the cross-product operator).
Otherwise,
Ax = Wz X N.
Scale Ax to unit length.
Но черт побери! вектора 0,0,0 не существует в природе! Это точка!
И в Автокаде надо 1,0,0 вместо нее ставить! Результат перемножения векторов должен быть вектор!
Кто-нибудь напишет НОРМАЛЬНУЮ функцию перемножения векторов? Чтобы и проверка на паралельность, точность и единичный вектор возвращала? Сколько можно одно и то же мусолить? Давайте делать!
Supermax вне форума  
 
Непрочитано 04.12.2009, 13:47
#110
Елпанов Евгений

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


Цитата:
Сообщение от Supermax Посмотреть сообщение
И в Автокаде надо 1,0,0 вместо нее ставить! Результат перемножения векторов должен быть вектор!
Кто-нибудь напишет НОРМАЛЬНУЮ функцию перемножения векторов? Чтобы и проверка на паралельность, точность и единичный вектор возвращала?
Считаю задание настолько неверным, что решил заявить - такая функция, появись она на форуме для всеобщего обозрения, будет больше вредить, чем помогать!!!

Для параллельных векторов, при перемножении нельзя выдавать что нибудь. Это как сделать свою функцию деления, в которой при делении на ноль, всегда возвращалось бы какое либо заранее заданное число...
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны.
/Сунь Цзы/
Елпанов Евгений вне форума  
 
Автор темы   Непрочитано 04.12.2009, 13:54
#111
Supermax

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


Елпанов Евгений, ну вроде тоже верные мысли, но как быть?
Придется закинуть эту математику к .. фене и сделать самим Автокадом методом штангенциркуля.
Так я это уже и сделал! См. http://forum.dwg.ru/showpost.php?p=480556&postcount=24

Вот как сам автокад этот ежик повернул - так тому и быть! Какая там точность?, Какая паралельность? - Все в тумане, но выше этого уже никакой математикой не прыгнешь!
Supermax вне форума  
 
Непрочитано 04.12.2009, 14:14
#112
zamtmn

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


>>Кто-нибудь напишет НОРМАЛЬНУЮ функцию перемножения векторов?
>>Чтобы и проверка на паралельность, точность и единичный вектор
>>возвращала? Сколько можно одно и то же мусолить? Давайте делать!

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

предположим ты считаешшь ск объекта: используй arbatrary axis - результат будет коректен, всё развернется как надо его смысл какраз в том чтобы не перемножить паралельные вектора.

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

Елпанов Евгений дело говорит, подправлять под свои хотелки математическую функцию и называть это "НОРМАЛЬНУЮ функцию перемножения векторов" - вредительство)))

(0,0,0) почему не вектор? нормальный вектор нулевой длины.
zamtmn вне форума  
 
Автор темы   Непрочитано 04.12.2009, 14:21
#113
Supermax

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


Да бог с ним, не надо мне уже ничего перемножать.
Я только наведу маленько тень на плетень и пойду.
1/64=0.015625 это дельта 15,625 миллиметров на метр. С такой точностью можно и локтями измерить.
Автокад устанавливает точность на много-много порядков больше.
Так что 1/64 - мягко говоря туфта.
Supermax вне форума  
 
Непрочитано 04.12.2009, 14:28
#114
Александр Ривилис

программист, рыцарь ObjectARX
 
Регистрация: 09.05.2005
Киев
Сообщений: 2,273
Отправить сообщение для Александр Ривилис с помощью Skype™


Цитата:
Сообщение от Supermax Посмотреть сообщение
Я только наведу маленько тень на плетень и пойду.
Именно этим и занимаешься.
Александр Ривилис вне форума  
 
Непрочитано 04.12.2009, 14:31
#115
zamtmn

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


1/64 - это не точность

это граница на которую может отклониться нормаль от 0,0,1
если отклонено больше - считаем 0x = Wz X N (т.е. нормаль не близка (не паралельна) к 0,0,1)
если меньше - 0x = Wy X N (т.е. нормаль близка (паралельна) к 0,0,1)

Это не предел для прощедуры векторного умножения, а условная граница переход через которую сдваигает 0x объекта. Наверно когдато давно, когда компы были большими а точность вычислений маленькой - 1\64 было близко к пределу влияющему на точность, сейчас нет. Просто так повелось

Последний раз редактировалось zamtmn, 04.12.2009 в 14:44.
zamtmn вне форума  
 
Непрочитано 04.12.2009, 14:35
#116
Елпанов Евгений

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


Supermax, Все, замяли с умножением векторов!

Вспоминаю код, явно писали инудсы... Видимо у них постоянно вылетала ошибка деления на ноль, так они в куче мест программы, все нули меняют на 1е-8. Стоит один раз запустить такую программу в чертеже и работать с ним становится невозможно - заменяются нули в 10 и 210 кодах dxf.

ой, забыл самое главное - еще все углы во всех примитивах (дуги, тексты итд...)
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны.
/Сунь Цзы/

Последний раз редактировалось Елпанов Евгений, 04.12.2009 в 15:17.
Елпанов Евгений вне форума  
 
Автор темы   Непрочитано 04.12.2009, 15:14
#117
Supermax

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


Александр Ривилис, наводить тень на плетень тоже нужно, иначе в мозгах застой образуется. Точнее в ваших мозгах, а в моем он не образуется, он там постоянно прописан.
zamtmn, не знаю как там повелось, но 1/64 и 1е-12 вещи настолько разные, что как-то не верится, что спецы AutoDesk при < 1/64 считают вектора паралельными. А я еще и 1е-16 и 1е-18 видел.
Елпанов Евгений, а вот тут я не догнал чуток.
"округляются нули" ты говоришь, что они 0 заменили на 1е-8, какое это округление?
Цитата:
округляются нули в 10 и 210 кодах dxf.
я понимаю как было 1е-8, а стало 0. Вот это округление. И е-8 что-то маловато для Автокада, не кажется?

Завязать с перемножением не получится. Я забыл, что есть благородная задача написать функцию получения координат точки на линии, пересекающей плоскость. А там перемножение - основа.
Supermax вне форума  
 
Непрочитано 04.12.2009, 15:19
#118
Елпанов Евгений

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


Supermax, извини, описался...
Имел в виду, что в начале работы программы, сканируется весь чертеж и в кодах 10 11 210 50 и возможно еще каких то, все нули меняются на 1е-8
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны.
/Сунь Цзы/
Елпанов Евгений вне форума  
 
Автор темы   Непрочитано 04.12.2009, 15:24
#119
Supermax

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


Ну тогда я понимаю, 1е-8 это уже не 1/64, но тем не менее тоже не сахар.

И вообще, разозлися не на шутку. Провел линию в 100 метров! и повернул ее на 0.00015 радиан, а вектор отклонил (210
-0.00015 0.0 1.0)) по Х на 15 миллиметров на 100 метрах!
Ну и где ваши 1/64? Вы посмотрите, в 210 паре даже е-хх не появилось, а оно там бывает, будьте уверены!

Вот, подправил 1 миллиметр на 100 метрах
(210 -1.0e-005 0.0 1.0) и тоже все в шоколаде.

Последний раз редактировалось Supermax, 04.12.2009 в 15:29.
Supermax вне форума  
 
Непрочитано 04.12.2009, 15:32
#120
zamtmn

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


1\64 ни как на ТОЧНОСТЬ вычислений не влият. прими они 1\32 все было бы также, угол бы скакал чуток позже, но всё по прежнему вращалось бы также корректно.

>>что спецы AutoDesk при < 1/64 считают вектора паралельными
это сделано чтоб не множить паралельные вектора, но это не значит что считают что они паралельны. на месте 1\64 должна быть какаято цифра почему ты думаешь что 1\64 много?
zamtmn вне форума  
 
Непрочитано 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. только без обид - я не хочу обидеть!
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны.
/Сунь Цзы/
Елпанов Евгений вне форума  
 
Автор темы   Непрочитано 08.12.2009, 14:51
#141
Supermax

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


А я тупой. Вот никак не могу понять, какого фига мне таскать за каждой лиспиной целую библиотеку. И мне не понятно, почему нельзя сделать такую библиотеку, чтобы я мог просто черпать идеи, а не готовые простыни, где текста порой больше самого кода. Все равно при компиляции весь этот мусор выбрасывается.
И погодите, такое складывается впечатление, что это я администратор форума и главный распорядитель библиотеки функций. Что вы меня обвиняете, что идея с библиотекой не пошла как следует?
Она пошла, но не так как хотелось бы. И это не я ее загубил. Просто было несколько подпорок, а они почему-то время от времени куда-то отлучаются и конструкция шатается. Она не упала. Это я малость передернул.

Вот классический пример:
VVA написал функцию, которая считает все в треугольнике.
http://forum.dwg.ru/showthread.php?t=15697
А мне не надо это все, мне только один угол надо.
И то, я его вместе с другими задачами решаю. Мне надо принцип понять и свои задачи решить более совершенно.
А тут функция а ссылается на функцию б, та на с, та на д и т.д.
Смотрю на код и не понимаю как он работает.

И вообще, мое мнение, это мое мнение. Причем тут библиотека?
Supermax вне форума  
 
Непрочитано 08.12.2009, 16:12
#142
Елпанов Евгений

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


Supermax, я в свое время, тоже предлагал сделать не библиотеку функций, а библиотеку алгоритмов...


ps. несколько функций из библиотеки:

проверка двух поверхностей, что они лежат на одной плоскости (совпадают)
Код:
[Выделить все]
(defun eq-plane (p1 p2 v1 v2)
 ;; ElpanovEvgeniy
 ;; 10.01.07
 ;; проверка двух поверхностей, что они лежат на одной плоскости (совпадают)
 ;; проверка производится на пересечение нормалей
 ;; и расстояние между плоскостями
 ;; p1 - точка на первой плоскости
 ;; p2 - точка на второй плоскости
 ;; v1 - вектор нормали первой поверхности
 ;; v2 - вектор нормали второй поверхности
 ;; (setq fuzz 1e-6)
 ;;(eq-plane '(0. 0. 1) '(1. 1. 1) '(0. 0. 1) '(0. 0. 5))
 (and (null (inters '(0. 0. 0.) v1 '(0. 0. 0.) v2 nil))
      (equal (- (caddr (trans p2 0 v1)) (caddr (trans p1 0 v1))) 0. fuzz)
 ) ;_  and
) ;_  defun
функция пересечения прямой и плоскости, прямая задается двумя точками
Код:
[Выделить все]
(defun inters_w-line-2p (P1 P2 V VP / P)
 ;; ElpanovEvgeniy
 ;; 10.01.07
 ;; функция пересечения прямой и плоскости, прямая задается двумя точками
 ;; P1 P2 - прямая
 ;; V     - вектор нормали плоскости
 ;; VP    - точка на плоскости
 ;;(inters_w-line '(5. 5. 5.) '(10. 10. 10.) '(1. 0. 0.) '(0. 0. 2))
 (if (setq p ((lambda (a b)
               (inters a
                       b
                       (list (car a) (cadr a) (caddr vp))
                       (list (car b) (cadr b) (caddr vp))
                       nil
               ) ;_  inters
              ) ;_  lambda
              (trans p1 0 v)
              (trans p2 0 v)
             )
     ) ;_  setq
  (trans p v 0)
 ) ;_  if
) ;_  defun
функция пересечения прямой и плоскост, прямая задается точкой и вектором
Код:
[Выделить все]
(defun inters_w-line-vp (PL VL V VP / P)
 ;; ElpanovEvgeniy
 ;; 10.01.07
 ;; функция пересечения прямой и плоскости,
 ;; прямая задается точкой и вектором
 ;; PL    - точка на прямой
 ;; VL    - вектор направления прямой
 ;; VP    - точка на плоскости
 ;; V     - вектор нормали плоскости
 ;;(inters_w-line-vp '(5. 5. 5.) '(1. 1. 1.) '(1. 0. 0.) '(0. 0. 2))
 (if (setq p ((lambda (a b)
               (inters a
                       b
                       (list (car a) (cadr a) (caddr vp))
                       (list (car b) (cadr b) (caddr vp))
                       nil
               ) ;_  inters
              ) ;_  lambda
              (trans pl 0 v)
              (trans (mapcar (function +) pl vl) 0 v)
             )
     ) ;_  setq
  (trans p v 0)
 ) ;_  if
) ;_  defun
функция вычисления единичного вектора по двум точкам
Код:
[Выделить все]
(defun pp-edv (p1 p2 / d)
 ;; ElpanovEvgeniy
 ;; 10.01.07
 ;; функция вычисления единичного вектора по двум точкам
 ;; p1 - точка на первой плоскости
 ;; p2 - точка на второй плоскости
 ;;(pp-edv '(5. 5. 5.) '(1. 1. 1.))
 (cond ((zerop (setq d (distance p1 p2))) nil)
       ((mapcar (function (lambda (a b c) (/ (- a b) c))) p2 p1 (list d d d)))
 ) ;_  cond
) ;_  defun
функция вычисления единичного вектора из вектора
Код:
[Выделить все]
(defun v-edv (v / d)
 ;; ElpanovEvgeniy
 ;; 10.01.07
 ;; функция вычисления единичного вектора из вектора
 ;; V - вектор
 ;; (v-edv '(5 5 5))
 (cond ((zerop (setq d (distance '(0. 0. 0.) v))) nil)
       ((mapcar (function /) v (list d d d)))
 ) ;_  cond
) ;_  defun

Функция вычисления вектора нормали по двум векторам
Код:
[Выделить все]
(defun v_norm_2v (v1 v2)
 ;; ElpanovEvgeniy
 ;; 10.01.07
 ;; Функция вычисления вектора нормали по двум векторам
 ;; (v_norm_2v v1 v2)
 ;; (v_norm_2v '(5. 10. 0.) '(1. 2. 3.))
 ((lambda (a b)
   (mapcar (function (lambda (a1 b1 a2 b2) (- (* a1 b1) (* a2 b2))))
           a
           (cdr b)
           b
           (cdr a)
   ) ;_  mapcar
  ) ;_  lambda
  (list (cadr v1) (caddr v1) (car v1) (cadr v1))
  (list (cadr v2) (caddr v2) (car v2) (cadr v2))
 )
) ;_  defun
функции из библиотеки Григория Черевкова (Элекран)
Функция вычисления вектора нормали по двум векторам
Код:
[Выделить все]
(defun 3d_wnorm (W1 W2)
 ;; функции из библиотеки Григория Черевкова (Элекран)
 ;; Функция вычисления вектора нормали по двум векторам
 ;;(v_norm_2v '(5. 10. 0.) '(1. 2. 3.))
 (list (- (* (cadr W1) (caddr W2)) (* (caddr W1) (cadr W2)))
       (- (* (caddr W1) (car W2)) (* (car W1) (caddr W2)))
       (- (* (car W1) (cadr W2)) (* (cadr W1) (car W2)))
 ) ;_  list
) ;_  defun
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны.
/Сунь Цзы/

Последний раз редактировалось Елпанов Евгений, 08.12.2009 в 16:31.
Елпанов Евгений вне форума  
 
Автор темы   Непрочитано 08.12.2009, 17:12
#143
Supermax

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


Как нибудь соберусь с духом и подправлю первый пост. Что-то очень много одинаковых по назначению функций собралось. Надо выбрать самые красивые.
А библиотеку функций надо просто модернизировать. Как? - пока не знаю.

Есть очень интересная задача, связанная, между прочим, с 1 DXF кодами солидов да, да. Спасибо тебе Евгений, за подарок.

Есть пространство, в нем куча точек, точнее мы имеем список списков точек с их координатами. Надо найти две самые удаленные друг от друга точки. Если таких больше двух - nil
Supermax вне форума  
 
Непрочитано 08.12.2009, 17:25
#144
Елпанов Евгений

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


Цитата:
Сообщение от Supermax Посмотреть сообщение
Если таких больше двух - nil
опять применительно к частностям? Если есть облако точек и три находятся на одинаковом и максимальном расстоянии, то надо либо вернуть одну пару, те. только две точки, либо все три пары! Случай, когда информация уже не нужна - частный случай, который подходит для твоей конкретной задачи. Хотя, на основе основного кода, можно сделать функцию проверки - сколько пар найдено...


Цитата:
Сообщение от Supermax Посмотреть сообщение
Спасибо тебе Евгений, за подарок.
Какой подарок?
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны.
/Сунь Цзы/
Елпанов Евгений вне форума  
 
Автор темы   Непрочитано 08.12.2009, 19:44
#145
Supermax

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


Да я скромно, так, чтобы не наглеть. Стал писать про вектора, анализ, и понял - пошлют. Остановился на двух точках.

А про подарок - http://dwg.ru/dnl/4451
Забыл? А я расколупал. Сделал функцию, которая считает длинну цилиндра, даже если ты его порезал с обеих концов и дырок в нем насверлил.
Правда я дырок не сверлю, и наискосок почти никогда не режу, но солидами трубы делаю. Мне надо для исполнительной длинну каждой. И оси в них линиями делать. Вот тут ты мне помог! Низкий мой поклон. Без этой инфы - как без рук был.


Могу выложить в новой теме для освистания.

А смысл следующий. Есть установка, что облако точек делится на две группы. Одна - все точки в одной плоскости, а другая - в другой. Расстояние между этими плоскостями и есть искомый результат.
Надо определить наличие таких плоскостей, а они есть и даже вектора к ним есть, все точки к ним уже приписаны. Осталось только как-то расстояние между плоскостями замерить. Точки по плоскости разбросаны, но каждая имеет пару на противоположной.
Грубо говоря, солид имеет несколько плоскостей и надо замерить длинну у тех, которые самые маленькие по площади, или площадь уже известна, в виде аргумента функции дается.

Последний раз редактировалось Supermax, 08.12.2009 в 19:52.
Supermax вне форума  
 
Непрочитано 08.12.2009, 19:52
#146
Елпанов Евгений

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


Ааа, ну тогда ладно...
Просто все представленные мной, в этой теме, функции - настоящий оффтоп! Там никакой тригонометрии и даже линейной алгебры. Максимум - перемножение векторов...
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны.
/Сунь Цзы/
Елпанов Евгений вне форума  
 
Непрочитано 08.12.2009, 20:09
#147
zamtmn

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


Цитата:
Есть пространство, в нем куча точек, точнее мы имеем список списков точек с их координатами. Надо найти две самые удаленные друг от друга точки.
и
Цитата:
А смысл следующий. Есть установка, что облако точек делится на две группы. Одна - все точки в одной плоскости, а другая - в другой. Расстояние между этими плоскостями и есть искомый результат.
совсем разные вещи.
дергать информацию из солидов - всеравно что распечатать чертеж а потом оцифровывать и мерить длины. охота объемных труб - добро пожаловать в МЕП
zamtmn вне форума  
 
Непрочитано 08.12.2009, 20:16
#148
Елпанов Евгений

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


Спасибо zamtmn, я понял про облако точек. Supermax, ты что, не стал разбираться с солидами, а просто вытащил оттуда точки и пытаешься восстановить размеры цилиндров? Я то думал, ты действительно разобрался с описанием трехмерных тел - там не так сложно, тем более, если только цилиндры, а получилось, ты научился извлекать точки и придумал, что делать дальше. Если ты действительно разберешься с описанием формата - будет проще и точнее. А задачку про облако точек - оставим студентам...
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны.
/Сунь Цзы/
Елпанов Евгений вне форума  
 
Автор темы   Непрочитано 08.12.2009, 20:55
#149
Supermax

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


Вы как террористы. Народ конкретикой озабочен (я в смысле), а вы его на научные подвиги толкаете.
Вот стала у меня задача колом в горле, я ее и решил. Да что там решать?
В цилиндре всего две плоскости с радиусом
Код:
[Выделить все]
("ellipse-curve $-1 -1 $-1 148.07186247359115 77.578418280957393 -2.3205436570539785e-030 
                           -0.91537347899412247 0.4026057549938859 -0 
                           -6.7629448227472997 -15.376383108923761 -3.9464094645501665e-015 
                           0.95249809790483786 I I #" 
"ellipse-curve $-1 -1 $-1 273.40350000000001 64.382500000000022 3.5045967281109811e-030 
                           0.99450287985200081 -0.10470922579255794 4.622231866529366e-032
                           -1.675347612680927 -15.912046077632013 -3.9464094645501665e-015 
                           1 I I #")
Первых три - x,y,z центра плоскости
Вторые три - x,y,z нормали плоскости
Третьи три - x,y,z вектор-радиуса
потом коофициент элипсности (или как там его)
А все остальное - пока подождет.
Если в трубе "штаны" не вырезать и прямоугольным профилем пазы не резать - больше ничего колупать не надо.
Если трубу сделать полую, то четыре ellipse-curve. Два с одним радиусом, а два с другим. Посортировал по радиусам и баеньки.
Все остальное - ЕГОР и на помойку.
Если я буду в эти английские письмена тщательно вчитываться - помру.

p.s. Между прочим, я не для себя хочу задачку решить, а для народа, который прокатом озабочен.

p.s.2 Изучая эти ...curve заметил интересную особенность. Оказывается есть 0 и есть -0 и это не спроста. Вот тут и почитать не грех.

Последний раз редактировалось Supermax, 08.12.2009 в 21:17.
Supermax вне форума  
 
Непрочитано 08.12.2009, 22:22
#150
zamtmn

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


>>0 и есть -0
очень маленькое положительное и очень маленькое отрицательное. считай 0
zamtmn вне форума  
Ответ
Вернуться   Форум 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