Search code examples
geometrylispscalingautocadautolisp

Extracting the new coordinates of a geometry scaled in AutoCAD


This is a followup to my previous post here

I've a 2D geometry created using the following code, ref.

(defun graph ( pts sls tls )

    (   (lambda ( l )
            (foreach x l (text (cdr x) (itoa (car x)) 0.0 1))
            (mapcar
               '(lambda ( a b / p q r )
                    (setq p (cdr (assoc a l))
                          q (cdr (assoc b l))
                          r (angle p q)
                    )
                    (entmake (list '(0 . "LINE") (cons 10 p) (cons 11 q) '(62 . 8)))
                    (text
                        (mapcar '(lambda ( x y ) (/ (+ x y) 2.0)) p q)
                        (rtos (distance p q) 2)
                        (if (and (< (* pi 0.5) r) (<= r (* pi 1.5))) (+ r pi) r)
                        2
                    )
                )
                sls tls
            )
        )
        (mapcar 'cons (vl-sort (append sls tls) '<) pts)
    )
)
(defun text ( p s a c )
    (entmake
        (list
           '(0 . "TEXT")
            (cons 10 p)
            (cons 11 p)
            (cons 50 a)
            (cons 01 s)
            (cons 62 c)
           '(40 . 2)
           '(72 . 1)
           '(73 . 2)
        )
    )
)

Input:

(graph
   '((75 25) (115 45) (90 60) (10 5) (45 0) (45 55) (0 25))
   '(1 1 1 1 2 2 3 4 4 5 6)
   '(2 3 4 5 3 6 6 5 7 7 7)
)

The resulting image

enter image description here

is scaled in AutoCAD by a factor of 10.

Any suggestions on how to obtain the XY coordinates after scaling will be really helpful.

In summary, I give the input coordinates and want the output to be the coordinates and lengths between the coordinates of the scaled geometry.

From what I understand from the suggestions offered in the previous post, the scaling can be done by using a scaling matrix in the code itself instead of using the SCALE command in GUI of AutoCAD. But, I am not sure how this has to be implemented.


Solution

  • As I noted in the comments to your other question, supplying a set of points to the function and then applying a scaling operation within the function, only to then have to obtain the resulting scaled points from the function is like the tail wagging the dog.

    A far better approach would be to scale the points before supplying them to the function; that way, the function requires no modification and you already have the set of scaled points constituting your network.

    Scaling relative to the origin is really easy: simply multiply each of the point coordinates by the scale factor, e.g.:

    (defun c:test ( / lst scl )
        (setq lst '((75 25) (115 45) (90 60) (10 5) (45 0) (45 55) (0 25))
              scl 0.1
        )
        (graph
            (mapcar '(lambda ( x ) (mapcar '* x (list scl scl))) lst)
           '(1 1 1 1 2 2 3 4 4 5 6)
           '(2 3 4 5 3 6 6 5 7 7 7)
        )
        (princ)
    )
    

    Depending on the desired appearance, you may also want to tweak the height of the text objects created by the function, which you can do by changing the value of DXF group 40 here:

    '(40 . 2) ;; <--- text height = 2