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

##  angle.py Version 1.00 (module 'angle')

##  Version 1.01 (11/12/06) - add function 'planRotPts'

"""

/// 'rtod' - Radian argument returns degrees

/// 'dtor' - Degree argument returns radians

/// 'angle_between_members' - Return the complement to the projected net angle between mem1 and mem2 in radians (0.0< theta <1.0)

/// 'flg_bevel_cut' - Return the bevel cut angle in degrees given the framing face and relative rotation in degrees

/// 'bm_setback' - Return a setback given a depth (d2), clearance (clr), setback (setb), and flange bevel cut

/// 'planRotPts' - Return plan angle in radians for argument points

"""

from math import pi, atan, cos

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

def rtod ( r ):

return (r * 180.0 / pi)

def dtor ( d ):

return (d * pi / 180.0)

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

# return the complement to the projected net angle in radians between mem1 and mem2

# the projection is in the plane of the top flange of mem1

def angle_between_members(mem1, mem2):

pt1 = mem1.trans_to_local(mem2.left_location - mem1.left_location)

pt2 = mem1.trans_to_local(mem2.right_location - mem1.left_location)

return atan((pt2.x - pt1.x) / (pt2.z - pt1.z))

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

# return the bevel cut angle in degrees given the framing face

# and relative rotation

def flg_bevel_cut (face, rot):

if face == "Face C":

if rot >= 0.0 and rot < 90.0:

return -rot

else:

return 360.0 - rot

elif face == "Face D":

return 90.0 - rot

elif face == "Face A":

return 180.0 - rot

elif face == "Face B":

return 270.0 - rot

elif face == "None":

return 0.0

else:

print "Invalid results"

return 0

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

# return a setback given a depth (d2), clearance (clr), setback (setb),

# and flange bevel cut

def bm_setback (d2, clr, setb, rot): # rot is the flange bevel cut

return (d2 + clr + setb) / cos(dtor(rot))

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

# return plan angle for argument points in radians

def planRotPts(p1, p2):

from math import pi, atan2

dpx = p2.x - p1.x

dpy = p2.y - p1.y

if round(dpx, 4) == 0.0:

if dpy > 0.0:

return pi/2.0

else:

return -pi/2.0

else:

A = atan2(dpy, dpx)

if A > pi:

return A - pi

else:

return A

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

def test_planRotPts():

from param import yes_or_no, Warning

from point import Point, PointLocate

pt1 = PointLocate("Select Point 1")

pt2 = PointLocate("Select Point 2")

Warning("The plan angle between selected points is %0.4f degrees." % (rtod(planRotPts(pt1, pt2))))

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

def test_angle_between_members():

from member import Member, MemberLocate

from param import yes_or_no, Warning

from macrolib.ExceptWarn import formatExceptionInfo

mem1 = MemberLocate("Select Member 1")

mem2 = MemberLocate("Select Member 2")

Warning('The complement to the net angle between the members in the plane\nof the top flange of Member 1 = %0.4f degrees' % \

(rtod(angle_between_members(mem1, mem2))))

## END test_angle_between_members() #################################

if __name__ == '__main__':

try:

test_angle_between_members()

test_planRotPts()

finally:

del rtod, dtor, flg_bevel_cut, angle_between_members, bm_setback, planRotPts

del test_angle_between_members

del test_planRotPts