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