找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 253|回复: 0

将一组对象从正交参考系投影到 倾斜的视角,然后从一个倾斜的视角到另一个倾斜的视角

[复制链接]

0

主题

0

回帖

26

积分

管理员

积分
26
发表于 2024-2-17 23:08:54 | 显示全部楼层 |阅读模式
  1. ;;-------------------------=={ 2D Projection }==------------------------;;
  2. ;;                                                                      ;;
  3. ;;  This program provides the user with a means of projecting a         ;;
  4. ;;  selected set of planar objects from one reference frame to another. ;;
  5. ;;                                                                      ;;
  6. ;;  Upon issuing the command syntax '2dpro' at the AutoCAD              ;;
  7. ;;  command-line, the user is prompted to select a set of 2D planar     ;;
  8. ;;  objects to be projected. This selection is restricted to Arcs,      ;;
  9. ;;  Circles, Elipses, Lines, LWPolylines, 2D (Heavy) Polylines,         ;;
  10. ;;  2D Splines & Points.                                                ;;
  11. ;;                                                                      ;;
  12. ;;  The user is then prompted to select a source reference frame &      ;;
  13. ;;  a destination reference frame. For each of these prompts, the       ;;
  14. ;;  program requires the user to select a closed LWPolyline with four   ;;
  15. ;;  non-collinear vertices. Following each selection, the program       ;;
  16. ;;  will ensure the points are counter-clockwise oriented with the      ;;
  17. ;;  points ordered such that the lower-left vertex appears first.       ;;
  18. ;;                                                                      ;;
  19. ;;  Following valid user responses, the program will then convert the   ;;
  20. ;;  four 2D points defining each reference frame into homogeneous       ;;
  21. ;;  coordinates, and will calculate the transformation matrix to map    ;;
  22. ;;  from the source reference frame (or projective space) to the        ;;
  23. ;;  destination reference frame.                                        ;;
  24. ;;                                                                      ;;
  25. ;;  The program will then iterate over the set of selected objects      ;;
  26. ;;  and, for each object, will calculate a 2D point set describing or   ;;
  27. ;;  (in the case of curved objects) approximating the object.           ;;
  28. ;;                                                                      ;;
  29. ;;  Each point is then converted to homogeneous coordinates and mapped  ;;
  30. ;;  to the destination reference frame using the tranformation matrix,  ;;
  31. ;;  before being converted back to cartesian coordinates.               ;;
  32. ;;                                                                      ;;
  33. ;;  The program will then generate either a Point, Line or LWPolyline   ;;
  34. ;;  from the mapped point(s) with properties matching those of the      ;;
  35. ;;  original object.                                                    ;;
  36. ;;----------------------------------------------------------------------;;
  37. ;;  Author:  Lee Mac, Copyright ?2014  -  www.lee-mac.com              ;;
  38. ;;----------------------------------------------------------------------;;
  39. ;;  Version 1.0    -    2014-10-10                                      ;;
  40. ;;                                                                      ;;
  41. ;;  First release.                                                      ;;
  42. ;;----------------------------------------------------------------------;;
  43. (defun c:2dpro ( / *error* des ent enx idx lst mat ocs sel src typ )
  44.     (defun *error* ( msg )
  45.         (LM:endundo (LM:acdoc))
  46.         (if (not (wcmatch (strcase msg t) "*break,*cancel*,*exit*"))
  47.             (princ (strcat "\nError: " msg))
  48.         )
  49.         (princ)
  50.     )
  51.     (LM:startundo (LM:acdoc))
  52.     (if
  53.         (and
  54.              (setq sel
  55.                  (LM:ssget "\nSelect objects to project: "
  56.                     '(   "采用:L"
  57.                          (
  58.                              (-4 . "<OR")
  59.                                  (-4 . "<AND")
  60.                                      (0 . "ARC,CIRCLE,ELLIPSE,LINE,*POLYLINE,POINT")
  61.                                      (-4 . "<NOT")
  62.                                          (-4 . "<AND")
  63.                                              (0 . "POLYLINE") (-4 . "&") (70 . 88)
  64.                                          (-4 . "AND>")
  65.                                      (-4 . "NOT>")
  66.                                  (-4 . "AND>")
  67.                                  (-4 . "<AND")
  68.                                      (0 . "SPLINE") (-4 . "&=") (70 . 8)
  69.                                  (-4 . "AND>")
  70.                              (-4 . "OR>")
  71.                          )
  72.                      )
  73.                  )
  74.              )
  75.              (setq src (2dprojection:getreferenceframe "\nSelect source reference frame: "))
  76.              (setq des (2dprojection:getreferenceframe "\nSelect destination reference frame: "))
  77.              (setq mat (2dprojection:getmatrix src des))
  78.              (setq ocs (trans '(0.0 0.0 1.0) 1 0 t))
  79.         )
  80.         (repeat (setq idx (sslength sel))
  81.             (setq ent (ssname sel (setq idx (1- idx)))
  82.                   enx (entget ent)
  83.                   typ (cdr (assoc 0 enx))
  84.             )
  85.             (cond
  86.                 (   (= "POINT" typ)
  87.                     (entmake
  88.                         (vl-list*
  89.                            '(0 . "POINT")
  90.                             (cons 10 (trans (2dprojection:mappoint mat (trans (cdr (assoc 10 enx)) 0 ocs)) ocs 0))
  91.                             (LM:defaultprops enx)
  92.                         )
  93.                     )
  94.                 )
  95.                 (   (= "LINE" typ)
  96.                     (entmake
  97.                         (vl-list*
  98.                            '(0 . "LINE")
  99.                             (cons 10 (trans (2dprojection:mappoint mat (trans (cdr (assoc 10 enx)) 0 ocs)) ocs 0))
  100.                             (cons 11 (trans (2dprojection:mappoint mat (trans (cdr (assoc 11 enx)) 0 ocs)) ocs 0))
  101.                             (LM:defaultprops enx)
  102.                         )
  103.                     )
  104.                 )
  105.                 (   (setq lst (LM:Entity->PointList ent))
  106.                     (entmake
  107.                         (append
  108.                             (list
  109.                                '(000 . "LWPOLYLINE")
  110.                                '(100 . "AcDbEntity")
  111.                                '(100 . "AcDbPolyline")
  112.                                 (cons 90 (length lst))
  113.                                 (if (vlax-curve-isclosed ent) '(70 . 1) '(70 . 0))
  114.                             )
  115.                             (LM:defaultprops enx)
  116.                             (mapcar '(lambda ( p ) (cons 10 (2dprojection:mappoint mat (trans p 0 ent)))) lst)
  117.                             (list (assoc 210 enx))
  118.                         )
  119.                     )
  120.                 )
  121.             )
  122.         )
  123.     )
  124.     (LM:endundo (LM:acdoc))
  125.     (princ)
  126. )
  127. ;; 2D Projection: Get Reference Frame  -  Lee Mac
  128. ;; Prompts the user to select a closed planar polyline with 4 vertices in
  129. ;; order to obtain 4 counter-clockwise oriented non-collinear points
  130. ;; defining a reference frame for the transformation.
  131. (defun 2dprojection:getreferenceframe ( msg / ent enx lst tmp )
  132.     (while
  133.         (progn (setvar 'errno 0) (setq ent (car (entsel msg)))
  134.             (cond
  135.                 (   (= 7 (getvar 'errno))
  136.                     (princ "\nMissed, try again.")
  137.                 )
  138.                 (   (null ent) nil)
  139.                 (   (or (/= "LWPOLYLINE" (cdr (assoc 0 (setq enx (entget ent)))))
  140.                         (zerop (logand 1 (cdr (assoc 70 enx))))
  141.                         (/= 4 (cdr (assoc 90 enx)))
  142.                         (/= 4 (length (setq lst (2dprojection:uniquefuzz (mapcar 'cdr (vl-remove-if-not '(lambda ( x ) (= 10 (car x))) enx)) 1e-8))))
  143.                         (2dprojection:checkcollinearity (cons (last lst) lst))
  144.                     )
  145.                     (setq lst nil)
  146.                     (princ "\nPlease select a closed polyline with 4 non-collinear vertices.")
  147.                 )
  148.             )
  149.         )
  150.     )
  151.     (if lst
  152.         (progn
  153.             (if (2dprojection:clockwise-p lst)
  154.                 (setq lst (reverse lst))
  155.             )
  156.             (setq tmp (apply 'mapcar (cons 'min lst)))
  157.             (repeat (car (vl-sort-i lst '(lambda ( a b ) (< (distance a tmp) (distance b tmp)))))
  158.                 (setq lst (append (cdr lst) (list (car lst))))
  159.             )
  160.             lst
  161.         )
  162.     )
  163. )
  164. ;; 2D Projection: Unique with Fuzz  -  Lee Mac
  165. ;; Returns a list with all elements considered duplicate to a given tolerance removed.
  166. (defun 2dprojection:uniquefuzz ( lst fuz )
  167.     (if lst
  168.         (cons (car lst)
  169.             (2dprojection:uniquefuzz
  170.                 (vl-remove-if
  171.                     (function (lambda ( x ) (equal x (car lst) fuz)))
  172.                     (cdr lst)
  173.                 )
  174.                 fuz
  175.             )
  176.         )
  177.     )
  178. )
  179. ;; 2D Projection: Check Collinearity  -  Lee Mac
  180. ;; Returns T if any three points in a supplied list are collinear.
  181. (defun 2dprojection:checkcollinearity ( lst )
  182.     (and (caddr lst)
  183.         (or (   (lambda ( a b c )
  184.                     (or (equal (+ a b) c 1e-8)
  185.                         (equal (+ b c) a 1e-8)
  186.                         (equal (+ c a) b 1e-8)
  187.                     )
  188.                 )
  189.                 (distance (car  lst) (cadr  lst))
  190.                 (distance (cadr lst) (caddr lst))
  191.                 (distance (car  lst) (caddr lst))
  192.             )
  193.             (2dprojection:checkcollinearity (cdr lst))
  194.         )
  195.     )
  196. )
  197. ;; 2D Projection: Clockwise-p  -  Lee Mac
  198. ;; Returns T if the supplied point list is clockwise oriented.
  199. (defun 2dprojection:clockwise-p ( lst )
  200.     (minusp
  201.         (apply '+
  202.             (mapcar
  203.                 (function
  204.                     (lambda ( a b )
  205.                         (- (* (car b) (cadr a)) (* (car a) (cadr b)))
  206.                     )
  207.                 )
  208.                 lst (cons (last lst) lst)
  209.             )
  210.         )
  211.     )
  212. )
  213. ;; 2D Projection: Map Point  -  Lee Mac
  214. ;; Converts a supplied 2D point to homogeneous coordinates, applies a
  215. ;; matrix transformation & then converts the result back to cartesian coordinates.
  216. (defun 2dprojection:mappoint ( mat pnt )
  217.     (apply (function (lambda ( x y z ) (list (/ x z) (/ y z))))
  218.         (mxv mat (list (car pnt) (cadr pnt) 1.0))
  219.     )
  220. )
  221. ;; 2D Projection: Get Matrix  -  Lee Mac
  222. ;; Calculates the transformation matrix for transforming
  223. ;; homogeneous 2D points from one reference frame to another.
  224. (defun 2dprojection:getmatrix ( l1 l2 / f )
  225.     (mxm
  226.         (
  227.             (setq f
  228.                 (lambda ( l / c m )
  229.                     (setq c
  230.                         (mxv
  231.                             (invm
  232.                                 (setq m
  233.                                     (trp
  234.                                         (mapcar
  235.                                             (function
  236.                                                 (lambda ( a b )
  237.                                                     (list (car a) (cadr a) b)
  238.                                                 )
  239.                                             )
  240.                                             l '(1.0 1.0 1.0)
  241.                                         )
  242.                                     )
  243.                                 )
  244.                             )
  245.                             (list (car (last l)) (cadr (last l)) 1.0)
  246.                         )
  247.                     )
  248.                     (mapcar '(lambda ( r ) (mapcar '* r c)) m)
  249.                 )
  250.             )
  251.             l2
  252.         )
  253.         (invm (f l1))
  254.     )
  255. )
  256. ;; Default Properties  -  Lee Mac
  257. ;; Returns a list of DXF properties for the supplied DXF data,
  258. ;; substituting default values for absent DXF groups
  259. (defun LM:defaultprops ( enx )
  260.     (mapcar '(lambda ( x ) (cond ((assoc (car x) enx)) ( x )))
  261.        '(
  262.             (006 . "BYLAYER")
  263.             (008 . "0")
  264.             (039 . 0.0)
  265.             (048 . 1.0)
  266.             (062 . 256)
  267.             (370 . -1)
  268.         )
  269.     )
  270. )
  271. ;; Entity to Point List  -  Lee Mac
  272. ;; Returns a list of points describing or approximating the supplied entity,
  273. ;; else nil if the entity is not supported.
  274. (defun LM:entity->pointlist ( ent / acc der di1 di2 di3 enx fun inc lst par rad typ )
  275.     (setq enx (entget ent)
  276.           typ (cdr (assoc 0 enx))
  277.           acc 35.0
  278.     )
  279.     (cond
  280.         (   (= "POINT" typ)
  281.             (list (cdr (assoc 10 enx)))
  282.         )
  283.         (   (= "LINE" typ)
  284.             (list (cdr (assoc 10 enx)) (cdr (assoc 11 enx)))
  285.         )
  286.         (   (wcmatch typ "CIRCLE,ARC")
  287.             (setq di1 0.0
  288.                   di2 (vlax-curve-getdistatparam ent (vlax-curve-getendparam ent))
  289.                   inc (/ di2 (1+ (fix (* acc (/ di2 (cdr (assoc 40 enx)) (+ pi pi))))))
  290.                   fun (if (vlax-curve-isclosed ent) < <=)
  291.             )
  292.             (while (fun di1 di2)
  293.                 (setq lst (cons (vlax-curve-getpointatdist ent di1) lst)
  294.                       di1 (+ di1 inc)
  295.                 )
  296.             )
  297.             lst
  298.         )
  299.         (   (or (= typ "LWPOLYLINE")
  300.                 (and (= typ "POLYLINE") (zerop (logand (cdr (assoc 70 enx)) 80)))
  301.             )
  302.             (setq par 0)
  303.             (repeat (fix (1+ (vlax-curve-getendparam ent)))
  304.                 (if (setq der (vlax-curve-getsecondderiv ent par))
  305.                     (if (equal der '(0.0 0.0 0.0) 1e-8)
  306.                         (setq lst (cons (vlax-curve-getpointatparam ent par) lst))
  307.                         (if (setq rad (distance '(0.0 0.0) (vlax-curve-getfirstderiv ent par))
  308.                                   di1 (vlax-curve-getdistatparam ent par)
  309.                                   di2 (vlax-curve-getdistatparam ent (1+ par))
  310.                             )
  311.                             (progn
  312.                                 (setq inc (/ (- di2 di1) (1+ (fix (* acc (/ (- di2 di1) rad (+ pi pi)))))))
  313.                                 (while (< di1 di2)
  314.                                     (setq lst (cons (vlax-curve-getpointatdist ent di1) lst)
  315.                                           di1 (+ di1 inc)
  316.                                     )
  317.                                 )
  318.                             )
  319.                         )
  320.                     )
  321.                 )
  322.                 (setq par (1+ par))
  323.             )
  324.             (if (or (vlax-curve-isclosed ent) (equal '(0.0 0.0 0.0) der 1e-8))
  325.                 lst
  326.                 (cons (vlax-curve-getendpoint ent) lst)
  327.             )
  328.         )
  329.         (   (= "ELLIPSE" typ)
  330.             (setq di1 (vlax-curve-getdistatparam ent (vlax-curve-getstartparam ent))
  331.                   di2 (vlax-curve-getdistatparam ent (vlax-curve-getendparam   ent))
  332.                   di3 (* di2 (/ (+ pi pi) (abs (- (vlax-curve-getendparam ent) (vlax-curve-getstartparam ent)))))
  333.             )
  334.             (while (< di1 di2)
  335.                 (setq lst (cons (vlax-curve-getpointatdist ent di1) lst)
  336.                       der (distance '(0.0 0.0) (vlax-curve-getsecondderiv ent (vlax-curve-getparamatdist ent di1)))
  337.                       di1 (+ di1 (/ di3 (1+ (fix (/ acc (/ di3 der (+ pi pi)))))))
  338.                 )
  339.             )
  340.             (if (vlax-curve-isclosed ent)
  341.                 lst
  342.                 (cons (vlax-curve-getendpoint ent) lst)
  343.             )
  344.         )
  345.         (   (= "SPLINE" typ)
  346.             (setq di1 (vlax-curve-getdistatparam ent (vlax-curve-getstartparam ent))
  347.                   di2 (vlax-curve-getdistatparam ent (vlax-curve-getendparam   ent))
  348.                   inc (/ di2 25.0)
  349.             )
  350.             (while (< di1 di2)
  351.                 (setq lst (cons (vlax-curve-getpointatdist ent di1) lst)
  352.                       der (/ (distance '(0.0 0.0) (vlax-curve-getsecondderiv ent (vlax-curve-getparamatdist ent di1))) inc)
  353.                       di1 (+ di1 (if (equal 0.0 der 1e-10) inc (min inc (/ 1.0 der (* 10. inc)))))
  354.                 )
  355.             )
  356.             (if (vlax-curve-isclosed ent)
  357.                 lst
  358.                 (cons (vlax-curve-getendpoint ent) lst)
  359.             )
  360.         )
  361.     )
  362. )
  363. ;; Matrix Inverse  -  gile & Lee Mac
  364. ;; Uses Gauss-Jordan Elimination to return the inverse of a non-singular nxn matrix.
  365. ;; Args: m - nxn matrix
  366. (defun invm ( m / c f p r )
  367.     (defun f ( p m ) (mapcar '(lambda ( x ) (mapcar '(lambda ( a b ) (- a (* (car x) b))) (cdr x) p)) m))
  368.     (setq  m (mapcar 'append m (imat (length m))))
  369.     (while m
  370.         (setq c (mapcar '(lambda ( x ) (abs (car x))) m))
  371.         (repeat (vl-position (apply 'max c) c)
  372.             (setq m (append (cdr m) (list (car m))))
  373.         )
  374.         (if (equal 0.0 (caar m) 1e-14)
  375.             (setq m nil
  376.                   r nil
  377.             )
  378.             (setq p (mapcar '(lambda ( x ) (/ (float x) (caar m))) (cdar m))
  379.                   m (f p (cdr m))
  380.                   r (cons p (f p r))
  381.             )
  382.         )
  383.     )
  384.     (reverse r)
  385. )
  386. ;; Identity Matrix  -  Lee Mac
  387. ;; Args: n - matrix dimension
  388. (defun imat ( n / i j l m )
  389.     (repeat (setq i n)
  390.         (repeat (setq j n)
  391.             (setq l (cons (if (= i j) 1.0 0.0) l)
  392.                   j (1- j)
  393.             )
  394.         )
  395.         (setq m (cons l m)
  396.               l nil
  397.               i (1- i)
  398.         )
  399.     )
  400.     m
  401. )
  402. ;; Matrix x Matrix  -  Vladimir Nesterovsky
  403. ;; Args: m,n - nxn matrices
  404. (defun mxm ( m n )
  405.     ((lambda ( a ) (mapcar '(lambda ( r ) (mxv a r)) m)) (trp n))
  406. )
  407. ;; Matrix x Vector  -  Vladimir Nesterovsky
  408. ;; Args: m - nxn matrix, v - vector in R^n
  409. (defun mxv ( m v )
  410.     (mapcar '(lambda ( r ) (apply '+ (mapcar '* r v))) m)
  411. )
  412. ;; Matrix Transpose  -  Doug Wilson
  413. ;; Args: m - nxn matrix
  414. (defun trp ( m )
  415.     (apply 'mapcar (cons 'list m))
  416. )
  417. ;; ssget  -  Lee Mac
  418. ;; A wrapper for the ssget function to permit the use of a custom selection prompt
  419. ;; msg - [str] selection prompt
  420. ;; arg - [lst] list of ssget arguments
  421. (defun LM:ssget ( msg arg / sel )
  422.     (princ msg)
  423.     (setvar 'nomutt 1)
  424.     (setq sel (vl-catch-all-apply 'ssget arg))
  425.     (setvar 'nomutt 0)
  426.     (if (not (vl-catch-all-error-p sel)) sel)
  427. )
  428. ;; Start Undo  -  Lee Mac
  429. ;; Opens an Undo Group.
  430. (defun LM:startundo ( doc )
  431.     (LM:endundo doc)
  432.     (vla-startundomark doc)
  433. )
  434. ;; End Undo  -  Lee Mac
  435. ;; Closes an Undo Group.
  436. (defun LM:endundo ( doc )
  437.     (while (= 8 (logand 8 (getvar 'undoctl)))
  438.         (vla-endundomark doc)
  439.     )
  440. )
  441. ;; Active Document  -  Lee Mac
  442. ;; Returns the VLA Active Document Object
  443. (defun LM:acdoc nil
  444.     (eval (list 'defun 'LM:acdoc 'nil (vla-get-activedocument (vlax-get-acad-object))))
  445.     (LM:acdoc)
  446. )
  447. ;;----------------------------------------------------------------------;;
  448. (vl-load-com)
  449. (princ
  450.     (strcat
  451.         "\n:: 2DProjection.lsp | Version 1.0 | \\U+00A9 Lee Mac "
  452.         (menucmd "m=$(edtime,0,yyyy)")
  453.         " www.lee-mac.com ::"
  454.         "\n:: Type "2dpro" to Invoke ::"
  455.     )
  456. )
  457. (princ)
  458. ;;----------------------------------------------------------------------;;
  459. ;;                             End of File                              ;;
  460. ;;----------------------------------------------------------------------;;
复制代码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|膜结构网

GMT+8, 2024-12-28 18:15 , Processed in 0.110107 second(s), 23 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表