(Answered) Transformation between AutoCAD OCS and WCS coordinate systems

1.4k Views Asked by At

This question originates in a problem I am having with transforming between two coordinate systems, that come from AutoCAD. This question is purely about the math of the problem, I just include the background of the problem so that others can use this question later.

AutoCAD changes the coordinate system for some of its objects into an Object Coordinate System (OCS), from a the usual World Coordinate System (WCS). I have exported a drawing to a DXF file and are trying to analyse the data of some of the objects in it. I need the WCS coordinates, but the objects are in OCS.

I have spent more than a day now researching this, and here is what I have - hope someone here can help me over the final hump.

This Link explains how to derive directional cosines from the OCS, that should be used to transform the coordinate I have into WCS.

Here is an example of what I have so far:

I have a test sample, WCS_point_xyz = [151.4117, 282.2828, 0.4514]. This is the coordinate in WCS of the object. This is the result I should arrive at.

When the data is exported, the point is now in OCS and look like this: OCS_point_xyz = [292.6949715389058, 58.91690693849874, 116.0505716044619] and have an extrusion vector = [0.8907951627859745, -0.0659739887935157, -0.4495902698677794]

This is what I want to transform into a WCS coordinate. Following the instructions in the link above I have done this: (python code, using numpy)

if abs(extrution_vector[0]) < 1/64 and abs(extrution_vector[1]) < 1/64:
    ax = np.cross(extrution_vector, (0,1,0))
else:
    ax = np.cross(extrution_vector, (0,0,1))

mx = sum([i**2 for i in ax])**.5   #calculate magnitude of ax
ax = ax * 1/mx   #scale ax to have magnitude 1

ay = np.cross(extrution_vector, ax)
az = extrution_vector

ax, ay, az should now be direction cosines of the OCS.

rotation_matrix = np.matrix([[ax[0], ax[1], ax[2]],[ay[0], ay[1], ay[2]],[az[0], az[1], az[2]]])

Building the rotation matrix from the direction cosines.

point_xyz = np.matrix([[point_xyz[0]], [point_xyz[1]], [point_xyz[2]]])

Building a 1*3 vector from the coordinates to be transformed

xyz = rotation_matrix * point_xyz

Now this is the process for going from a WCS to a OCS, which is the reverse of what I want. First I tested that this actually worked, so I ran the WCS coordinate through this as point_xyz, and got the OCS coordinate out correctly.

So in order to go the other way I change the last line to:

xyz = rotation_matrix.transpose() * point_xyz

and run the OCS coordinate through this as point_xyz. Which should give me the WCS coordinate. Instead I get this out:

[[ 55.34283021] [-297.59540959] [-104.80184537]]

Which is no where near the result I expected. I am sorry for the wall of text here. I hope one of you can spot where I am missing the point.