Author Topic: Coordinate Systems And The Trans Function  (Read 11111 times)

0 Members and 1 Guest are viewing this topic.

Lerner

  • Newt
  • Posts: 33
Coordinate Systems And The Trans Function
« on: January 23, 2010, 01:56:25 AM »
Despite a lot of posts regarding the use of the Trans function, I still could not understand it. After a lot of research I think I figured out what I need to know and I thought I would share what I have learned for the benefit of other like-minded people. I will start with the basics to make sure everyone is on the right page.

There are 3 coordinate systems I will discuss: WCS, UCS, and OCS. Those stand for the World Coordinate System, User Coordinate System, and Object Coordinate System. The WCS is an unchanging fixed system that underlies all others.

A UCS can be user defined with a different origin and rotation from the WCS, but not a different scale. A UCS is used to redefine the locations referred to by the coordinates which are entered or read from most AutoCAD commands. It is much easier to draw an object if the coordinate system is aligned with the object's geometry, instead of dealing with the complications of something that is skewed and shifted.

An OCS is used internally by AutoCAD to reduce file size. One suspects that this isn't as much of an issue anymore and if AutoCAD were written from scratch today it probably wouldn't employ this complication. This is hinted to by the fact that the ellipse entity, which was added later then other 2D elements, uses WCS internally rather than OCS, while the earlier circle entity uses OCS. Or the fact that the older text entity uses OCS while the newer mtext uses WCS.

In any case, we are stuck with OCS and must understand it in order to use entmake or entmod on many 2D element types. The first thing you must know is what is meant by the extrusion direction or extrusion vector of an object. This is simply the normal to the plane which contains the object. If you are looking at a plan view with UCS=WCS and draw a circle, the circle is created on the XY plane. The normal to the XY plane is the Z axis, or '(0 0 1), so this is the extrusion direction for the circle. If you want to draw a circle at the same point with the same radius but in the XZ plane, well you couldn't do it without changing UCS because the CIRCLE command only draws on the XY plane of the current UCS. On the other hand, you could create a circle with entmake by specifying an extrusion direction of '(0 1 0), which is the Y axis direction, which is the normal to the XZ plane.

One important piece of information that only seems to be mentioned once in the AutoCAD documentation is that the extrusion direction is always specified in WCS in all elements, even ones whose other coordinates are specified in OCS. This isn't so much a choice as it has to be the case because the extrusion direction DEFINES the OCS. The way it defines it is by what Autodesk has dubbed the Arbitrary Axis Algorithm. If you know what cross product is this is quite easy to understand. First of all, the origin of the OCS always equals the origin of the WCS. Then, if the extrusion vector is not pointing in a direction which is very close to the Z axis, the X axis of the OCS is just the WCS Z axis crossed with the extrusion vector. You can't use this when the extrusion vector is too close to the Z axis because of numerical accuracy and because it degenerates completely if they are equal. So, if it is close, then the OCS X axis is the WCS Y axis crossed with the extrusion vector. The test for closeness is if both the X and Y coordinates of the extrusion vector are less then 1/64. The extrusion vector is normalized, which means its length is 1, which is why you can use a fixed number like 1/64. According the AutoCAD documentation, the reason 1/64 is used is because its decimal representation terminates after 6 digits, 0.015625, and it also equals 2^-6, which means in binary decimal it is 0.000001, which also has 6 digits. As far as the other two axes, the Z coordinate of the OCS is the extrusion direction (as you might have guessed) and the Y direction is Z crossed with X (the usual right hand rule).

Now that we know what the OCS is we can think about its relationship to the other systems. For instance, we can see that even if a UCS has its origin at the WCS origin and Z direction the same as the extrusion direction of an OCS, then the two systems may still not be the same because the UCS can have its X and Y axes rotated at any angle around the Z axis, but the OCS cannot. When you create an entity with an AutoCAD command you specify its coordinates in UCS. But when the entity is added to the drawing these coordinates get converted to OCS. Therefore, if you look at the entity with entget, the coordinates you see might not be the same as the ones you entered. In order to convert between them you need the Trans function.

The Trans function is used to transform between coordinate systems. I don't like to think of trans as short for translate because translation usually means a shifting of coordinates, whereas the trans function also handles rotation. The way to think about this function is that a point in space does not change its location, but when a coordinate system changes, the numbers which refer to this fixed point do. The Trans function will tell you the new numbers for the same point in different coordinate systems. The syntax of the function is (trans pt from to [disp]). Here 'pt' is a list of the coordinates of a point in the coordinate system 'from' and 'to' is the coordinate system you want to convert the coordinates to. 'disp' is a logical switch for whether 'pt' is a displacement or a point. The difference is this: a displacement implies two points, 'pt' and '(0 0 0). If you just transform 'pt', then, as I just mentioned, the point referred to by the two sets of coordinates will be the same. But if the origin of the new coordinate system is different than the old one, the direction from the origin to the point will have changed (unless the origin just happens to move in the exact direction of the point). The 'disp' switch will correct this and give you a point in the same direction and at the same distance from the origin as before, instead of the basic translation of the original point. A way to remember how to use it is to turn the 'disp' switch on to transform a vector (where it is the direction from the origin to the point that matters), and leave 'disp' off to convert a point (where only the location matters). If the origin of both systems is the same then 'disp' has no effect. In particular, this is always the case for transforming between WCS and OCS. Although, I always include the 'disp' switch for any displacement whether it is necessary or not, just as a matter of form.

There are 3 ways to specify the coordinate systems 'from' and 'to'. The first is the easiest, using an integer code. The only two codes I am concerned with here are 0 for WCS and 1 for UCS. If you write a program that asks for coordinates from a user they are returned in UCS. If you then want to use these coordinates to create an entity with entmake you will have to transform them into the coordinates required by the entity. Let's say the entity requires WCS, like with mtext. Then you would use something like (trans INPUT 1 0). This is easy to overlook because if UCS=WCS then your program will work without this. But if you want a versatile program you have to remember that the UCS can change. Conversely, if you get coordinates from an entity which uses WCS with entget and you want to display this to the user, or use it in a command, you have to convert the other way, such as (trans DATA 0 1).

Another important example is in finding extrusion directions. In the example I gave previously of the extrusion direction for the XY plane, I assumed UCS=WCS. But what if you are using some other UCS and you want to create an entity on the XY plane of that UCS? In other words, we want the extrusion direction to be '(0 0 1) in the UCS. But extrusion directions must be specified in WCS. Since the extrusion direction is a vector, the solution should be clear from the discussion up to this point - the extrusion direction we need is (trans '(0 0 1) 1 0 T).

The other two methods of specifying 'from' and 'to' are used when dealing with OCS. The difficultly with OCS is that there is not just one OCS at any given time, as with WCS and UCS, but can be a different one for each entity in a drawing. So the second way to specify a coordinate system is by passing a standard entity name, such as what is returned by (car (entsel)). This specifies an OCS because the entity data contains its extrusion direction, and the extrusion direction defines the OCS. And this suggests the third way of specifying coordinate systems - by giving the extrusion vector directly. This third way is really the missing link in using entmake. The problem with using entmake for entities which require coordinates in OCS is that there is no OCS until the entity is created. This Catch-22 situation is resolved by using extrusion vectors. Remember an extrusion vector is in WCS, which does already exist, and you will be able to calculate it because you know what plane you want your element to lie in. You can then use this in the Trans function to compute OCS coordinates. Then you can use the OCS coordinates in entmake. For instance, to create that circle on the XZ plane of the WCS which I mentioned before, you would obtain the center coordinates using (trans CENTER 1 '(0 1 0)), where CENTER is the list of center coordinates in UCS and '(0 1 0) is the extrusion vector in WCS. Because radius is a distance and coordinate systems do not change scale, radius is independent of coordinate system and needs no translation. The final DXF code you need for using entmake is the extrusion direction, which you already know is '(0 1 0). The result will look like a horizontal line in WCS plan view, but don't worry, it's a circle!

The previous example of an extrusion vector normal to the UCS XY plane, namely (trans '(0 0 1) 1 0 T), is particularly useful because it represents the extrusion vector which defines the OCS for all entities created on the current design plane, and hence will be the 'to' coordinate system if you want to transform any other coordinates to an OCS for plane elements. For example, to draw another circle, this one on the current design plane, you would use (trans CENTER 1 (trans '(0 0 1) 1 0 T)) for the center coordinates. To draw a circle in the XZ plane of the UCS you would use (trans CENTER 1 (trans '(0 1 0) 1 0 T)). Got the hang of it yet?

Have fun coders.
« Last Edit: May 28, 2016, 03:29:58 AM by Lerner »

gile

  • Water Moccasin
  • Posts: 2406
  • Marseille, France
Re: Coordinate Systems And The Trans Function
« Reply #1 on: January 23, 2010, 04:36:32 AM »
Hi,

Very nice explaination.
In better English than this I tried here.

I don't completely agree with this:
Quote
An OCS is used internally by AutoCAD to reduce file size. One suspects that this isn't as much of an issue anymore and if AutoCAD were written from scratch today it probably wouldn't employ this complication.

Using OCS (called ECS in .NET APIs) also make programming much more easy with 2d entities i.e. dealing with arc start or end points/angles, dealing with polyline bulges.
OCSs aren't complications, if they weren't provided, many programs should have to build them (or a sort of) to be able to work in the entiy plane.

Quote
This is hinted to by the fact that the ellipse entity, which was added later then other 2D elements, uses WCS internally rather than OCS.
I've done some stuff with ellipses. Even center and major axis vector (DXF 10 and 11) are given in WCS coordinates, if you have to do some calculations with the ellipse parmeters (DXF 41 42) i.e. calculating start or end points of an elliptical arc, you will need to build a 'virtual' coordinate system wich origin is the ellipse center, X axis given by the major axis vector and Zaxis given by the extrusion direction.
Speaking English as a French Frog

Lerner

  • Newt
  • Posts: 33
Re: Coordinate Systems And The Trans Function
« Reply #2 on: January 23, 2010, 05:42:04 AM »
Yes, gile, I have read your excellent post and learned a lot from it. I made extensive use of it when I was doing a lot of programming last year, but when I finally got back to programming again recently I realized I might not have understood it as well as I thought. I was going to mention your posting, and then thought I would have to go through all the other sources I had looked at too, and it just seemed like too much work to go back and catalog everything. I'm sorry I didn't include yours though because it was the most useful.

Oh, and the reason I said OCS is used to reduce file size is because of AutoCAD's own documentation which says "To save space in the drawing database (and in the DXF file), the points associated with each entity are expressed in terms of the entity's own object coordinate system (OCS)." I guess that doesn't mean it can't also facilitate programming though.
« Last Edit: January 23, 2010, 11:30:31 AM by Lerner »

wizman

  • Bull Frog
  • Posts: 287
Re: Coordinate Systems And The Trans Function
« Reply #3 on: January 23, 2010, 05:48:54 AM »
Thank you guys for your explanations.  After reading Gile's Lecture for numerous times, Just want to share my Learning Excercise for Coordinates(Spherical) with TRANS and OCS.  


Code: [Select]
;;
;;  Command Name - Wizphere
;;      Sample routine utilising Spherical Coordinates,
;;      Trans function and OCS
;;      By WizMan_22Jan2010
;;
(defun c:Wizphere (/ pt pt2 rad regob ron spc x z)
    ;;
    ;;
    ;;  Function Name - wiz-polar3d
    ;;      Polar function accepting angle on XY Plane
    ;;      and angle from XY Plane/
    ;;
    ;;  Arguments:
    ;;      pt - point in WCS
    ;;      <X - Angle on XY in radians with respect to WCS
    ;;      <Z - Angle from XY Plane with respect to WCS
    ;;     dis - distance relative to pt
    ;;
    ;;  Return Value:
    ;;     A point relative to pt with rotation angles with
    ;;     respect to XY and from XY Plane
    ;;  
    ;;

    (defun wiz-polar3d (pt <X <Z dis)
        (defun dtr (var)
            (* PI (/ var 180.0))
        )
        (mapcar '+
                pt
                (trans
                    (polar '(0 0 0) (dtr <z) dis)
                    (polar '(0 0 0) (dtr (- <x 90)) 1.)
                    0
                )
        )
    )
    ;;
    ;;
    (setq x   0
          z   0
          pt  '(0 0 0)
          rad 1.
    )
    (or *adoc*
        (setq *adoc* (vla-get-ActiveDocument (vlax-get-acad-object)))
    )
    (setq spc (vla-get-ModelSpace *adoc*))
    ;;
    ;;
    (while (< x 180)
        (while (< z 360)
            (setq pt2 (wiz-polar3d pt x z rad))
            (setq ron
                     (entmakex (list (cons 0 "CIRCLE")
                                     (cons 10 '(0 0 1))
                                     (cons 40 0.005) ;***
                                     (cons 210 pt2)
                               )
                     )


            )
            (setq regob (vl-catch-all-apply
                            'vlax-invoke
                            (list spc 'addRegion (list (vlax-ename->vla-object ron)))
                        )
            )
            (vla-put-color
                (vla-addextrudedsolid spc (car regob) 0.025 0.)
                1
            )
            (vla-delete (vlax-ename->vla-object ron))
            (vla-delete (car regob))

            (setq z (+ 5 z))
        )
        (setq z 0
              x (+ 5 x)
        )
    )
    (vla-put-color
        (vla-AddSphere spc (vlax-3d-point '(0 0 0)) 1.0)
        3
    )
    (princ)
)
(vl-load-com)
;;
;;
(prompt
    "\n>>>...Wizphere.lsp is now loaded. Type 'Wizphere'  to run ...<<<"
) ;_ prompt
(princ)
;;
;;
;;WIZ_22JAN10








« Last Edit: January 23, 2010, 05:56:25 AM by wizman »

CAB

  • Global Moderator
  • Seagull
  • Posts: 10400
Re: Coordinate Systems And The Trans Function
« Reply #4 on: January 23, 2010, 09:04:29 AM »
Thanks to all who continue to shed light on the subject. :-)
I've reached the age where the happy hour is a nap. ()
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.