##  Basis3D.py Version 1.04 (module macrolib.Basis3D)

##  Copyright (c) 2006 Bruce Vaughan, BV Detailing & Design, Inc.

##  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)

Class BasisTransToLocal

Given 3 counter-clockwise non-collinear points, define an orthonormal basis.

Given a fourth point in the standard basis set, calculate the local coordinate in the defined basis.

Method 'trans_to_local' example usage:

a = class instance (defines local basis)

x, y, and z are floats corresponding to global coordinate

a.trans_to_local(x, y, z) --> local point in local basis defined by class instance 'a'

Version 1.01 (12/06/06) - Optimize function chk_type()

Version 1.02 (12/18/06) - Add translate method to BasisTransToGlobal

Version 1.03 (12/20/06) - Derive BasisTransToGlobal and BasisTransToLocal from Plane3D

Version 1.04 (2/16/07) -  Add __repr__ methods for both class definitions.

__str__ method is inherited from Plane3D.

"""

from macrolib.ExceptWarn import formatExceptionInfo

from macrolib.P3D import Plane3D

from param import Warning

from point import Point

from macrolib.fifDim import fifDim

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(Plane3D):

def __init__(self, vN, vA, vB, vR=Point(0,0,0)):

self.vN = vN

self.vA = vA

self.vB = vB

self.vR = vR

# 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'>"

def translate(self, X, Y, Z):

def determinant3(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

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 = determinant3(A.x, A.y, A.z, N.x, N.y, N.z, B.x, B.y, B.z)

Dx = determinant3(X1, A.y, A.z, Z1, N.y, N.z, Y1, B.y, B.z)

Dy = determinant3(A.x, X1, A.z, N.x, Z1, N.z, B.x, Y1, B.z)

Dz = 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 __repr__(self):

return 'BasisTransToGlobal(Point(%s), Point(%s), Point(%s), Point(%s))' % (self.vN, self.vA, self.vB, self.vR)

def version(self):

"Basis3D.BasisTransToGlobal Version 1.03"

## END BasisTransToGlobal() ##########################################################

class BasisTransToLocal(Plane3D):

def __init__(self, vN, vA, vB, R1=Point(0,0,0)):

# local basis aligned with plane defined

Plane3D.__init__(self, vN, vA, vB)

self.vN = vN

self.vA = vA

self.vB = vB

self.R1 = R1

if chk_type([R1, ]):

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)

# instance attribute 'P' is the local coordinate vector

self.P = self.trans_to_local(R1.x, R1.y, R1.z)

else:

Warning("The points are collinear ***INVALID***")

self.P = None

else:

raise TypeError, "Arguments must be <type 'point'>"

def dot_product(self, p1, p2):

return (p1.x*p2.x + p1.y*p2.y + p1.z*p2.z)

def trans_to_local(self, X, Y, Z):

R = Point(X, Y, Z) - self.vN

# Vector projection of: R along vA, R along vB, R along vN

return Point(self.dot_product(R, self.A), self.dot_product(R, self.B), self.dot_product(R, self.N))

def __repr__(self):

return 'BasisTransToLocal(Point(%s), Point(%s), Point(%s), Point(%s))' % (self.vN, self.vA, self.vB, self.R1)

def version(self):

"Basis3D.BasisTransToLocal Version 1.03"

## END 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:

Warning(formatPtList("Resultant Global Point:", [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)])

print dir(a)

print

print a

print

print repr(a)

## END test_BasisTransToGlobal() ##########################

def test_BasisTransToLocal():

from macrolib.ExceptWarn import formatExceptionInfo

from macrolib.PrintPtList import formatPtList

from macrolib.PrintDict import formatDict

from param import Warning, Units, dim_print

from point import Point, PointLocate

Units("feet")

try:

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 = PointLocate("Pick point 4 and determine local basis coordinates")

except:

Warning(formatExceptionInfo())

else:

a = BasisTransToLocal(pt1, pt2, pt3)

if a.P:

Warning(formatPtList("Global Point(0,0,0) --> Local Basis Point(0,0,0):", [a.P, ]))

print formatPtList("Global Point(0,0,0) --> Local Basis Point(0,0,0):", [a.P, ])

print formatPtList("Selected Global Point (%s, %s, %s) --> Resultant Local Point:" % \

(dim_print(pt4.x), dim_print(pt4.y), dim_print(pt4.z)), \

[a.trans_to_local(pt4.x, pt4.y, pt4.z), ])

print formatDict("BasisTransToLocal Instance Dictionary:", a.__dict__)

print formatDict("Local Dictionary:", locals())

print formatPtList("Resultant Local Points Calculated With Method 'trans_to_local':",

[a.trans_to_local(12, 12, 0), a.trans_to_local(13, 13, 0), \

a.trans_to_local(14, 14, -3)])

print

print dir(a)

print

print a

print

print repr(a)

## END test_BasisTransToLocal() ##########################

if __name__ == '__main__':

try:

#test_BasisTransToGlobal()

test_BasisTransToLocal()

finally:

del test_BasisTransToGlobal

del test_BasisTransToLocal

del BasisTransToGlobal

del BasisTransToLocal

del chk_type

""" Output from test_BasisTransToGlobal()

Local Basis Origin:

X attribute         Y attribute         Z attribute

============================================================

31-1 3/4            32-4 1/2            988-6 1/8

Local Basis Translate Vector:

X attribute         Y attribute         Z attribute

============================================================

5-0                 2-6                 1-0

Resultant Global Point:

X attribute         Y attribute         Z attribute

============================================================

35-10 7/16          35-6 1/4            988-7 3/4

BasisTransToGlobal Instance Dictionary:

Key = A        Value = 0.834688, 0.353974, -0.421898

Key = B        Value = 0, 0.766081, 0.642744

Key = D        Value = -37814556.9835

Key = F        Value = 415.574927, 406.207335, 11840.96773

Key = G        Value = 365.076469, 403.863501, 11882.493525

Key = N        Value = 0.550723, -0.53649, 0.639439

Key = N_len    Value = 4987.071941

Key = N_uv     Value = 0.550723, -0.53649, 0.639439

Key = Q        Value = 1.96714819484

Key = R        Value = 430.46263, 426.262852, 11863.73862

Key = Ra       Value = 100.162570884

Key = d        Value = 83.60451, 35.454928, -42.258426

Key = d0       Value = 0.834688, 0.353974, -0.421898

Key = e        Value = -17.392406, 30.767261, 40.793163

Key = e0       Value = -0.322236, 0.570038, 0.755792

Key = k        Value = 37814556.9835

Key = k0       Value = 7582.516842

Key = p1       Value = 373.772672, 388.479871, 11862.096943

Key = p2       Value = 457.377182, 423.934799, 11819.838516

Key = p3       Value = 356.380266, 419.247132, 11902.890106

Key = pp       Value = 197.034620505

Key = vA       Value = 457.377182, 423.934799, 11819.838516

Key = vB       Value = 356.380266, 419.247132, 11902.890106

Key = vN       Value = 373.772672, 388.479871, 11862.096943

Key = vR       Value = 60, 30, 12

Resultant Global Points Calculated With Method 'translate':

X attribute         Y attribute         Z attribute

============================================================

31-11 13/16         33-5 15/16          988-8 3/4

32-0 5/8            33-7 1/16           988-8 15/16

31-11 13/16         33-9 3/4            988-7 1/4

['A', 'B', 'D', 'F', 'G', 'N', 'N_len', 'N_uv', 'PointRotate3D', 'Q', 'R', 'Ra', '__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__', 'cross_product', 'd', 'd0', 'dot_product', 'e', 'e0', 'k', 'k0', 'lie_check', 'p1', 'p2', 'p3', 'plane_2', 'plane_3', 'plane_def', 'pp', 'three_pt_circle', 'translate', 'vA', 'vB', 'vN', 'vR', 'version']

Instance of Class BasisTransToGlobal - Plane Definition Data:

Normal Unit Vector - 0.5507, -0.5365, 0.6394

Displacement from Model Origin - 7582.5168

Plane Origin and Unit Vector Points:

Origin point - 31'-1 3/4, 32'-4 1/2, 988'-6 1/8

Unit Vector d0  - 0.8347, 0.3540, -0.4219

Unit Vector e0  - -0.3222, 0.5700, 0.7558

BasisTransToGlobal(Point(373.772672, 388.479871, 11862.096943), Point(457.377182, 423.934799, 11819.838516), Point(356.380266, 419.247132, 11902.890106), Point(60, 30, 12))

"""

""" Output from test_BasisTransToLocal()

Global Point(0,0,0) --> Local Basis Point(0,0,0):

X attribute         Y attribute         Z attribute

============================================================

379-7 1/8           -660-1 7/8          -631-10 1/2

Selected Global Point (37-3 7/8, 39-8 9/16, 989-4 3/16) --> Resultant Local Point:

X attribute         Y attribute         Z attribute

============================================================

7-4 3/4             6-1 15/16           0

BasisTransToLocal Instance Dictionary:

Key = A        Value = 0.834688, 0.353974, -0.421898

Key = B        Value = 0, 0.766081, 0.642744

Key = D        Value = -129165559.229

Key = F        Value = 415.574927, 406.207335, 11840.96773

Key = G        Value = 404.478354, 466.645261, 11901.23229

Key = N        Value = 0.550723, -0.53649, 0.639439

Key = N_len    Value = 17034.655105

Key = N_uv     Value = 0.550723, -0.53649, 0.639439

Key = P        Value = 4555.104174, -7921.895658, -7582.516842

Key = Q        Value = 1.16249738903

Key = R1       Value = 0, 0, 0

Key = Ra       Value = 100.162570884

Key = d        Value = 83.60451, 35.454928, -42.258426

Key = d0       Value = 0.834688, 0.353974, -0.421898

Key = e        Value = 61.411363, 156.330781, 78.270694

Key = e0       Value = 0.331412, 0.843652, 0.422394

Key = k        Value = 129165559.229

Key = k0       Value = 7582.516842

Key = p1       Value = 373.772672, 388.479871, 11862.096943

Key = p2       Value = 457.377182, 423.934799, 11819.838516

Key = p3       Value = 435.184036, 544.810652, 11940.367636

Key = pp       Value = 116.43872713

Key = vA       Value = 457.377182, 423.934799, 11819.838516

Key = vB       Value = 435.184036, 544.810652, 11940.367636

Key = vN       Value = 373.772672, 388.479871, 11862.096943

Local Dictionary:

Key = Point                  Value = <built-in function Point>

Key = PointLocate            Value = <built-in function PointLocate>

Key = Units                  Value = <built-in function Units>

Key = Warning                Value = <built-in function Warning>

Key = a                      Value = Instance of Class BasisTransToLocal - Plane Definition Data:

Normal Unit Vector - 0.5507, -0.5365, 0.6394

Displacement from Model Origin - 7582.5168

Plane Origin and Unit Vector Points:

Origin point - 31'-1 3/4, 32'-4 1/2, 988'-6 1/8

Unit Vector d0  - 0.8347, 0.3540, -0.4219

Unit Vector e0  - 0.3314, 0.8437, 0.4224

Key = dim_print              Value = <built-in function dim_print>

Key = formatDict             Value = <function formatDict at 0x06491764>

Key = formatExceptionInfo    Value = <function formatExceptionInfo at 0x064403AC>

Key = formatPtList           Value = <function formatPtList at 0x06491DBC>

Key = pt1                    Value = 373.772672, 388.479871, 11862.096943

Key = pt2                    Value = 457.377182, 423.934799, 11819.838516

Key = pt3                    Value = 435.184036, 544.810652, 11940.367636

Key = pt4                    Value = 447.866182, 476.546336, 11872.171132

Resultant Local Points Calculated With Method 'trans_to_local':

X attribute         Y attribute         Z attribute

============================================================

380-9 3/8           -659-4 11/16        -631-10 3/8

380-10 9/16         -659-3 15/16        -631-10 5/16

381-1               -659-5 1/8          -632-0 1/4

['A', 'B', 'D', 'F', 'G', 'N', 'N_len', 'N_uv', 'P', 'PointRotate3D', 'Q', 'R1', 'Ra', '__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__', 'cross_product', 'd', 'd0', 'dot_product', 'e', 'e0', 'k', 'k0', 'lie_check', 'p1', 'p2', 'p3', 'plane_2', 'plane_3', 'plane_def', 'pp', 'three_pt_circle', 'trans_to_local', 'vA', 'vB', 'vN', 'version']

Instance of Class BasisTransToLocal - Plane Definition Data:

Normal Unit Vector - 0.5507, -0.5365, 0.6394

Displacement from Model Origin - 7582.5168

Plane Origin and Unit Vector Points:

Origin point - 31'-1 3/4, 32'-4 1/2, 988'-6 1/8

Unit Vector d0  - 0.8347, 0.3540, -0.4219

Unit Vector e0  - 0.3314, 0.8437, 0.4224

BasisTransToLocal(Point(373.772672, 388.479871, 11862.096943), Point(457.377182, 423.934799, 11819.838516), Point(435.184036, 544.810652, 11940.367636), Point(0, 0, 0))

"""

“””

Script Basis3D_XYZ demonstrating class BasisTransToGlobal and its translate() method

“””

##  Basis3D_XYZ.py Version 1.01

##  Copyright (c) 2006 Bruce Vaughan, BV Detailing & Design, Inc.

##  NOT FOR SALE. The software is provided "as is" without any warranty.

############################################################################

"""

Define a plane in 3D space by picking 3 counter-clockwise non-collinear points.

Line p1p2 defines the 'X' axis of an orthogonal basis.

Translate X, Y, and Z dimensions in the orthogonal basis and return a global point.

Display information in Report Viewer.

Add miscellaneous members to represent the orthonormal basis and the calculated resultant unit vector.

A basis which is also an orthonormal set of vectors (ie every pair of vectors is orthogonal, and every

vector has magnitude 1) is called an orthonormal basis.

Revision History:

Version 1.00 (11/14/06) - Initial Version

Version 1.01 (12/18/06) - Demonstrate instance method 'translate' calculation

"""

def run_script():

from macrolib.Basis3D import BasisTransToGlobal

from macrolib.ExceptWarn import formatExceptionInfo

from macrolib.P3D import Plane3D

from macrolib.PolarPt import PolarPt3D

from macrolib.PrintPtList import formatPtList

from macrolib.PrintDict import formatDict

from param import Warning, yes_or_no, dim_print, Prompt, Units, Dialog, ResponseNotOK

from point import Point, PointLocate

from rnd_bar import RndBar

from member import Member

import os

Units("feet")

#######################################################

# cannot assign existing = "Yes"

# cannot assign sequence to miscellaneous member

# description is ignored

###########################################

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(100.0), "Enter translate 'X' direction")

dlg1.entry('distY', dim_print(75.00), "Enter translate 'Y' direction")

dlg1.entry('distZ', dim_print(-50.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:

a = BasisTransToGlobal(pt1, pt2, pt3, pt4)

if a.R:

print formatPtList("Resultant Global Point (instance attribute 'R'):", [a.R, ])

print formatDict("\nBasisTransToGlobal Instance Dictionary:", a.__dict__)

print formatDict("\nLocal Dictionary:", locals())

print formatPtList("Global points calculated with method 'translate':",

[pt1+a.translate(120, 120, 0), pt1+a.translate(132, 132, 0), pt1+a.translate(144, 144, -30)])

print formatDict("\nBasisTransToGlobal Instance Dictionary After Calling Method 'translate':", a.__dict__)

## END run_script() ############################################

if __name__ == '__main__':

try:

run_script()

finally:

del run_script

“””

Sample output from test script Basis3D_XYZ:

Local Basis Origin:
X attribute         Y attribute         Z attribute
============================================================
57-1 1/8            73-0 1/4            138-3 1/2

Local Basis Translate Vector:
X attribute         Y attribute         Z attribute
============================================================
5-0                 2-6                 1-0

Resultant Global Point:
X attribute         Y attribute         Z attribute
============================================================
56-6 11/16          76-2 7/8            142-11 1/4

BasisTransToGlobal Instance Dictionary:
Key = A        Value = 0.276485, 0.771189, 0.573432
Key = B        Value = -0.900763, 0, 0.43431
Key = D        Value = -1483971.6353
Key = F        Value =
693.396015, 899.384225, 1676.704266
Key = G        Value =
671.589962, 876.248558, 1666.015973
Key = N        Value = 0.334935, -0.636607, 0.694658
Key = N_len    Value = 1800.007731
Key = N_uv     Value = 0.334935, -0.636607, 0.694658
Key = Q        Value = 1.57079632679
Key = R        Value =
678.686877, 914.880588, 1715.272428
Key = Ra       Value = 60.0000315318
Key = d        Value = 16.589103, 46.271336, 34.405943
Key = d0       Value = 0.276485, 0.771189, 0.573432
Key = e        Value = -27.023002, 1e-06, 13.029357
Key = e0       Value = -0.900763, 0, 0.43431
Key = k        Value = 1483971.6353
Key = k0       Value =
824.425145
Key = p1       Value =
685.101463, 876.248557, 1659.501295
Key = pp       Value = 94.2478291377
Key = vN       Value =
685.101463, 876.248557, 1659.501295

Resultant Global Points Calculated With Method 'translate':
X attribute         Y attribute         Z attribute
============================================================
56-5 5/8            73-9 1/2            139-3 5/8
56-5                73-10 1/4           139-4 5/8
56-3 3/8            74-0 15/16          139-3 1/2

“””