Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Block inaccuracy

8 REPLIES 8
Reply
Message 1 of 9
apsaps
504 Views, 8 Replies

Block inaccuracy

Hi! I'm total beginner in AutoLISP, I work mostly with GIS software and data, but now I've got a lot of DWG files which are containing around 100000 entities with various entity types and several layers. Everything is in a custom local coordinate system, and I have to transform it into an other coordinate system (I've only got the transformation equations). I use the following code to do this:

 

(defun c:customtransform ( / ss i entitylist obj new j x y )
  (if (setq ss (ssget "_:L"))
    (repeat (setq i (sslength ss))
      (setq entitylist (entget (ssname ss (setq i (1- i)))))
      (setq obj (ssname ss i))
      (setq new nil)
      (repeat (setq j (length entitylist))
        (cond 
          ( (= 10 (car (nth (setq j (1- j)) entitylist)))
            (setq x (cadr (nth j entitylist))
                  y (caddr (nth j entitylist))
            )
            (setq y (+ (+ (+ 0 332134.109) (* 0.40008331 x)) (* 0.59595102 y)))
            (setq x (+ (+ (+ 0 1087.012) (* 0.59595102 x)) (* -0.40008331 y)))
            (setq new (cons (list 10 x y) new))
          )
          ( (= 11 (car (nth j entitylist)))
            (setq x (cadr (nth j entitylist))
                  y (caddr (nth j entitylist))
            )
            (setq y (+ (+ (+ 0 332134.109) (* 0.40008331 x)) (* 0.59595102 y)))
            (setq x (+ (+ (+ 0 1087.012) (* 0.59595102 x)) (* -0.40008331 y)))
            (setq new (cons (list 11 x y) new))
          )
          ( (= 12 (car (nth j entitylist)))
            (setq x (cadr (nth j entitylist))
                  y (caddr (nth j entitylist))
            )
            (setq y (+ (+ (+ 0 332134.109) (* 0.40008331 x)) (* 0.59595102 y)))
            (setq x (+ (+ (+ 0 1087.012) (* 0.59595102 x)) (* -0.40008331 y)))
            (setq new (cons (list 12 x y) new))
          )
          ( (= 13 (car (nth j entitylist)))
            (setq x (cadr (nth j entitylist))
                  y (caddr (nth j entitylist))
            )
            (setq y (+ (+ (+ 0 332134.109) (* 0.40008331 x)) (* 0.59595102 y)))
            (setq x (+ (+ (+ 0 1087.012) (* 0.59595102 x)) (* -0.40008331 y)))
            (setq new (cons (list 13 x y) new))
          )
          ( (= 14 (car (nth j entitylist)))
            (setq x (cadr (nth j entitylist))
                  y (caddr (nth j entitylist))
            )
            (setq y (+ (+ (+ 0 332134.109) (* 0.40008331 x)) (* 0.59595102 y)))
            (setq x (+ (+ (+ 0 1087.012) (* 0.59595102 x)) (* -0.40008331 y)))
            (setq new (cons (list 14 x y) new))
          )
          ( (= 15 (car (nth j entitylist)))
            (setq x (cadr (nth j entitylist))
                  y (caddr (nth j entitylist))
            )
            (setq y (+ (+ (+ 0 332134.109) (* 0.40008331 x)) (* 0.59595102 y)))
            (setq x (+ (+ (+ 0 1087.012) (* 0.59595102 x)) (* -0.40008331 y)))
            (setq new (cons (list 15 x y) new))
          )
          ( (= 16 (car (nth j entitylist)))
            (setq x (cadr (nth j entitylist))
                  y (caddr (nth j entitylist))
            )
            (setq y (+ (+ (+ 0 332134.109) (* 0.40008331 x)) (* 0.59595102 y)))
            (setq x (+ (+ (+ 0 1087.012) (* 0.59595102 x)) (* -0.40008331 y)))
            (setq new (cons (list 16 x y) new))
          )
          ( t
            (setq new (cons (nth j entitylist) new))
          )
        )
      )
      (entdel obj)
      (entmake new)
    )
  )
  (princ)
)

 

It works fine for most of the objects, but unfortunately this code cannot handle some entity types like ellipses or regions. Therefore I was suggested to try blocks. I extended the code with Lee Mac's "objects to block" code, so it converts the entities into a single block and then transform the block into the new coordinate system. This method moves every entity, but during data verification I found that this method results inaccurate coordinates.

 

I checked with manual calculations that the transform-only code above is deadly accurate. But when I convert the objects into a single block (either with Lee Mac's method or with hand in AutoCAD) and then run the transformation routine on the block, inaccuracy occurs. The degree of inaccuracy seems to be almost constant and it is between 10 and 100 cm (4-39"), depends on the basepoint of the block selected before the transformation. I observed that using (0,0) as the block's base point gives the biggest error, while using EXTMIN as the base point results lower error. I've got the smallest difference when I use the center of the extent (EXTMAX + EXTMIN / 2) as the base point (it's around 4-7 cm).

 

Why does this inaccuracy occur? How can I get rid of it?

8 REPLIES 8
Message 2 of 9
hmsilva
in reply to: apsaps

Just a thought.

 

If your goal is just change the coordinate system, can't a move and a rotate be sufficient?

Maybe something like this:

 

(defun c:demo (/ new_pt p1 p1a p2 p2a ss)

  (defun new_pt (pt / x y)
    (setq x  (car pt)
          y  (cadr pt)
          x  (+ (+ (+ 0 1087.012) (* 0.59595102 x)) (* -0.40008331 y))
          y  (+ (+ (+ 0 332134.109) (* 0.40008331 x)) (* 0.59595102 y))
          pt (list x y)
    )
  )

  (setq p1  '(0.0 0.0)
        p2  '(1.0 1.0)
        p1a (new_pt p1)
        p2a (new_pt p2)
  )
  (if (setq ss (ssget "_X"))
    (command "_.layer" "_T" "*" "_ON" "*" "U" "*" ""
             "_.align" ss "" "_NONE" p1 "_NONE" p1a "_NONE" p2 "_NONE" p2a "" "_N"
             "_.layerp"
            )
  )
  (princ)
)

 

Hope that helps

Henrique

EESignature

Message 3 of 9
dgorsman
in reply to: hmsilva

Depending on needs (I'm not a GIS guy), if everything stays in the same relative geometric position it may be even simpler to just modify the UCS.

----------------------------------
If you are going to fly by the seat of your pants, expect friction burns.
"I don't know" is the beginning of knowledge, not the end.


Message 4 of 9
hmsilva
in reply to: dgorsman


@dgorsman wrote:

Depending on needs (I'm not a GIS guy), if everything stays in the same relative geometric position it may be even simpler to just modify the UCS.


I'm not a GIS guy also, but when I need to change a dwg from one datum to another datum, I need to move and rotate all objects, because our topographic dwg's must be in WCS.

 

Henrique

EESignature

Message 5 of 9
dgorsman
in reply to: hmsilva

"... must be in WCS."  Not to sound like a little kid, but... why?

----------------------------------
If you are going to fly by the seat of your pants, expect friction burns.
"I don't know" is the beginning of knowledge, not the end.


Message 6 of 9
hmsilva
in reply to: dgorsman


@dgorsman wrote:

"... must be in WCS."  Not to sound like a little kid, but... why?


Company policy...

And we need to supply to state agencies a .dxf in WCS...

 

Henrique

EESignature

Message 7 of 9
hmsilva
in reply to: apsaps

Please  disregard the code I have posted.

 

Rereading the code I realized that applying your transformation equation, the object ratio will be changed, and will not be just move and rotate all objects to a new coordinate system.

 

Henrique

EESignature

Message 8 of 9
apsaps
in reply to: hmsilva

Your code is so simple and clear! It works fine, just have to enable with 'Yes' the scaling of the objects based on the alignment points, and it gives exactly what I need.

 

Thank you very much!

Message 9 of 9
hmsilva
in reply to: apsaps


@apsaps wrote:

Your code is so simple and clear! It works fine, just have to enable with 'Yes' the scaling of the objects based on the alignment points, and it gives exactly what I need.

 

Thank you very much!


You're welcome, apsaps.

I'm glad you found a solution.

 

Henrique

EESignature

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

”Boost