##  bp_data.py Version 1.00 (module bp_data)

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

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

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

'''Class definition BPdata() for use with parametric Col_BntPLConn_v1.00 and higher.'''

from math import tan, sin, cos

from macrolib.angle import rtod, dtor

class BPdata(object):

def __init__(self, col, beam, flgweb, whichend, conntype, bpga, bpthk, e_clr):

self.beam = beam

self.col = col

self.flgweb = flgweb

self.whichend = whichend

self.conntype = conntype

self.bpga = bpga

self.bpthk = bpthk

self.e_clr = e_clr

self.netRot = round((beam.plan_rotation - col.rotation), 5)

# flgweb "Short Side" - attachment to flange

# flgweb "Long Side" - attachment to web (HSS only)

if flgweb == "Short Side":

self.bendAng = abs(90.0 - abs(self.netRot))

else:

self.bendAng = 90.0 - (abs(90.0 - abs(self.netRot)))

# calculate relative rotation relRot

endDict = {"right end": self.netRot+180, "left end": self.netRot}

relRot = endDict[whichend]

if relRot < 0.0: relRot += 360.0

caseDict = {"Case 1": {"Long Side": (1,1,(180.0-relRot, 0.0, 180.0)), "Short Side": (1,1,(relRot, 0.0, 0.0))}, \

"Case 2": {"Long Side": (-1,1,(relRot, 0.0, 0.0)), "Short Side": (-1,-1,(180.0-relRot, 0.0, 180.0))}, \

"Case 3": {"Long Side": (1,-1,(180.0-relRot, 0.0, 180.0)), "Short Side": (-1,1,(relRot, 0.0, 0.0))}, \

"Case 4": {"Long Side": (-1,-1,(relRot, 0.0, 0.0)), "Short Side": (1,-1,(180.0-relRot, 0.0, 180.0))}

}

if 0.0 < relRot <= 90.0:

caseno = "Case 1"

elif 90.0 < relRot <= 180.0:

caseno = "Case 2"

elif 180.0 < relRot <= 270.0:

caseno = "Case 3"

else:

caseno = "Case 4"

self.xflg, self.yflg, self.rot = caseDict[caseno][flgweb]

self.caseno = caseno

self.relRot = relRot

def xyz_offsets(self):

# calculate offsets and bent plate WP location

# attachment to flange

cr = cos(dtor(self.relRot))

sr = sin(dtor(self.relRot))

tr = tan(dtor(self.relRot))

if self.flgweb == "Short Side":

if self.conntype in ["Conventional", "Wrapped"]:

xoff = self.xflg * self.col.depth/2.0

else:

xoff = self.xflg * (self.col.depth/2.0 - (self.col.tf+self.bpthk))

if self.conntype in ["Conventional", "Hooked"]:

yoff = (xoff*tr - self.yflg*((self.beam.tw+self.e_clr)/2.0)/cr)

else:

yoff = (xoff*tr + self.yflg*((self.beam.tw+self.e_clr)/2.0+self.bpthk)/cr)

# attachment to web (hss only)

else:

yoff = self.yflg * self.col.bf/2.0

if self.conntype == "Conventional":

xoff = (yoff/tr - self.xflg*((self.beam.tw+self.e_clr)/2.0)/sr)

else:

xoff = (yoff/tr + self.xflg*((self.beam.tw+self.e_clr)/2.0+self.bpthk)/sr)

# calculate distance from column CL to first bolt column

if self.conntype in ["Conventional", "Hooked"]:

if self.flgweb == "Short Side":

zoff = abs(xoff/cr) - ((self.beam.tw + self.e_clr)/2.0) * abs(tr) + self.bpga

else:

zoff = abs(yoff/sr) - ((self.beam.tw + self.e_clr)/2.0) / abs(tr) + self.bpga

else:

if self.flgweb == "Short Side":

zoff = abs(xoff/cr) + ((self.beam.tw + self.e_clr)/2.0 + self.bpthk) * abs(tr) + self.bpga

else:

zoff = abs(yoff/sr) + ((self.beam.tw + self.e_clr)/2.0 + self.bpthk) / abs(tr) + self.bpga

return xoff, yoff, zoff

if __name__ == '__main__':

from member import Member, MemberLocate

col = MemberLocate("Select column")

bm = MemberLocate("Select beam")

'''

arguments: col, bm, flgweb, whichend, conntype, bpga, bpthk, e_clr

flgweb = "Short Side" or "Long Side"

whichend = "left end" or "right end"

conntype = "Conventional", "Hooked", "Wrapped", "HookWrap"

'''

a = BPdata(col, bm, "Short Side", "left end", "Hooked", 2.5, 0.375, 0.0)

xoff, yoff, zoff = a.xyz_offsets()

print a.netRot, a.relRot, xoff, yoff, zoff

b = BPdata(col, bm, "Short Side", "left end", "Conventional", 2.5, 0.375, 0.0)

xoff, yoff, zoff = b.xyz_offsets()

print b.netRot, b.relRot, xoff, yoff, zoff