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: - ## Basis3D.py Version 1.02 (module macrolib.Basis3D)
-
## Copyright (c) 2006 Bruce Vaughan, BV Detailing & Design, Inc.
-
## All rights reserved.
-
## NOT FOR SALE. The software is provided "as is" without any warranty.
-
############################################################################
-
"""
-
Class BasisTransToGlobal
-
Given 3 counter-clockwise non-collinear points, define an orthonormal basis in 3D space (the local basis).
-
Calculate the global point, a vector in the standard basis set, given a displacement vector in the local basis.
-
The object type of the displacement vector 'vR' is 'point'.
-
An instance translate method can be called:
-
ref_pt + instance.translate(x, y, z) --> global coordinate point object
-
Method 'translate' example usage:
-
pt = global point origin of translation to be calculated (example: mem.left.location)
-
a = class instance
-
x, y, and z are offsets from pt in the local basis
-
pt + a.translate(x, y, z)
-
"""
-
-
from macrolib.ExceptWarn import formatExceptionInfo
-
from macrolib.P3D import Plane3D
-
from param import Warning
-
from point import Point
-
-
def chk_type(p_list):
-
for p in p_list:
-
if not isinstance(p, type(Point(0,0,0))):
-
return False
-
return True
-
-
class BasisTransToGlobal(object):
-
def __init__(self, vN, vA, vB, vR=Point(0,0,0)):
-
self.vN = vN
-
if chk_type([vN, vA, vB, vR]):
-
-
# local basis aligned with instance 'a', define the plane
-
a = Plane3D(vN, vA, vB)
-
-
if a.N_len > 0.0:
-
-
# Unit vector normal to defined plane, local basis 'Z'
-
self.N = a.N_uv
-
-
# Unit vector between vN and vA, local basis 'X'
-
self.A = a.d0
-
-
# Unit cross product vector, local basis 'Y'
-
self.B = a.cross_product(self.N, self.A)
-
-
# global coordinate vector
-
self.R = self.translate(vR.x, vR.y, vR.z) + vN
-
-
else:
-
Warning("The points are collinear ***INVALID***")
-
self.R = None
-
else:
-
Warning("Argument type must be 'point'")
-
self.R = None
-
-
def translate(self, X, Y, Z):
-
A, B, N = self.A, self.B, self.N
-
M = (X*X + Y*Y + Z*Z)**0.5
-
# vR normalized
-
if M > 0:
-
X1, Y1, Z1 = X/M, Y/M, Z/M
-
else:
-
X1, Y1, Z1 = 0.0, 0.0, 0.0
-
-
D = self.determinant3(A.x, A.y, A.z, N.x, N.y, N.z, B.x, B.y, B.z)
-
Dx = self.determinant3(X1, A.y, A.z, Z1, N.y, N.z, Y1, B.y, B.z)
-
Dy = self.determinant3(A.x, X1, A.z, N.x, Z1, N.z, B.x, Y1, B.z)
-
Dz = self.determinant3(A.x, A.y, X1, N.x, N.y, Z1, B.x, B.y, Y1)
-
-
# resultant unit vector R1
-
R1 = Point(Dx/D, Dy/D, Dz/D)
-
-
# global coordinate vector with respect to local basis origin
-
return Point(R1.x*M, R1.y*M, R1.z*M)
-
-
def determinant3(self, a,b,c,m,n,k,u,v,w):
-
return a*n*w + b*k*u + m*v*c - c*n*u - b*m*w - a*k*v
-
-
def version(self):
-
"Basis3D.BasisTransToGlobal Version 1.02"
Here' s the test script: - from macrolib.Basis3D import BasisTransToGlobal
-
def test_BasisTransToGlobal():
-
from macrolib.ExceptWarn import formatExceptionInfo
-
from macrolib.PrintPtList import formatPtList
-
from macrolib.PrintDict import formatDict
-
from param import Dialog, dim_print, Warning, ResponseNotOK, Units
-
from point import Point, PointLocate
-
import os
-
Units("feet")
-
try:
-
dlg1 = Dialog("Translate to Global in an Orthogonal Basis")
-
dlg1.group_title("Orthonormal Basis and Resultant Unit Vector")
-
image_path = os.path.join(os.getcwd(), "macro", "Images")
-
image_name = os.path.join(image_path, "Basis3D_XYZ.gif")
-
dlg1.image(image_name)
-
dlg1.group_title("Translation Vector")
-
dlg1.entry('distX', dim_print(60.0), "Enter translate 'X' direction")
-
dlg1.entry('distY', dim_print(30.0), "Enter translate 'Y' direction")
-
dlg1.entry('distZ', dim_print(0.0), "Enter translate 'Z' direction")
-
try:
-
dlg1.done()
-
except ResponseNotOK:
-
raise StandardError, "User Cancelled"
-
pt1 = PointLocate("Pick point 1 (Basis 0,0,0)")
-
pt2 = PointLocate("Pick point 2 (Basis 'X')")
-
pt3 = PointLocate("Pick point 3 to define plane")
-
pt4 = Point(dlg1.distX, dlg1.distY, dlg1.distZ)
-
except:
-
Warning(formatExceptionInfo())
-
else:
-
if pt1 and pt2 and pt3 and pt4:
-
a = BasisTransToGlobal(pt1, pt2, pt3, pt4)
-
if a.R:
-
print formatPtList("Local Basis Origin:", [pt1, ])
-
print formatPtList("Local Basis Translate Vector:", [pt4, ])
-
print formatPtList("Resultant Global Point:", [a.R, ])
-
print formatDict("BasisTransToGlobal Instance Dictionary:", a.__dict__)
-
# print formatDict("Local Dictionary:", locals())
-
print formatPtList("Resultant Global Points Calculated With Method 'translate':",
-
[pt1+a.translate(12, 12, 0), pt1+a.translate(13, 13, 0), \
-
pt1+a.translate(14, 14, -3)])
-
-
if __name__ == '__main__':
-
test_BasisTransToGlobal()
Test script output: - Local Basis Origin:
-
X attribute Y attribute Z attribute
-
==================================================
-
2-7 3/8 -2-3 1/2 1-9 15/16
-
-
Local Basis Translate Vector:
-
X attribute Y attribute Z attribute
-
==================================================
-
5-0 2-6 10
-
-
Resultant Global Points:
-
X attribute Y attribute Z attribute
-
==================================================
-
-1-3 5/8 -7-2 3/8 -7 7/8
-
-
BasisTransToGlobal Instance Dictionary:
-
Key = A Value = 0, -0.623718, -0.78165
-
Key = B Value = 0.746515, -0.520085, 0.415003
-
Key = N Value = -0.665369, -0.583513, 0.465615
-
Key = R Value = -15.620537, -86.364783, -7.845922
-
Key = vN Value = -31.362292, -27.504023, 21.946829
-
-
Resultant Global Points Calculated With Method 'translate':
-
X attribute Y attribute Z attribute
-
==================================================
-
-1-10 3/8 -3-5 1/4 1-5 9/16
-
-1-9 11/16 -3-6 3/8 1-5 3/16
-
-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
9 3081
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.
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
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. -
class BasisTransToGlobal(Plane3D):
-
def __init__(self, vN, vA, vB, vR=Point(0,0,0)):
-
Plane3D.__init__(self, vN, vA, vB)
-
self.vN = vN
-
if chk_type([vN, vA, vB, vR]):
-
-
# local basis aligned with instance 'a', define the plane
-
# 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.
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. -
class BasisTransToGlobal(Plane3D):
-
def __init__(self, vN, vA, vB, vR=Point(0,0,0)):
-
Plane3D.__init__(self, vN, vA, vB)
-
self.vN = vN
-
if chk_type([vN, vA, vB, vR]):
-
-
# local basis aligned with instance 'a', define the plane
-
# 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.
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: -
class BasisTransToGlobal(Plane3D):
-
def __init__(self, vN, vA, vB, vR=Point(0,0,0)):
-
self.vN = vN
-
if chk_type([vN, vA, vB, vR]):
-
-
# local basis aligned with instance 'a', define the plane
-
Plane3D.__init__(self, vN, vA, vB)
-
# now all references to a. become self.
But I still don't see much, if any, advantage.
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
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
bvdet 2,851
Expert Mod 2GB
Of course, you could do this: -
class BasisTransToGlobal(Plane3D):
-
def __init__(self, vN, vA, vB, vR=Point(0,0,0)):
-
self.vN = vN
-
if chk_type([vN, vA, vB, vR]):
-
-
# local basis aligned with instance 'a', define the plane
-
Plane3D.__init__(self, vN, vA, vB)
-
# 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: - class BasisTransToGlobal(Plane3D):
-
def __init__(self, vN, vA, vB, vR=Point(0,0,0)):
-
self.vN = vN
-
# local basis aligned with plane defined
-
Plane3D.__init__(self, vN, vA, vB)
-
if chk_type([vR, ]):
-
-
if self.N_len > 0.0:
-
-
# Unit vector normal to defined plane, local basis 'Z'
-
self.N = self.N_uv
-
-
# Unit vector between vN and vA, local basis 'X'
-
self.A = self.d0
-
-
# Unit cross product vector, local basis 'Y'
-
self.B = self.cross_product(self.N, self.A)
-
-
# global coordinate vector
-
self.R = self.translate(vR.x, vR.y, vR.z) + vN
-
-
else:
-
Warning("The points are collinear ***INVALID***")
-
self.R = None
-
else:
-
raise TypeError, "Arguments must be <type 'point'>"
This would be consistent with Plane3D.
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: - class BasisTransToGlobal(Plane3D):
-
def __init__(self, vN, vA, vB, vR=Point(0,0,0)):
-
self.vN = vN
-
# local basis aligned with plane defined
-
Plane3D.__init__(self, vN, vA, vB)
-
if chk_type([vR, ]):
-
-
if self.N_len > 0.0:
-
-
# Unit vector normal to defined plane, local basis 'Z'
-
self.N = self.N_uv
-
-
# Unit vector between vN and vA, local basis 'X'
-
self.A = self.d0
-
-
# Unit cross product vector, local basis 'Y'
-
self.B = self.cross_product(self.N, self.A)
-
-
# global coordinate vector
-
self.R = self.translate(vR.x, vR.y, vR.z) + vN
-
-
else:
-
Warning("The points are collinear ***INVALID***")
-
self.R = None
-
else:
-
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.
Sign in to post your reply or Sign up for a free account.
Similar topics
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,...
|
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...
|
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, "|.", ",")
|
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
|
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...
|
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...
|
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, ' ',...
|
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
|
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...
|
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
|
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...
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
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...
|
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,...
|
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,...
|
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...
|
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,...
|
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...
| |