## PointRotate.py Version 1.02

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

## All rights reserved.

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

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

"""

Return a point rotated about an arbitrary axis in 3D.

Positive angles are counter-clockwise looking down the axis toward the origin.

The coordinate system is assumed to be right-hand.

Arguments: 'axis point 1', 'axis point 2', 'point to be rotated', 'angle of rotation (in radians)' >> 'new point'

Revision History:

Version 1.01 (11/11/06) - Revised function code

Version 1.02 (11/16/06) - Rewrote PointRotate3D function

 

Reference 'Rotate A Point About An Arbitrary Axis (3D)' - Paul Bourke

"""

def PointRotate3D(p1, p2, p0, theta):

from point import Point

from math import cos, sin, sqrt

 

# Translate so axis is at origin

p = p0 - p1

# Initialize point q

q = Point(0.0,0.0,0.0)

N = (p2-p1)

Nm = sqrt(N.x**2 + N.y**2 + N.z**2)

# Rotation axis unit vector

n = Point(N.x/Nm, N.y/Nm, N.z/Nm)

 

# Matrix common factors

c = cos(theta)

t = (1 - cos(theta))

s = sin(theta)

X = n.x

Y = n.y

Z = n.z

 

# Matrix 'M'

d11 = t*X**2 + c

d12 = t*X*Y - s*Z

d13 = t*X*Z + s*Y

d21 = t*X*Y + s*Z

d22 = t*Y**2 + c

d23 = t*Y*Z - s*X

d31 = t*X*Z - s*Y

d32 = t*Y*Z + s*X

d33 = t*Z**2 + c

 

# |p.x|

# Matrix 'M'*|p.y|

# |p.z|

q.x = d11*p.x + d12*p.y + d13*p.z

q.y = d21*p.x + d22*p.y + d23*p.z

q.z = d31*p.x + d32*p.y + d33*p.z

 

# Translate axis and rotated point back to original location

return q + p1

## END PointRotate3D() ##########################

def test_PointRotate3D():

from point import Point, PointLocate

from member import Member, MemberLocate

from param import dim_print, Prompt, yes_or_no, Warning, ClearSelection

from macrolib.angle import dtor

from macrolib.ExceptWarn import formatExceptionInfo

from macrolib.PrintPtList import formatPtList

a1 = 45.0

while 1:

ClearSelection()

try:

Warning("Rotate a Point About a Member Line - The rotation is REVERSED if the view " +\

"along the rotation axis is from the member LEFT end toward the member RIGHT end. " + \

"A right hand coordinate system is assumed. Positive angles are counter-clockwise " +\

"when looking down the axis toward the origin. The member LEFT end is the origin.")

mem1 = MemberLocate("Select member to rotate about")

pt1 = PointLocate("Pick point to rotate")

a1 = Prompt(a1, "Rotation angle")

pt2 = PointRotate3D(mem1.left.location, mem1.right.location, pt1, dtor(a1))

Warning("The selected point is %s, %s, %s \nThe new point is %s, %s, %s" % \

(dim_print(pt1.x), dim_print(pt1.y), dim_print(pt1.z), dim_print(pt2.x), dim_print(pt2.y), dim_print(pt2.z)))

print formatPtList("Rotation Axis End Points:", [mem1.left.location, mem1.right.location])

print formatPtList("Original Point and Rotated Point Coordinates:", [pt1, pt2])

except:

Warning(formatExceptionInfo())

if not yes_or_no("Continue?"):

break

## END test_PointRotate3D() #####################

if __name__ == '__main__':

try:

test_PointRotate3D()

finally:

del test_PointRotate3D

 

# SAMPLE OUTPUT

Rotation Axis End Points:
X attribute         Y attribute         Z attribute         
============================================================
80-0                46-10               120-7               
80-0                52-6                110-5 1/8           

Original Point and Rotated Point Coordinates:
X attribute         Y attribute         Z attribute         
============================================================
80-0                61-3 3/4            115-1 7/8           
87-0 7/8            58-9 1/16           113-8 3/4