;|
Psevdo-Aksonometr gorizontal ver 3.3

All rights reserved including right of reproduction in whole or in part in ang form.

Перевод прямоугольного чертежа (плана) из плоскости "XY <90" в псевдоаксонометрическую
плоскость "XY <45" (сантехническая аксонометрия), при этом угол может быть задан
от 0 до 90 градусов считая от положительного направления оси Х против часовой стрелки.
ВНИМАНИЕ:
программа работает только для следующих типов объектов:
- линия "LINE" (правильная работа гарантируется)
- дуга "ARC"
- полилиния "LWPOLYLINE" без криволинейных сегментов
- круг "CIRCLE" (пересчет в эллипс)
- прямоугольник "RECTANGLE" (также, как и полилиния)
- многоугольник "POLYGON" (также, как и полилиния)
- текст "TEXT", "MTEXT" (перемещение без поворота)
ИСХОДНЫЕ ОБЪЕКТЫ НЕ СОХРАНЯЮТСЯ (апгрейдятся они :)

Планируется сделать пересчет для:
- фигура "SOLID"
- полоса "TRACE"
- кольцо "DONUT"
- блок "INSERT"

!!! ВСЕ ДРУГИЕ ОБЪЕКЫ БУДУТ ИГНОРИРОВАТЬСЯ !!!

ПРИМЕР:
Command: gakson
ПРОГРАММА ПЕРЕВОДА ПЛАНА В АКСОНОМЕТРИЧЕСКУЮ ПРОЕКЦИЮ.
Выберите объекты:
Select objects: Specify opposite corner: 13 found
Select objects:
Введите угол в градусах (от 0 до 90), : 60
Укажите точку поворота :
0
(к этому моменту все указанные выше объекты уже перестроены в аксонометрию)
Command:
|;

(defun C:gakson ( / *error*)
(setq p_cmdecho (getvar "CMDECHO")
p_snapmode (getvar "SNAPMODE")
p_orthomode (getvar "ORTHOMODE")
p_blipmode (getvar "BLIPMODE")
p_osmode (getvar "OSMODE")
)

(defun *error* (msg) ; Переопределение функции ERROR
(princ "Программа прервана пользователем")
(setvar "SNAPMODE" p_snapmode)
(setvar "ORTHOMODE" p_orthomode)
(setvar "BLIPMODE" p_blipmode)
(setvar "OSMODE" p_osmode)
(setvar "CMDECHO" p_cmdecho)
; (setvar "ERRNO" 0)
(setq p_cmdecho nil p_snapmode nil p_orthomode nil p_osmode nil p_blipmode nil)
; (princ "\n END with ERROR")
(princ)
) ; defun(*error*)

(setvar "CMDECHO" 0)
(setvar "SNAPMODE" 0)
(setvar "ORTHOMODE" 0)
(setvar "BLIPMODE" 0)
(setvar "OSMODE" 1)
(gc)

(setq stangle nil stangle1 nil endangle nil endangle1 nil bit10 nil bit10new nil
bit11 nil bit11new nil bit50 nil bit50new nil bit51 nil bit51new nil object_new nil)
(setq n 0 nabr nil number 0 name nil processed_obj 0)

(princ "\n2D Axonometric Conversion Programm")
(princ "\nSelect Objects")
(setq nabr (ssget))
(setq number (sslength nabr))
(initget 6)
(setq ugol (getreal "\n Enter Rotation Angle from 0-90 : "))
(if (null ugol) (setq ugol 45.0))
(setq ugolrad (* pi (/ ugol 180.0)))
(setq point (getpoint "\n Select Rotation Point : ")
x0 (car point)
y0 (cadr point)
)
(princ "\n")
(setvar "OSMODE" 0)
(while (> number n)
(setq name (ssname nabr n))
(setq object (entget name))
(setq klass (cdr (assoc 0 object)))
(if (= (cdr (assoc 70 (tblsearch "LAYER" (cdr (assoc 8 object))))) 4) ; бит 4 - слой заблокирован (проверять для каждой версии AutoCAD'a)
(vl-cmdf "_.-layer" "_U" (cdr (assoc 8 object)) "")
)
; разделение по типам объектов
(cond
;;;----- Обработка примитивов типа "LINE", пересчет координат вершин
((eq klass "LINE")
(setq bit10 (assoc 10 object)
bit11 (assoc 11 object)
x1 (cadr bit10)
y1 (caddr bit10)
z1 (cadddr bit10)
x2 (cadr bit11)
y2 (caddr bit11)
z2 (cadddr bit11)

x1n (+ (* (- y1 y0) (cos ugolrad)) x1)
y1n (+ (* (- y1 y0) (sin ugolrad)) y0)
x2n (+ (* (- y2 y0) (cos ugolrad)) x2)
y2n (+ (* (- y2 y0) (sin ugolrad)) y0)

bit10new (list 10 x1n y1n z1)
bit11new (list 11 x2n y2n z2)

object_new (subst bit10new bit10 object)
object_new (subst bit11new bit11 object_new)

processed_obj (1+ processed_obj)
)
(entmod object_new)
(entupd name)
) ; equal klass "LINE"

;;;----- Обработка примитивов типа "LWPOLYLINE", пересчет координат вершин
((eq klass "LWPOLYLINE")
(foreach item object ; выбор из описания полилинии координат вершин
(if (= (car item) 10)
(setq coords (cons item coords))
)
)
(setq vertex (length coords) num_ver 0 object_new object)
(while (> vertex num_ver)
(setq bit10 (nth num_ver coords)
x1 (cadr bit10)
y1 (caddr bit10)

x1n (+ (* (- y1 y0) (cos ugolrad)) x1)
y1n (+ (* (- y1 y0) (sin ugolrad)) y0)

bit10new (list 10 x1n y1n)

object_new (subst bit10new bit10 object_new)
)
(setq num_ver (1+ num_ver))
) ; while(vertex>num_ver)
(entmod object_new)
(entupd name)
(setq processed_obj (1+ processed_obj) coords nil vertex nil)
) ; equal klass "LWPOLYLINE"

;;;----- Обработка примитивов типа "CIRCLE", пересчет координат центра
;;; для преобразования окружности в эллипс используется коэффициенты (эмпирические):
;;; Rmin/Rmax=-0,0000000000943901414007017*ugol^4+0,000000567997308646077*ugol^3-0,0000362793934898559*ugol^2+0,00997592958744082*ugol-0,0128148277900414
;;; Rmax/Rокр=0,000000000310680082815694*ugol^4+0,00000000353048189760587*ugol^3-0,0000539963966370921*ugol^2+0,00000236411058931183*ugol+1,41420291881995
((eq klass "CIRCLE")
(setq bit8 (assoc 8 object) ; слой объекта
bit10 (assoc 10 object) ; координаты центра окружности
bit40 (assoc 40 object) ; радиус окружности
bit67 (assoc 67 object) ; пространство модель/лист
bit410 (assoc 410 object) ; имя пространства
x1 (cadr bit10)
y1 (caddr bit10)
z1 (cadddr bit10)
radius (cdr bit40)
x1n (+ (* (- y1 y0) (cos ugolrad)) x1)
y1n (+ (* (- y1 y0) (sin ugolrad)) y0)
)
(if (= ugol 45.0)
(setq radiuscoeff (/ 54.11961001 130.65629649)
Rmaxcoeff (/ 130.65629649 100.0)
)
(setq radiuscoeff (- (+ (* 0.000000567997308646077 (expt ugol 3.0)) (* 0.00997592958744082 ugol)) (* 0.0000000000943901414007017 (expt ugol 4.0)) (* 0.0000362793934898559 (expt ugol 2.0)) 0.0128148277900414)
Rmaxcoeff (- (+ (* 0.000000000310680082815694 (expt ugol 4.0)) (* 0.00000000353048189760587 (expt ugol 3.0)) (* 0.00000236411058931183 ugol) 1.41420291881995) (* 0.0000539963966370921 (expt ugol 2.0)))
)
)
(setq Xbit11 (* Rmaxcoeff radius (cos (* pi (/ ugol 360.0))))
Ybit11 (* Rmaxcoeff radius (sin (* pi (/ ugol 360.0))))
bit10new (list 10 x1n y1n z1)
bit11new (list 11 Xbit11 Ybit11 z1)
bit40new (cons 40 radiuscoeff)
bit42new (cons 42 (* pi 2.0))

processed_obj (1+ processed_obj)
)
(entmakex (list '(0 . "ELLIPSE") '(100 . "AcDbEntity") bit67 bit410 bit8
'(100 . "AcDbEllipse") bit10new bit11new '(210 0.0 0.0 1.0)
bit40new '(41 . 0.0) bit42new))
(entdel name)
) ; equal klass "CIRCLE"

;;;----- Обработка примитивов типа "ARC", пересчет координат центра и вершин
((eq klass "ARC")
(setq bit8 (assoc 8 object) ; слой объекта
bit10 (assoc 10 object) ; координаты центра дуги
bit40 (assoc 40 object) ; радиус дуги
bit50 (assoc 50 object) ; начальный угол (радианы)
bit51 (assoc 51 object) ; конечный угол (радианы)
bit67 (assoc 67 object) ; пространство модель/лист
bit410 (assoc 410 object) ; имя пространства
x1 (cadr bit10)
y1 (caddr bit10)
z1 (cadddr bit10)
radius (cdr bit40)
stangle (cdr bit50)
endangle (cdr bit51)
x1n (+ (* (- y1 y0) (cos ugolrad)) x1)
y1n (+ (* (- y1 y0) (sin ugolrad)) y0)
chetv (* pi (/ 90.0 180.0))
eighth (* pi (/ ugol 360.0))
)
(if (and (>= stangle 0.0) (= endangle 0.0) (= stangle (* pi 0.5)) (= endangle (* pi 0.5)) (= stangle pi) (= endangle pi) (= stangle (* pi 1.5)) (= endangle (* pi 1.5)) (< endangle (* pi 2.0)))
(setq endangle1 (- endangle (* (- chetv ugolrad) (- 4.0 (/ endangle chetv)))))) ; if для IV четверти

(if (= ugol 45.0)
(setq radiuscoeff (/ 54.11961001 130.65629649)
Rmaxcoeff (/ 130.65629649 100.0)
)
(setq radiuscoeff (- (+ (* 0.000000567997308646077 (expt ugol 3.0)) (* 0.00997592958744082 ugol)) (* 0.0000000000943901414007017 (expt ugol 4.0)) (* 0.0000362793934898559 (expt ugol 2.0)) 0.0128148277900414)
Rmaxcoeff (- (+ (* 0.000000000310680082815694 (expt ugol 4.0)) (* 0.00000000353048189760587 (expt ugol 3.0)) (* 0.00000236411058931183 ugol) 1.41420291881995) (* 0.0000539963966370921 (expt ugol 2.0)))
)
)
(setq Xbit11 (* Rmaxcoeff radius (cos (* pi (/ ugol 360.0))))
Ybit11 (* Rmaxcoeff radius (sin (* pi (/ ugol 360.0))))
bit10new (list 10 x1n y1n z1)
bit11new (list 11 Xbit11 Ybit11 z1)
bit40new (cons 40 radiuscoeff)
bit41new (cons 41 stangle1)
bit42new (cons 42 endangle1)

processed_obj (1+ processed_obj)
)
(entmakex (list '(0 . "ELLIPSE") '(100 . "AcDbEntity") bit67 bit410 bit8
'(100 . "AcDbEllipse") bit10new bit11new '(210 0.0 0.0 1.0)
bit40new bit41new bit42new))
(entdel name)

) ; equal klass "ARC"

;;;----- Обработка примитивов типа "*TEXT" и "POINT", пересчет координат точки вставки
((member klass '("TEXT" "MTEXT" "POINT"))
(setq bit10 (assoc 10 object)
x1 (cadr bit10)
y1 (caddr bit10)
z1 (cadddr bit10)

x1n (+ (* (- y1 y0) (cos ugolrad)) x1)
y1n (+ (* (- y1 y0) (sin ugolrad)) y0)

bit10new (list 10 x1n y1n z1)
object_new (subst bit10new bit10 object)

processed_obj (1+ processed_obj)
)
(entmod object_new)
(entupd name)
) ; member klass "*TEXT" "POINT"

) ; cond
(setq n (+ n 1))

) ;while(main)

(if (/= n processed_obj)
(princ (strcat "\nUnchanged Objects " (rtos (- n processed_obj) 2 0) ".\n"))
)
(setvar "SNAPMODE" p_snapmode)
(setvar "ORTHOMODE" p_orthomode)
(setvar "BLIPMODE" p_blipmode)
(setvar "OSMODE" p_osmode)
(setvar "CMDECHO" p_cmdecho)
; (setvar "ERRNO" 0)

)
(c:gakson)
; defun

Advertisements