3

I need this piece of information for a filter that I'm creating.

So let's say I set my grid and snap to 1 for example and then I place the origin with UCS.

And then I draw a circle with center 5, 0.

Here is what I get:

(
    (-1 . <Entity name: 1f3dbb9d580>)
    (0 . "CIRCLE")
    (330 . <Entity name: 1f3dbba51f0>)
    (5 . "270")
    (100 . "AcDbEntity")
    (67 . 0)
    (410 . "Model")
    (8 . "0")
    (100 . "AcDbCircle")
    (10 2495.0 1180.0 0.0)
    (40 . 3.16228)
    (210 0.0 0.0 1.0)
)

Why at number 10 I have those numbers?

Shouldn't it be like (10 5.0 0.0 0.0)?

Lee Mac
  • 15,615
  • 6
  • 32
  • 80

2 Answers2

5

The coordinates defining the geometry of the majority of planar entities (such as arcs, circles, 2D polylines etc.) are defined relative to a coordinate system known as the Object Coordinate System (OCS).

The OCS shares its origin with the World Coordinate System (WCS), with its Z-axis corresponding to the normal vector (aka extrusion vector) associated with the entity (represented by DXF group 210), and its X & Y axes defined by the Arbitary Axis Algorithm applied to the normal vector.

The Arbitrary Axis Algorithm is implemented in the standard AutoLISP trans function, which facilitates easy transformation of points from one coordinate system to another.

In your particular example, the normal vector is (0.0 0.0 1.0), which is equal to the normal vector of the WCS plane, and so for this particular example, the OCS is equal to the WCS.

However, in general, to translate points from an arbitrary OCS to either the WCS or the active User Coordinate System (UCS), you would supply the trans function with either the OCS normal vector or the entity name of the entity in question.

For example, translating from OCS to the active UCS using the OCS normal vector:

(trans (cdr (assoc 10 <dxf-data>)) (cdr (assoc 210 <dxf-data>)) 1)

Or, translating from OCS to the active UCS using the entity name:

(trans (cdr (assoc 10 <dxf-data>)) (cdr (assoc -1 <dxf-data>)) 1)

Implemented in a sample program, this might be:

(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)
)

Addressing the issues you are encountering as described in your comments, you'll need to transform the coordinates from/to the OCS & UCS to achieve the desired result, for example:

(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)
)

The operation could also be condensed to a single expression, e.g.:

(setq old (assoc 10 enx)
      enx (subst (cons 10 (trans (list (car (trans (cdr old) ent 1)) 0) 1 ent)) old enx)
)
(entmod enx)

However, this is less readable.

Lee Mac
  • 15,615
  • 6
  • 32
  • 80
1

In this list coordinates are in WCS. So if You draw circle using command and active UCS is differend than WCS, everything is OK the result is as expected. To translate coordinates between coordinate systems You can use

(trans (assoc 10 YourList) 0 1 nil)

CAD Developer
  • 1,532
  • 2
  • 21
  • 27