#!/usr/local/bin/perl # perl script for Equal Pitch Bay Window Rafter Chart Calculations use CGI::Carp qw(fatalsToBrowser); #comment out this line when your done debugging this script $|++; #dont't buffer output #use strict; # file name:: baywindow html table.cgi # Created on Sunday, July 15, 2007 by Sim Ayers of SBE Builders # get latest version of this script at http://www.sbebuilders.com ################################################### # You are free to customize this script as you wish. # DISCLAIMER # The information and code provided is provided 'as is' without # warranty of any kind, either express or implied. In no event # shall the Company SBE Builders be liable for any damages whatsoever # including direct, indirect, incidental, consequential, loss of # business profits or special damages, even if the author has been # advised of the possibility of such damages. # DO NOT USE THIS SCRIPT UNLESS YOU CAN FULLY AGREE WITH THIS # DISCLAIMER. # copyright(C) 2007 ################################################### my ($content_type_printed,%data,$back_wall,$projection,$face_wall,$pitch,$show_feet_inches); # print out perl headers to browser print "Content-type: text/html\n\n" unless $content_type_printed++; &read_input(); #read user input variables #while(($key,$value)= each %data ){print "
$key...$value\n";}#print all key=value pairs if ($data{'back_wall'} eq ""){ # hand edit baywindow variables below for default values $back_wall = 96; $projection = 24; $face_wall = 48; $show_feet_inches = 'yes'; } else{ $back_wall = $data{'back_wall'}; $projection = $data{'projection'}; $face_wall = $data{'face_wall'}; $show_feet_inches = $data{'show_feet_inches'}; } #Global symbols # http://perldoc.perl.org/Math/Complex.html use Math::Complex qw(:trig); use POSIX qw(ceil floor); $PIE = 3.14159265358979323846; $RAD_TO_DEGREE = (180/pi); $DEGREE_TO_RAD = ($PIE/180); $RAD_TO_DEGREE45 = (0.785398163397448309616); $half_the_thickness_of_the_hips = 0.75; $start = 3; $stop = 16; my @DatabaseFieldNames=("Common Rafter Pitch", "Common Rafter Run", "Common Rafter Rise", "Common Rafter Pitch Angle","Common Rafter Length" , "Bay Hip Rafter Angle","Bay Hip Rafter Bevel Angle", "Bay Hip Rafter Run","Bay Hip Rafter Unit Run","Bay Hip Rafter Length", "Wall Hip Rafter Angle", "Wall Hip Rafter Run","Wall Hip Rafter Unit Run", "Wall Hip Rafter Length", "Wall Hip Rafter Bevel Angle", "Bay Hip Plan Angle" ,"Frieze Block Angle", "Frieze Block Bevel Angle", "Bay Hip Rafter Backing Angle", "Bay Hip Rafter Drop","Wall Hip Rafter Drop"); my $cr = "\n"; $table_cells = ""; my @FieldNames; foreach $key(@DatabaseFieldNames){ $key =~ s/[\r\n\"'\cM]//g; $key =~ s/^\s+//; $key =~ s/\s+$//; $table_cells .= "" .$key ."\n"; $key =~ s/ /_/g; push(@FieldNames,$key); } $table_rows = "" .$table_cells ."\n"; # back wall length must be > or = face wall length $back_wall = $face_wall if($back_wall < $face_wall); # projection must be < or = face wall length $projection = $face_wall if($projection > $face_wall); if($back_wall > $face_wall) { $projection_offset = ($back_wall - $face_wall) /2; } else { $projection_offset = 0;} # get geometry angles for baywindow $run = $projection; if($projection_offset > 0){ $projection_wall_angle_deg = $RAD_TO_DEGREE * atan($projection / $projection_offset); } else { $projection_wall_angle_deg = 90; } $projection_offset_wall_angle_deg = 90 - $projection_wall_angle_deg; $interior_wall_angle_deg = 90 + $projection_offset_wall_angle_deg; $bay_hip_rafter_run_bisect_angle_deg = $interior_wall_angle_deg / 2; $poly_halfangle_deg = 90 - $bay_hip_rafter_run_bisect_angle_deg; #print "\n\n poly_halfangle_deg = " .roundAngle($poly_halfangle_deg); $poly_angle_deg = $poly_halfangle_deg * 2; #print "\n\n poly_angle_deg = " .roundAngle($poly_angle_deg); $theta = $DEGREE_TO_RAD * $bay_hip_rafter_run_bisect_angle_deg; $bay_hip_rafter_run_offset = $projection / tan($theta); $opposite = $bay_hip_rafter_run_offset*tan($theta); for($i=$start; $i<=$stop; $i++){ my @row; $table_cells = ""; $pitch = $i; $pitch_angle = $RAD_TO_DEGREE * atan($pitch / 12); $Major_Pitch = atan($pitch / 12); $Minor_Pitch = atan($pitch / 12); $common_rafter_rise = $run * ($pitch / 12); $common_rafter_length = $run / cos(atan($pitch / 12)); $bay_hip_rafter_run = $run / sin($theta); $bay_hip_rafter_angle = atan($common_rafter_rise / $bay_hip_rafter_run); $bay_hip_rafter_unit_run = (12 / sin($theta)); $bay_hip_rafter_unit_run_hypot = (12 / sin($theta)) / cos($bay_hip_rafter_angle); $bay_hip_rafter_length = $bay_hip_rafter_run / cos($bay_hip_rafter_angle); $bay_hip_rafter_bevel_angle = $poly_halfangle_deg; $wall_hip_rafter_run = $projection_offset + $bay_hip_rafter_run_offset; $wall_hip_rafter_angle = atan($common_rafter_rise / $wall_hip_rafter_run); $wall_hip_rafter_length = $wall_hip_rafter_run / cos($wall_hip_rafter_angle); $wall_hip_rafter_bevel_angle = $projection_wall_angle_deg; $wall_hip_rafter_unit_run = (12 / sin($projection_wall_angle_deg * $DEGREE_TO_RAD)); $exterior_angle_deg = $DEGREE_TO_RAD * (360 - $interior_wall_angle_deg); if($projection_offset > 0){ $projection_wall_length = $projection_offset / cos($projection_wall_angle_deg * $DEGREE_TO_RAD); } else{$projection_wall_length = $projection;} $row{'Common_Rafter_Run'} = convertTOfeet($projection); $row{'Common_Rafter_Pitch'} = roundAngle($pitch); $row{'Common_Rafter_Pitch_Angle'} = roundAngle($pitch_angle); $row{'Common_Rafter_Rise'} = convertTOfeet($common_rafter_rise); $row{'Common_Rafter_Length'} = convertTOfeet($common_rafter_length); $row{'Bay_Hip_Rafter_Angle'}= roundAngle($bay_hip_rafter_angle * $RAD_TO_DEGREE); $row{'Bay_Hip_Rafter_Bevel_Angle'} = roundAngle($bay_hip_rafter_bevel_angle); $row{'Bay_Hip_Rafter_Run'} = convertTOfeet($bay_hip_rafter_run); $row{'Bay_Hip_Rafter_Unit_Run'} = roundAngle($bay_hip_rafter_unit_run); $row{'Bay_Hip_Rafter_Length'} = convertTOfeet($bay_hip_rafter_length); $row{'Wall_Hip_Rafter_Angle'} = roundAngle($wall_hip_rafter_angle * $RAD_TO_DEGREE); $row{'Wall_Hip_Rafter_Run'} = convertTOfeet($wall_hip_rafter_run); $row{'Wall_Hip_Rafter_Unit_Run'}= roundAngle($wall_hip_rafter_unit_run); $row{'Wall_Hip_Rafter_Length'} = convertTOfeet($wall_hip_rafter_length); $row{'Wall_Hip_Rafter_Bevel_Angle'} = roundAngle($wall_hip_rafter_bevel_angle); $Major_Side_Plan_Angle = abs(atan (sin $exterior_angle_deg / ($Major_Pitch / $Minor_Pitch + cos $exterior_angle_deg))); if($projection_offset > 0){$Major_Side_Plan_Angle = $bay_hip_rafter_run_bisect_angle_deg * $DEGREE_TO_RAD;} # work for 90 walls only # $Frieze_Block_Angle = atan(cos((90.00 - ($Major_Pitch* $RAD_TO_DEGREE))* $DEGREE_TO_RAD)); $Frieze_Block_Angle = atan (sin ($Major_Pitch) / tan($Major_Side_Plan_Angle)); $Frieze_Block_Bevel_Angle = atan (sin ($Frieze_Block_Angle) / tan ($Major_Pitch)); $row{'Bay_Hip_Plan_Angle'} = roundAngle($Major_Side_Plan_Angle * $RAD_TO_DEGREE); $row{'Frieze_Block_Angle'} = roundAngle($Frieze_Block_Angle * $RAD_TO_DEGREE); $row{'Frieze_Block_Bevel_Angle'} = roundAngle($Frieze_Block_Bevel_Angle * $RAD_TO_DEGREE); $Backing_Angle = acos (cos($pitch_angle * $DEGREE_TO_RAD) / cos ($bay_hip_rafter_angle)); $row{'Bay_Hip_Rafter_Backing_Angle'} = roundAngle($Backing_Angle * $RAD_TO_DEGREE); $bay_hip_rafter_drop = ($pitch * ($half_the_thickness_of_the_hips / tan($bay_hip_rafter_run_bisect_angle_deg * $DEGREE_TO_RAD))/$bay_hip_rafter_unit_run); $row{'Bay_Hip_Rafter_Drop'} = convertTOfeet($bay_hip_rafter_drop); # if the $projection_wall_angle_deg == 45 then sin of 45 = 1 and Wall Hip Rafter Drop = half_the_thickness_of_the_hips * pitch/16.97 or * tan(hip_angle) $wall_hip_rafter_drop = ($pitch * ($half_the_thickness_of_the_hips / tan($projection_wall_angle_deg * $DEGREE_TO_RAD))/$wall_hip_rafter_unit_run); $row{'Wall_Hip_Rafter_Drop'} = convertTOfeet($wall_hip_rafter_drop); foreach $key(@FieldNames){ $td = $row{$key}; $table_cells .= "" .$td ."\n"; } $table_rows .= "" .$table_cells ."\n"; } print " "; print "

\n
Back Wall Length = " .convertTOfeet($back_wall); print "\n
Face Wall length = " .convertTOfeet($face_wall); print "\n
Projection of Bay Window = " .convertTOfeet($projection); print "\n
Projection Offset = " .convertTOfeet($projection_offset); print "\n
Projection Wall Length = " .convertTOfeet($projection_wall_length); print "\n
Projection Wall Angle = " .roundAngle($projection_wall_angle_deg); print "\n
Projection Offset Wall Angle = " .roundAngle($projection_offset_wall_angle_deg); print "\n
Interior Wall Angle = " .roundAngle($interior_wall_angle_deg); print "\n
Bay Hip Rafter Run Bisect Angle = " .roundAngle($bay_hip_rafter_run_bisect_angle_deg); print "\n

\n\n"; print "\n"; print "$table_rows"; print "\n
\n"; exit; ################################### # library sub routines follow ################################### #=============================================================================# sub escape_string { my($esc) = @_; $esc =~ s/([^a-zA-Z0-9_\-.])/uc sprintf("%%%02x",ord($1))/eg; $esc =~ s/ /+/g; return $esc; } #=============================================================================# sub get_dxf_header_file{ my($file)=shift; my $header; open(FH, "<$file") || die("$file: Can't open because ($!)."); while(){ $header .= $_; } close(FH); return $header; } #=============================================================================# sub hypot{ my ($x,$y) = @_; my $s = sqrt( $x* $x + $y * $y); return $s; } #=============================================================================# sub convertTOfeet{ my ($decimal) = @_; return $decimal unless $show_feet_inches eq 'yes'; #print "\n inches decimal = " .$decimal; my $wholefeet = floor($decimal/12); my $wholeinch = floor($decimal - ($wholefeet*12)); my $decimalfrac = ($decimal*1) - floor($decimal); my ($frac1,$frac2,$frac_str); $frac2 = 16; if ($decimalfrac >= 0.9774) # 15/16 = 0.9375 { $wholeinch++; $decimalfrac = 0.00; if($wholeinch == 12) { $wholefeet++; $wholeinch = 0; } } if ($decimalfrac > 0.0001) { $frac1 = $decimalfrac * $frac2; my $wholefrac = floor($decimalfrac * $frac2); $frac1 = ceil($decimalfrac * $frac2); $frac1 = 15 if($frac1 == 16); ($frac1,$frac2) = check_frac($frac1,$frac2); $frac_str = sprintf(" %d/%d",$frac1,$frac2); } my $str = sprintf("%d'-%d%s''", $wholefeet,$wholeinch,$frac_str); return $str; } #=============================================================================# sub check_frac{ my ($numerator ,$denominator) = @_; return (7,8) if $numerator eq 14; return (3,4) if $numerator eq 12; return (5,8) if $numerator eq 10; return (1,2) if $numerator eq 8; return (3,8) if $numerator eq 6; return (1,4) if $numerator eq 4; return (1,8) if $numerator eq 2; return ("","") if $numerator eq 0; return ("","") if $denominator eq 0; return ($numerator ,$denominator); } #=============================================================================# sub roundAngle{ my ($angle) = @_; my $str = sprintf("%.2f",$angle); return $str; } #=============================================================================# sub read_input { my($buffer) = undef; my ($item); if ($ENV{'REQUEST_METHOD'} eq 'POST') { read(STDIN,$buffer,$ENV{'CONTENT_LENGTH'}); } else { $buffer=$ENV{'QUERY_STRING'}; } $buffer = $ARGV[0] if (not $buffer); my @pairs=split(/&/,$buffer); foreach $item(@pairs) { my ($key,$content)=split (/=/,$item,2); # Split into key and value. $content =~ tr/+/ /; # Convert plus's to spaces $content =~ s/%(..)/pack("c",hex($1))/ge; # Convert %XX from hex numbers to alphanumeric $content =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; # prevent hackers from exploiting the input name $key =~ tr/+/ /; # Convert plus's to spaces $key =~ s/%(..)/pack("c",hex($1))/ge; # Convert %XX from hex numbers to alphanumeric $key =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $key =~ s/ /_/g; # get rid of attempts to insert HTML tags $content =~ s///g; # server-side-includes $content =~ s/<([^>]|\n)*>//gs; $content =~ s//>/g; # get rid of attempts to insert illegal characters $content =~ s/\\//g; # remove black slashes $content =~ s/\0//g; # remove nulls $content =~ s/[\\\&\;\`\'\"\|\*\?\~\^\[\]\{\}\$]//gs; $content =~ s/\cM/\n/g; #convert CR to LF $content =~ s/^\s+|\s+$//gs; $content = substr($content,0,4096); $data{$key} = $content; } return 1; }