473,401 Members | 2,139 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,401 software developers and data experts.

Translate in 3D

bvdet
2,851 Expert Mod 2GB
I have done some more work on a simple class I wrote to calculate a global coordinate in 3D given a local coordinate:
Expand|Select|Wrap|Line Numbers
  1. ##  Basis3D.py Version 1.02 (module macrolib.Basis3D)
  2. ##  Copyright (c) 2006 Bruce Vaughan, BV Detailing & Design, Inc.
  3. ##  All rights reserved.
  4. ##  NOT FOR SALE. The software is provided "as is" without any warranty.
  5. ############################################################################
  6. """
  7.     Class BasisTransToGlobal
  8.     Given 3 counter-clockwise non-collinear points, define an orthonormal basis in 3D space (the local basis).
  9.     Calculate the global point, a vector in the standard basis set, given a displacement vector in the local basis.
  10.     The object type of the displacement vector 'vR' is 'point'.
  11.     An instance translate method can be called:
  12.         ref_pt + instance.translate(x, y, z) --> global coordinate point object
  13.     Method 'translate' example usage:
  14.         pt = global point origin of translation to be calculated (example: mem.left.location)
  15.         a = class instance
  16.         x, y, and z are offsets from pt in the local basis
  17.         pt + a.translate(x, y, z)
  18. """
  19.  
  20. from macrolib.ExceptWarn import formatExceptionInfo
  21. from macrolib.P3D import Plane3D
  22. from param import Warning
  23. from point import Point
  24.  
  25. def chk_type(p_list):
  26.     for p in p_list:
  27.         if not isinstance(p, type(Point(0,0,0))):
  28.             return False
  29.     return True
  30.  
  31. class BasisTransToGlobal(object):
  32.     def __init__(self, vN, vA, vB, vR=Point(0,0,0)):
  33.         self.vN = vN
  34.         if chk_type([vN, vA, vB, vR]):
  35.  
  36.             # local basis aligned with instance 'a', define the plane
  37.             a = Plane3D(vN, vA, vB)
  38.  
  39.             if a.N_len > 0.0:
  40.  
  41.                 # Unit vector normal to defined plane, local basis 'Z'
  42.                 self.N = a.N_uv
  43.  
  44.                 # Unit vector between vN and vA, local basis 'X'
  45.                 self.A = a.d0
  46.  
  47.                 # Unit cross product vector, local basis 'Y'
  48.                 self.B = a.cross_product(self.N, self.A)
  49.  
  50.                 # global coordinate vector
  51.                 self.R = self.translate(vR.x, vR.y, vR.z) + vN
  52.  
  53.             else:
  54.                 Warning("The points are collinear ***INVALID***")
  55.                 self.R = None
  56.         else:
  57.             Warning("Argument type must be 'point'")
  58.             self.R = None
  59.  
  60.     def translate(self, X, Y, Z):
  61.         A, B, N = self.A, self.B, self.N
  62.         M = (X*X + Y*Y + Z*Z)**0.5
  63.         # vR normalized
  64.         if M > 0:
  65.             X1, Y1, Z1 = X/M, Y/M, Z/M
  66.         else:
  67.             X1, Y1, Z1 = 0.0, 0.0, 0.0
  68.  
  69.         D = self.determinant3(A.x, A.y, A.z, N.x, N.y, N.z, B.x, B.y, B.z)
  70.         Dx = self.determinant3(X1, A.y, A.z, Z1, N.y, N.z, Y1, B.y, B.z)
  71.         Dy = self.determinant3(A.x, X1, A.z, N.x, Z1, N.z, B.x, Y1, B.z)
  72.         Dz = self.determinant3(A.x, A.y, X1, N.x, N.y, Z1, B.x, B.y, Y1)
  73.  
  74.         # resultant unit vector R1
  75.         R1 = Point(Dx/D, Dy/D, Dz/D)
  76.  
  77.         # global coordinate vector with respect to local basis origin
  78.         return Point(R1.x*M, R1.y*M, R1.z*M)
  79.  
  80.     def determinant3(self, a,b,c,m,n,k,u,v,w):
  81.         return a*n*w + b*k*u + m*v*c - c*n*u - b*m*w - a*k*v
  82.  
  83.     def version(self):
  84.         "Basis3D.BasisTransToGlobal Version 1.02"
Here' s the test script:
Expand|Select|Wrap|Line Numbers
  1. from macrolib.Basis3D import BasisTransToGlobal
  2. def test_BasisTransToGlobal():
  3.     from macrolib.ExceptWarn import formatExceptionInfo
  4.     from macrolib.PrintPtList import formatPtList
  5.     from macrolib.PrintDict import formatDict
  6.     from param import Dialog, dim_print, Warning, ResponseNotOK, Units
  7.     from point import Point, PointLocate
  8.     import os
  9.     Units("feet")
  10.     try:
  11.         dlg1 = Dialog("Translate to Global in an Orthogonal Basis")
  12.         dlg1.group_title("Orthonormal Basis and Resultant Unit Vector")
  13.         image_path = os.path.join(os.getcwd(), "macro", "Images")
  14.         image_name = os.path.join(image_path, "Basis3D_XYZ.gif")
  15.         dlg1.image(image_name)
  16.         dlg1.group_title("Translation Vector")
  17.         dlg1.entry('distX', dim_print(60.0), "Enter translate 'X' direction")
  18.         dlg1.entry('distY', dim_print(30.0), "Enter translate 'Y' direction")
  19.         dlg1.entry('distZ', dim_print(0.0), "Enter translate 'Z' direction")
  20.         try:
  21.             dlg1.done()
  22.         except ResponseNotOK:
  23.             raise StandardError, "User Cancelled"
  24.         pt1 = PointLocate("Pick point 1 (Basis 0,0,0)")
  25.         pt2 = PointLocate("Pick point 2 (Basis 'X')")
  26.         pt3 = PointLocate("Pick point 3 to define plane")
  27.         pt4 = Point(dlg1.distX, dlg1.distY, dlg1.distZ)
  28.     except:
  29.         Warning(formatExceptionInfo())
  30.     else:
  31.         if pt1 and pt2 and pt3 and pt4:
  32.             a = BasisTransToGlobal(pt1, pt2, pt3, pt4)
  33.             if a.R:
  34.                 print formatPtList("Local Basis Origin:", [pt1, ])
  35.                 print formatPtList("Local Basis Translate Vector:", [pt4, ])
  36.                 print formatPtList("Resultant Global Point:", [a.R, ])
  37.                 print formatDict("BasisTransToGlobal Instance Dictionary:", a.__dict__)
  38.                 # print formatDict("Local Dictionary:", locals())
  39.                 print formatPtList("Resultant Global Points Calculated With Method 'translate':",
  40.                                    [pt1+a.translate(12, 12, 0), pt1+a.translate(13, 13, 0), \
  41.                                     pt1+a.translate(14, 14, -3)])
  42.  
  43. if __name__ == '__main__':
  44.     test_BasisTransToGlobal()
Test script output:
Expand|Select|Wrap|Line Numbers
  1. Local Basis Origin:
  2. X attribute         Y attribute         Z attribute         
  3. ==================================================
  4. 2-7 3/8            -2-3 1/2            1-9 15/16           
  5.  
  6. Local Basis Translate Vector:
  7. X attribute         Y attribute         Z attribute         
  8. ==================================================
  9. 5-0                 2-6                 10                  
  10.  
  11. Resultant Global Points:
  12. X attribute         Y attribute         Z attribute         
  13. ==================================================
  14. -1-3 5/8            -7-2 3/8            -7 7/8              
  15.  
  16. BasisTransToGlobal Instance Dictionary:
  17. Key = A     Value = 0, -0.623718, -0.78165
  18. Key = B     Value = 0.746515, -0.520085, 0.415003
  19. Key = N     Value = -0.665369, -0.583513, 0.465615
  20. Key = R     Value = -15.620537, -86.364783, -7.845922
  21. Key = vN    Value = -31.362292, -27.504023, 21.946829
  22.  
  23. Resultant Global Points Calculated With Method 'translate':
  24. X attribute         Y attribute         Z attribute         
  25. ==================================================
  26. -1-10 3/8           -3-5 1/4            1-5 9/16            
  27. -1-9 11/16          -3-6 3/8            1-5 3/16            
  28. -1-6 15/16          -3-5 3/4            1-3 7/16
Any comments or suggestions for improvement will be appreciated. I am planning to use this class in some of my production scripts. Thank you.

BV
Dec 19 '06 #1
9 3081
bartonc
6,596 Expert 4TB
Looks like good encapsulation of the problem space to me. Admittedly, vector math is not my strong suit, but I see a clean style here.
Dec 20 '06 #2
bvdet
2,851 Expert Mod 2GB
Looks like good encapsulation of the problem space to me. Admittedly, vector math is not my strong suit, but I see a clean style here.
Thanks Barton. I have been working on this on and off for over two months and been unable to find anything else to improve on my own. Is there a reason to derive BasisTransToGlobal from Plane3D instead of creating a Plane3D instance?

BV
Dec 20 '06 #3
bartonc
6,596 Expert 4TB
Thanks Barton. I have been working on this on and off for over two months and been unable to find anything else to improve on my own. Is there a reason to derive BasisTransToGlobal from Plane3D instead of creating a Plane3D instance?

BV
Sinse your instance (a) doesn't seem to live outside of __init__, I don't see much advantage. But let's see what it would look like and discuss it.

Expand|Select|Wrap|Line Numbers
  1. class BasisTransToGlobal(Plane3D):
  2.     def __init__(self, vN, vA, vB, vR=Point(0,0,0)):
  3.         Plane3D.__init__(self, vN, vA, vB)
  4.         self.vN = vN
  5.         if chk_type([vN, vA, vB, vR]):
  6.  
  7.             # local basis aligned with instance 'a', define the plane
  8.             # now all references to a. become self.
If Plane3D exposes vN then either self.vN collides with it or is not needed. I'd really need to know more about a Plane3D object. You probably got it right in your implementation, though. Something to think about, anyway.
Dec 20 '06 #4
bartonc
6,596 Expert 4TB
Sinse your instance (a) doesn't seem to live outside of __init__, I don't see much advantage. But let's see what it would look like and discuss it.

Expand|Select|Wrap|Line Numbers
  1. class BasisTransToGlobal(Plane3D):
  2.     def __init__(self, vN, vA, vB, vR=Point(0,0,0)):
  3.         Plane3D.__init__(self, vN, vA, vB)
  4.         self.vN = vN
  5.         if chk_type([vN, vA, vB, vR]):
  6.  
  7.             # local basis aligned with instance 'a', define the plane
  8.             # now all references to a. become self.
If Plane3D exposes vN then either self.vN collides with it or is not needed. I'd really need to know more about a Plane3D object. You probably got it right in your implementation, though. Something to think about, anyway.
Oh! I see why not to do this! instantiation takes place if chk_typ passes. I'm guessing that Plane3D doesn't do that for you.
Dec 20 '06 #5
bartonc
6,596 Expert 4TB
Oh! I see why not to do this! instantiation takes place if chk_typ passes. I'm guessing that Plane3D doesn't do that for you.
Of course, you could do this:

Expand|Select|Wrap|Line Numbers
  1. class BasisTransToGlobal(Plane3D):
  2.     def __init__(self, vN, vA, vB, vR=Point(0,0,0)):
  3.         self.vN = vN
  4.         if chk_type([vN, vA, vB, vR]):
  5.  
  6.             # local basis aligned with instance 'a', define the plane
  7.             Plane3D.__init__(self, vN, vA, vB)
  8.             # now all references to a. become self.
But I still don't see much, if any, advantage.
Dec 20 '06 #6
kudos
127 Expert 100+
its been ages since I have done any 3d computer graphics programming, but isn't it easier to use homogenous coordinates. Then you also can dig out somekind of matrix package (pynum?) and use it for all the operations.

-kudos
Dec 20 '06 #7
bvdet
2,851 Expert Mod 2GB
its been ages since I have done any 3d computer graphics programming, but isn't it easier to use homogenous coordinates. Then you also can dig out somekind of matrix package (pynum?) and use it for all the operations.

-kudos
Hi kudos,

Many SDS/2 Python scripts are designed to add to or modify objects in 3D space. These objects are beams, columns, and other members that form the structural skeleton of a building. Each of these objects has its own coordinate system, and we can translate in member coordinates with the built-in member translate method. Occasionally there will be a situation where a series of points need to be calculated with respect to a local basis and there is no member. That's why I wrote this class and its sister class that calculates the local point given a global coodinate.

It's likely that SciPy, Numpy or CoordSys would do what I need, but there may be installation issues with the average SDS/2 user. Beside that, I wanted to know how to perform these translations.

Have a great day,
BV
Dec 20 '06 #8
bvdet
2,851 Expert Mod 2GB
Of course, you could do this:

Expand|Select|Wrap|Line Numbers
  1. class BasisTransToGlobal(Plane3D):
  2.     def __init__(self, vN, vA, vB, vR=Point(0,0,0)):
  3.         self.vN = vN
  4.         if chk_type([vN, vA, vB, vR]):
  5.  
  6.             # local basis aligned with instance 'a', define the plane
  7.             Plane3D.__init__(self, vN, vA, vB)
  8.             # now all references to a. become self.
But I still don't see much, if any, advantage.
Barton,

It gives me some additional methods, but I may not need them. Plane3D also does a type check, but raises a TypeError. It would look like this:
Expand|Select|Wrap|Line Numbers
  1. class BasisTransToGlobal(Plane3D):
  2.     def __init__(self, vN, vA, vB, vR=Point(0,0,0)):
  3.         self.vN = vN
  4.         # local basis aligned with plane defined
  5.         Plane3D.__init__(self, vN, vA, vB)
  6.         if chk_type([vR, ]):
  7.  
  8.             if self.N_len > 0.0:
  9.  
  10.                 # Unit vector normal to defined plane, local basis 'Z'
  11.                 self.N = self.N_uv
  12.  
  13.                 # Unit vector between vN and vA, local basis 'X'
  14.                 self.A = self.d0
  15.  
  16.                 # Unit cross product vector, local basis 'Y'
  17.                 self.B = self.cross_product(self.N, self.A)
  18.  
  19.                 # global coordinate vector
  20.                 self.R = self.translate(vR.x, vR.y, vR.z) + vN
  21.  
  22.             else:
  23.                 Warning("The points are collinear ***INVALID***")
  24.                 self.R = None
  25.         else:
  26.             raise TypeError, "Arguments must be <type 'point'>"
This would be consistent with Plane3D.
Dec 20 '06 #9
bartonc
6,596 Expert 4TB
Barton,

It gives me some additional methods, but I may not need them. Plane3D also does a type check, but raises a TypeError. It would look like this:
Expand|Select|Wrap|Line Numbers
  1. class BasisTransToGlobal(Plane3D):
  2.     def __init__(self, vN, vA, vB, vR=Point(0,0,0)):
  3.         self.vN = vN
  4.         # local basis aligned with plane defined
  5.         Plane3D.__init__(self, vN, vA, vB)
  6.         if chk_type([vR, ]):
  7.  
  8.             if self.N_len > 0.0:
  9.  
  10.                 # Unit vector normal to defined plane, local basis 'Z'
  11.                 self.N = self.N_uv
  12.  
  13.                 # Unit vector between vN and vA, local basis 'X'
  14.                 self.A = self.d0
  15.  
  16.                 # Unit cross product vector, local basis 'Y'
  17.                 self.B = self.cross_product(self.N, self.A)
  18.  
  19.                 # global coordinate vector
  20.                 self.R = self.translate(vR.x, vR.y, vR.z) + vN
  21.  
  22.             else:
  23.                 Warning("The points are collinear ***INVALID***")
  24.                 self.R = None
  25.         else:
  26.             raise TypeError, "Arguments must be <type 'point'>"
This would be consistent with Plane3D.
That sure look very clean to me. You never know when the extra methods may come in handy... It's a little more work to document, though.
Dec 21 '06 #10

Sign in to post your reply or Sign up for a free account.

Similar topics

7
by: Bengt Richter | last post by:
Just thought None as the first argument would be both handy and mnemonic, signifying no translation, but allowing easy expression of deleting characters, e.g., s = s.translate(None,...
1
by: shank | last post by:
I'm sure this is a stretch, but is there some kind of component that I could install to translate from English to Spanish on the fly? I have a lot of equipment features and specifications that I...
4
by: Gadrin77 | last post by:
I have data that looks like <Root> <Main Value="Line1|Line2.|Line3|Line4.|Line5"/> </Root> I'm using Translate(@Value, "|.", ",")
6
by: bobueland | last post by:
The module string has a function called translate. I tried to find the source code for that function. In: C:\Python24\Lib there is one file called string.py I open it and it says
6
by: Anders K. Olsen | last post by:
Hello group I'm trying to list the users and groups who has read access to a file. I use .NET 2.0 and FileInfo.GetAccessControl().GetAccessRules(...) and then loop through the...
1
by: peterbe | last post by:
This has always worked fine for me. Peter fine Now if I do it with a unicode string: Traceback (most recent call last): File "<stdin>", line 1, in ? File "/usr/lib/python2.4/string.py", line...
1
by: =?Utf-8?B?R2F1cmF2?= | last post by:
Hi, I am using the Translate() function in one of the .XSLT file to remove the spaces, like this: <xsl:for-each select=".//Illustration"> <xsl:value-of select="translate(./@illusName, ' ',...
3
by: Kenneth McDonald | last post by:
I have the need to occasionally translate a single word programatically. Would anyone have a Python script that would let me do this using Google (or another) translation service? Thanks, Ken
4
by: kovariadam | last post by:
Hi, Does anybody know why i get this error: SQL0176N The second, third or fourth argument of the TRANSLATE scalar function is incorrect. SQLSTATE=42815 with this query: SELECT...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.