Координаты, определяющие геометрию большинства плоских объектов (таких как дуги, окружности, 2D-полилинии и т. Д. c.), Определяются относительно системы координат, известной как Система координат объекта (OCS ).
OCS делит свое происхождение от Всемирной системы координат (WCS), а ее ось Z соответствует нормальному вектору (так называемому вектору экструзии), связанному с объектом (представленным группой DXF 210
). и его оси X и Y, определенные алгоритмом произвольной оси , примененным к вектору нормали.
алгоритм произвольной оси реализован в стандартном AutoLISP trans
функция, которая облегчает преобразование точек из одной системы координат в другую.
В вашем конкретном примере вектор нормали равен (0.0 0.0 1.0)
, который равен вектору нормали плоскости WCS, и поэтому для этого конкретный пример, OCS равен WCS.
Однако, в общем, для перевода точек из произвольного OC S либо в WCS, либо в активную пользовательскую систему координат (UCS), вы должны предоставить функции trans
либо вектор нормали OCS, либо имя объекта рассматриваемого объекта.
Например, перевод из OCS в активную UCS с использованием вектора нормалей OCS:
(trans (cdr (assoc 10 <dxf-data>)) (cdr (assoc 210 <dxf-data>)) 1)
Или перевод из OCS в активную UCS с использованием имени объекта:
(trans (cdr (assoc 10 <dxf-data>)) (cdr (assoc -1 <dxf-data>)) 1)
Реализовано в примере программы это может быть:
(defun c:test ( / ent enx )
(cond
( (not (setq ent (car (entsel "\nSelect circle: "))))
(princ "\nNothing selected.")
)
( (/= "CIRCLE" (cdr (assoc 0 (setq enx (entget ent)))))
(princ "\nThe selected object is not a circle.")
)
( (princ "\nThe circle center relative to the UCS is: ")
(princ (trans (cdr (assoc 10 enx)) ent 1))
)
)
(princ)
)
Для решения проблем, с которыми вы сталкиваетесь, как описано в ваших комментариях, вам необходимо преобразовать координаты из / в OCS & UCS для достижения желаемый результат, например:
(defun c:test ( / ent enx new old xco )
(cond
( (not (setq ent (car (entsel "\nSelect circle: "))))
(princ "\nNothing selected.")
)
( (/= "CIRCLE" (cdr (assoc 0 (setq enx (entget ent)))))
(princ "\nThe selected object is not a circle.")
)
( (setq old (assoc 10 enx)
xco (car (trans (cdr old) ent 1))
new (cons 10 (trans (list xco 0.0 0.0) 1 ent))
enx (subst new old enx)
)
(entmod enx)
)
)
(princ)
)
Операция также может быть сведена к одному выражению, например:
(setq old (assoc 10 enx)
enx (subst (cons 10 (trans (list (car (trans (cdr old) ent 1)) 0) 1 ent)) old enx)
)
(entmod enx)
Однако, это менее читабельно.