找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1094|回复: 1

[精彩文萃] 理解Trans函数和WCS/UCS/OCS三种坐标系

[复制链接]

已领礼包: 20个

财富等级: 恭喜发财

发表于 2018-6-17 12:51:52 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
本帖最后由 marting 于 2018-6-17 12:55 编辑

翻译一篇看到的不错的介绍TRANS, WCS/UCS/OCS的文章。有英文基础的还是读英文。


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.

OCS_1.PNG
OCS_2.PNG

尽管有很多关于使用Trans函数的帖子,但我仍然无法理解它。经过大量的研究,我想我想出了我需要知道的事情,我想我会分享我为了其他志趣相投的人的利益而学到的知识。我将从基础开始,确保每个人都在正确的理解。

我将讨论3个坐标系:WCS,UCS和OCS。这些代表世界坐标系统,用户坐标系统和对象坐标系统。 WCS是一个不变的固定系统,是所有其他系统的基础。

UCS可以由用户使用与WCS不同的起点和旋转来定义,但不能有不同的比例。 UCS用于重新定义由大多数AutoCAD命令输入或读取的坐标所指的位置。如果坐标系与对象的几何对齐,绘制对象要容易得多,而不用处理偏斜的复杂性。

AutoCAD内部使用OCS来减小文件大小。有人质疑文件大小现在这不再是一个问题,如果AutoCAD今天从头开始编写,它可能不会使用这种方式。这可以通过以下事实来暗示:后来新增的其他2D元素的椭圆实体在内部使用WCS而不是OCS,而较早的圆形实体使用OCS。或者较旧的文本实体使用OCS,而较新的多行文本使用WCS。

在任何情况下,我们都坚持使用OCS,并且必须了解它才能在许多2D元素类型上使用entmake或entmod。你必须知道的第一件事是对象的拉伸方向或拉伸向量的含义。这只是包含对象的平面的法线。如果使用UCS = WCS查看平面视图并绘制一个圆,则会在XY平面上创建该圆。 XY平面的法线是Z轴或'(0 0 1),所以这是圆的拉伸方向。如果要在相同半径的同一点上绘制一个圆,但在XZ平面中,则无法更改UCS,因为CIRCLE命令仅绘制当前UCS的XY平面。另一方面,可以通过指定“(0 1 0)”的拉伸方向(它是Y轴方向,即XZ平面的法线)来创建带entmake的圆。

在AutoCAD文档中似乎只提到过一个重要信息,即在所有元素中始终在WCS中指定拉伸方向,即使在OCS中指定了其他坐标的元素也是如此。这不是一个很好的选择,因为拉伸方向决定了OCS。它的定义方式是Autodesk称之为任意轴算法。如果你理解向量的“差积”是什么,这很容易理解。首先,OCS的起源始终等于WCS的起源。然后,如果拉伸向量不是指向非常接近Z轴的方向,则OCS的X轴就是与拉伸向量差积的WCS Z轴。当拉伸向量与Z轴过于接近时,由于数值的精度以及完全退化,所以不能使用它。所以,如果它接近,那么OCS X轴是与拉伸矢量交叉的WCS Y轴。如果拉伸矢量的X和Y坐标都小于1/64,则测试是否接近。拉伸矢量是单位化的,这意味着它的长度是1,这就是为什么你可以使用一个固定的数字,如1/64。根据AutoCAD文档,使用1/64的原因是因为其十进制表示在6位数字0.015625之后终止,并且它也等于2 ^ -6,这意味着二进制十进制数字是0.000001,它也有6位数字。就其他两个轴而言,OCS的Z坐标是拉伸方向(您可能已经猜到了),而Y方向与Z差积(通常的右手规则)。

现在我们知道了OCS是什么,我们可以考虑它与其他系统的关系。例如,我们可以看到,即使UCS的原点位于WCS原点,Z方向与OCS的拉伸方向相同,那么这两个系统可能仍然不是相同的,因为UCS可以有其X和Y轴围绕Z轴以任何角度旋转,但OCS不能。当您使用AutoCAD命令创建实体时,可以在UCS中指定其坐标。但是当实体添加到图形中时,这些坐标将转换为OCS。因此,如果您使用entget查看实体,您看到的坐标可能与您输入的坐标不同。为了在它们之间进行转换,你需要Trans函数。

Trans函数用于坐标系之间的转换。我不喜欢这个名字是因为Trans是翻译的缩写,因为Trans通常意味着坐标的移动,而Trans功能也处理旋转。

思考这个函数的方法是空间中的一个点不改变它的位置,但是当一个坐标系统改变时,引用这个固定点的坐标值会会变化。 Trans函数会告诉你不同坐标系统中相同点的不同的值。该函数的语法是(从[disp]到[disp])。这里'pt'是坐标系'from'中坐标的一个列表,'to'是你想要转换坐标的坐标系。 'disp'是否是'pt'是位移还是点的逻辑切换。区别在于:位移意味着两点,'pt'和'(0 0 0)。如果你只是改变'pt',那么,正如我刚刚提到的那样,这两组坐标所指向的点将是相同的。但是,如果新坐标系的原点与旧坐标系的原点不同,则从原点到点的方向将发生变化(除非原点恰好在点的确切方向上移动)。 'disp'开关将对此进行更正,并为您提供与原点相同的方向和距离原点的相同点,而不是原始点的基本平移。一种记住如何使用它的方法是将'disp'开关打开以转换一个向量(它是从原点到重要点的方向),并将'disp'关闭以转换点位置很重要)。如果两个系统的原点相同,那么'disp'不起作用。特别是,在WCS和OCS之间转换总是如此。尽管如此,我总是将“disp”开关包括在内,无论是否有必要,都只是形式上的问题。

有3种方式可以指定“源”'和'目标'的坐标系。第一个是最简单的,使用整数代码。我唯一关心的两个代码是WCS为0,UCS为1。如果您编写一个程序,请求用户坐标,它们将在UCS中返回。如果您希望使用这些坐标来创建带有entmake的实体,则必须将它们转换为实体所需的坐标。假设实体需要WCS,就像使用mtext一样。然后你会使用类似(trans INPUT 1 0)。这很容易忽略,因为如果UCS = WCS,那么你的程序将在没有这个的情况下工作。但是如果你想要一个多功能的程序,你必须记住UCS可以改变。相反,如果您从使用WCS的实体获得坐标并且想要将其显示给用户,或者在命令中使用它,则必须以另一种方式进行转换,例如(trans DATA 0 1)。

另一个重要的例子是找到拉伸方向。在我之前给出的XY平面的拉伸方向的例子中,我假定了UCS = WCS。但是如果你使用其他的UCS并且你想在UCS的XY平面上创建一个实体呢?换句话说,我们希望拉伸方向在UCS中是'(0 0 1)。但是拉伸方向必须在WCS中指定。由于拉伸方向是一个矢量,所以解决方案应该从讨论中清楚到这一点 - 我们需要的拉伸方向是(trans'(0 0 1)1 0 T)。

处理OCS时使用另外两种指定'from'和'to'的方法。 OCS的困难之处在于,在任何给定的时间,不仅有一个OCS,就像WCS和UCS一样,但对于图纸中的每个实体可以是不同的。因此,指定坐标系的第二种方法是传递标准实体名称,例如(car(entsel))返回的内容。这指定了OCS,因为实体数据包含其拉伸方向,并且拉伸方向定义了OCS。这表明了指定坐标系统的第三种方式 - 直接给出拉伸向量。这第三种方式实际上是使用entmake的缺失环节。在需要OCS中的坐标的实体中使用entmake的问题是在创建实体之前没有OCS。这种Catch-22情况可以通过使用拉伸载体来解决。记住一个拉伸矢量是在WCS中,它已经存在了,你可以计算它,因为你知道你想要哪个平面位于你的元素中。然后你可以在Trans函数中使用它来计算OCS坐标。然后你可以在entmake中使用OCS坐标。例如,要在我之前提到的WCS的XZ平面上创建该圆,可以使用(trans CENTER 1'(0 1 0))获得中心坐标,其中CENTER是UCS中的中心坐标列表, (0 1 0)是WCS中的拉伸矢量。由于半径是距离,坐标系不会改变比例尺,因此半径与坐标系无关,不需要平移。您使用entmake所需的最终DXF代码是拉伸方向,您已经知道它是'(0 1 0)。结果在WCS计划视图中看起来像一条水平线,但不用担心,它是一个圆圈!

与UCS XY平面垂直的拉伸矢量(即(trans'(0 0 1)1 0 T))的前一个例子特别有用,因为它表示拉伸矢量,它定义了在当前设计平面上创建的所有实体的OCS ,因此如果要将任何其他坐标转换为平面元素的OCS,则它们将是'to'坐标系。例如,要在当前设计平面上绘制另一个圆,您可以使用(trans CENTER 1(trans'(0 0 1)1 0 T))作为中心坐标。在要使用的UCS的XZ平面中绘制一个圆(trans CENTER 1(trans'(0 1 0)1 0 T))。

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 6056个

财富等级: 富甲天下

发表于 2018-6-17 18:24:12 | 显示全部楼层
沙发。谢谢分享。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-3-29 03:09 , Processed in 0.364418 second(s), 33 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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