#!/usr/local/bin/perl # perl script for Bowed Baywindow Rafter Calculations for unequal overhangs use CGI::Carp qw(fatalsToBrowser); #comment out this line when your done debugging this script $|++; #dont't buffer output #use strict; # Bow window: A composite of two or more window units in a radial or bow formation # Bow windows are created using three to five windows at a shallower angle to form a smooth curved shape. # file name:: unequal-bowed-baywindow.cgi # Created on Oct 1, 2007 by Sim Ayers of SBE Builders # and Joe Bartok at http://joe.bartok.googlepages.com/bow_window_solver.htm # 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/plain\n\n" unless $content_type_printed++; &read_input(); #read user input variables if ($data{'span'} eq ""){ # hand polygon variables below for default values $span = 160; $number_of_windows = 5; $projection = 24; #25.3446; $major_pitch = 6; $show_feet_inches = 'no'; $jack_spacing = 12; $overhang = 24; } else{ $major_pitch = $data{'pitch'}; $show_feet_inches = $data{'show_feet_inches'}; $jack_spacing = $data{'spacing'}; $overhang = $data{'overhang'}; $span = $data{'span'}; $number_of_windows = $data{'number_of_windows'}; $projection = $data{'projection'}; $major_pitch_angle = $data{'major_pitch_angle'}; $window_angle = $data{'window_angle'}; } $span = 12 if($span < 12); $projection = $span/2 if(projection > $span); $major_pitch = 8 if($major_pitch < 1.0 && $major_pitch_angle < 1.0); $number_of_windows = 3 if($number_of_windows < 0); $jack_spacing = 6 if($jack_spacing < 0); #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 = (pi/180); $RAD22 = ($PIE/8); $RAD45 = ($PIE/4); $RAD90 = ($PIE/2); $RAD135 = (3*$PIE/4); $RAD180 = $PIE; $RAD225 = (5*$PIE/4); $RAD270 = (3*$PIE/2); $RAD315 = (7*$PIE/4); $RAD360 = 0; $dxf_line_count = 100; $DXF_STYLE=0; #dxf Line style $DXF_LAYER=0; #dxf file LAYER number $DXF_COLOR=0; # dxf line color $DXF_TSIZE=4.0; #dxf default dxf text size my @fascia_lengths; my @hip_runs; my @eave_angles; my @bay_angles; my @common_rafter_slope_angle; my @hip_rafter_slope_angle; my @surface_angles; my @plan_angles; my @bay_points; my @hip_points; my @jack_diff; my @fascia_points; my @common_rafter_runs_altitudes; my @common_rafter_runs_altitude_pitches; $hip_width = 1.5; $close_enough_16 = 0.0625; # 1/16 $close_enough_32 = 0.03125; # 1/32 $close_enough = 0.015625; # 1/64 $close_enough = 0.0078125; # 1/128 $close_enough = 0.00390625; # 1/256 $close_enough = 0.001953125; # 1/512 $close_enough = 0.0009765625; # 1/1024 $close_enough = 0.0000000000001; # real close $projection_precision_check = 0.000001; $projection_precision = 0.00001; # origin center in dxf document $originX = 100; $originY = 100; if($major_pitch_angle > 0.0){ $tan_Major_Pitch_Angle = tan($major_pitch_angle * $DEGREE_TO_RAD); $major_pitch = (tan($major_pitch_angle * $DEGREE_TO_RAD) ) * 12; } else{ $tan_Major_Pitch_Angle = ($major_pitch /12); $major_pitch_angle = atan($tan_Major_Pitch_Angle) * $RAD_TO_DEGREE; } $Eave_Angle = 90 * $DEGREE_TO_RAD; $Major_Slope = atan($major_pitch / 12); $cos_Major_Pitch_Angle = cos(atan($tan_Major_Pitch_Angle)); $sin_Major_Pitch_Angle = sin(atan($tan_Major_Pitch_Angle)); #$span = 120; #$number_of_windows = 7; #$projection = 24; #$overhang=0; #$window_angle = 18.024845309288192; $Number_Of_Windows = $number_of_windows; $Bowed_Window_Span = $span; $Bowed_Window_Overhang = $overhang; $Bowed_Window_Projection = $projection; $Bowed_Window_Angle = $window_angle; $Bowed_Window_Run = $Bowed_Window_Span/2; $Polygon_Cord = $Bowed_Window_Span; if($Bowed_Window_Angle > 1.0){ $Bowed_Window_Rad = $Bowed_Window_Angle * $DEGREE_TO_RAD; } else{ $Bowed_Window_Rad = solve_theta($Bowed_Window_Projection,$Bowed_Window_Span,$Number_Of_Windows); } $Bowed_Window_Central_Angle_Rad = $Bowed_Window_Rad * $Number_Of_Windows; if($Bowed_Window_Rad <= 0.01 || $Bowed_Window_Central_Angle_Rad > $PIE){ print "\n\n ERROR: unconstructible bowed baywindows with these input values."; print "\n\n Span of Bowed Bay Windows = " .convertTOfeet($Bowed_Window_Span); print "\n\n Desired Projection of Bowed Bay Windows = " .convertTOfeet($projection); print "\n\n Number of Windows = " .$Number_Of_Windows; print "\n\n Bowed Bay Window Angle Degrees = " .roundAngle($Bowed_Window_Rad * $RAD_TO_DEGREE) ."°"; print "\n\n Bowed Bay Window Angle Radians = " .roundAngle($Bowed_Window_Rad) ."°"; print "\n\n Central Arc Angle = " .roundAngle($Bowed_Window_Central_Angle_Rad * $RAD_TO_DEGREE) ."°"; exit; } $Radius = $Bowed_Window_Span /(2 * sin($Bowed_Window_Central_Angle_Rad / 2)); $Apothem = $Radius * cos($Bowed_Window_Rad / 2); $Bowed_Window_Central_Side_Angle_Rad = ($PIE - $Bowed_Window_Central_Angle_Rad) /2; $Radius_Offset = ($Bowed_Window_Span/2) * tan($Bowed_Window_Central_Side_Angle_Rad); $Bowed_Window_Wall_Length = ($Apothem * tan($Bowed_Window_Rad/2)*2); $Bowed_Window_Offset = $Apothem - $Radius_Offset; my $odd_even = $Number_Of_Windows %2; if($odd_even == 0){$Bowed_Window_Offset = $Radius - (($Bowed_Window_Span/2) * tan($Bowed_Window_Central_Side_Angle_Rad));} $Radius_Layout_Offset = ($Bowed_Window_Span/2) * tan($Bowed_Window_Central_Side_Angle_Rad); $Side_Wall_Length = ($Bowed_Window_Span/2) - $Bowed_Window_Offset; $Bowed_Window_Projection = $Bowed_Window_Offset; $Bowed_Window_Max_Rad = $Bowed_Window_Rad * (($Number_Of_Windows - 1)/2); $Polygon_Nsides = ($PIE * 2) / $Bowed_Window_Rad; $Overhang_Radius = ($Apothem + $Bowed_Window_Overhang) / cos($Bowed_Window_Rad/2); $fascia_side_length = get_triangle_SAS($Overhang_Radius,$Bowed_Window_Rad,$Overhang_Radius); $fascia_slope_angle = $Bowed_Window_Rad * (($Number_Of_Windows-1)/2); $fascia_slope_angle_2 = $RAD90 - $fascia_slope_angle; $Fascia_Offset_H = $Bowed_Window_Overhang * tan($fascia_slope_angle); $Fascia_Offset_C = ($Bowed_Window_Overhang / sin($fascia_slope_angle_2)); $Fascia_Offset_Y = $Fascia_Offset_C - $Fascia_Offset_H; $originX_2 = $originX; $originY_2 = $originY - $Apothem + ($Bowed_Window_Span/2); $rafter_run = $Bowed_Window_Span/2; $rafter_run_to_fascia = ($Bowed_Window_Span/2) + $Bowed_Window_Overhang; $Major_Run = ($Bowed_Window_Span/2) + $Bowed_Window_Overhang; $Rafter_Rise = $rafter_run * tan($Major_Slope); $Major_Rise = (($Bowed_Window_Span/2) + $Bowed_Window_Overhang) * tan($Major_Slope); $theta = (2 * $PIE) / $Polygon_Nsides; $nsides = $Polygon_Nsides; $run = $Apothem; $radius = $Radius; if($odd_even == 0){$Side_Wall_Length = $Radius_Layout_Offset - ($originY - $originY_2); } print "Bowed Bay Window Rafter Calculations with Unequal Overhang Runs"; print "\nCalculations are rounded to the nearest 1/16 inch"; print "\n\n Major Pitch = " .($major_pitch); print "\n\n Major Pitch Angle = " .roundAngle($major_pitch_angle); print "\n\n Span of Bowed Bay Windows = " .convertTOfeet($Bowed_Window_Span); print "\n\n Desired Projection of Bowed Bay Windows = " .convertTOfeet($projection); print "\n\n Major Run of Bowed Bay Windows = " .convertTOfeet($rafter_run); print "\n\n Overhang Run = " .convertTOfeet($Bowed_Window_Overhang); print "\n\n Jack Rafter Spacing = " .convertTOfeet($jack_spacing); print "\n\n Major Run From Fascia = " .convertTOfeet($rafter_run_to_fascia); print "\n\n Major Rise From Fascia = " .convertTOfeet($Major_Rise); print "\n\n Number of Windows = " .$Number_Of_Windows; print "\n\n Bowed Bay Window Angle = " .roundAngle($Bowed_Window_Rad * $RAD_TO_DEGREE) ."°"; print "\n\n"; print "\n\n Number of Segmented Sides of Circle = " .floor($Polygon_Nsides); print "\n\n Central Arc Angle = " .roundAngle($Bowed_Window_Central_Angle_Rad * $RAD_TO_DEGREE) ."°"; print "\n\n Radius of Arc = " .convertTOfeet($Radius); print "\n\n Radius Layout Offset = " .convertTOfeet($Radius_Layout_Offset); print "\n\n Apothem of Arc Bowed Bay Window Wall = " .convertTOfeet($Apothem); print "\n\n Bowed Bay Window Wall Length = " .convertTOfeet($Bowed_Window_Wall_Length); print "\n\n Bowed Bay Window Wall Angle = " .roundAngle($Bowed_Window_Rad * $RAD_TO_DEGREE) ."°"; print "\n\n Side Wall Length = " .convertTOfeet($Side_Wall_Length); print "\n\n Bowed Windows Calculated Projection = " .convertTOfeet($Bowed_Window_Offset); # text file with dxf header information $DXF_HEADER_FILE = "dxf_header.txt"; # text file to save dxf drawing to $DXF_File="unequal-bowed-baywindow.dxf"; #load dxf header file $dxf_header = get_dxf_header_file($DXF_HEADER_FILE); open(FILE, ">$DXF_File") || die("$DXF_File: Can't open because ($!)."); # add dxf header information to dxf output file print FILE "$dxf_header\n0\n"; $x1 = $originX; $y1 = $originY; $radius3 = $Overhang_Radius; $start_angle = $RAD270 - ($Bowed_Window_Central_Angle_Rad/2)- ($Bowed_Window_Rad); $end_angle = $RAD270 + ($Bowed_Window_Central_Angle_Rad/2) + ($Bowed_Window_Rad); $sfx2 = $originX + $radius * cos(($theta ) + $start_angle); $sfy2 = $originY + $radius * sin(($theta ) + $start_angle); $sfx22 = $originX + $radius3 * cos(($theta ) + $start_angle); $sfy22 = $originY + $radius3 * sin(($theta ) + $start_angle); $nsides = $Number_Of_Windows; $left_x2 = $radius * cos(($theta * 1) + $start_angle); $bottom_y2 = $radius * sin(($theta * 1) + $start_angle); # draw rafters at back wall -- left fascia to right fascia line dxf_line($originX - $rafter_run - $Bowed_Window_Overhang,$originY_2,$originX + $rafter_run + $Bowed_Window_Overhang,$originY_2); # draw left side wall dxf_line($left_x2 + $originX,$bottom_y2+ $originY,$left_x2 + $originX,$originY_2); my $point_x = $left_x2 + $originX; my $point_y = $bottom_y2+ $originY; # draw wall lines for($i=1; $i<$nsides+2; $i++){ $x2 = $radius * cos(($theta * $i) + $start_angle); $y2 = $radius * sin(($theta * $i) + $start_angle); $x2 += $originX; $y2 += $originY; push(@bay_points,"$x2,$y2"); dxf_line($x2,$y2,$sfx2,$sfy2); # wall line $sfx2 = $x2; $sfy2 = $y2; } #right wall line dxf_line($x2,$y2,$x2,$originY_2); push(@bay_points,"$x2,$y2"); my $center_i = floor($Number_Of_Windows/2)+1; $y2 = $radius * sin(($theta * $center_i) + $start_angle); $y2 += $originY; $Bowed_Window_DXF_Projection = abs($point_y - $y2); print "\n\n Bowed Windows Actual Projection = " .convertTOfeet($Bowed_Window_DXF_Projection); my $check = abs($Bowed_Window_DXF_Projection - $Bowed_Window_Offset); if($check > $projection_precision_check){ print "\n\n Bowed Window Projection Precision Check FAILED by: " .convertTOfeet($check); } # draw polygon hip runs for($i=1; $i<=$nsides+1; $i++){ $x2 = $radius * cos(($theta * $i) + $start_angle); $y2 = $radius * sin(($theta * $i) + $start_angle); $x2 += $originX; $y2 += $originY; dxf_line_dashed($x1,$y1,$x2,$y2); } # draw bowed bay window hip rafter runs to fascia line $x2 = $left_x2 + $originX - $Bowed_Window_Overhang; $y2 = $fascia_y1; print "\n\n"; print "\n\n Hip rafter runs to fascia"; $Bowed_Window_Central_Side_Angle_Rad = atan($Side_Wall_Length / ($Bowed_Window_Span/2)); $start_angle = $RAD180 + $Bowed_Window_Central_Side_Angle_Rad; $theta = ($RAD180 - ($Bowed_Window_Central_Side_Angle_Rad*2))/$Number_Of_Windows; $theta2 = $theta; $Arc_Overhang = ($Bowed_Window_Overhang / cos( $Bowed_Window_Central_Side_Angle_Rad)); $radius3 = $radius + $Arc_Overhang; ($bx,$by) = split(",",$bay_points[0],2); ($bx2,$by2) = split(",",$bay_points[1],2); $slope = abs(atan(($by2 - $by) / ($bx2 - $bx))); $slope2 = $RAD180 - ($slope + $Bowed_Window_Central_Side_Angle_Rad + $RAD90); $bay_overhang = ($Arc_Overhang * cos( $slope2)); $bi = 1; for($i=0; $i<=$nsides; $i++){ ($bx,$by) = split(",",$bay_points[$i],2); if($originX_2 - $bx == 0){$slope = tan($RAD90);} else{ $slope = (($originY_2 - $by) / ($originX_2 - $bx));} if($slope < 0){$theta = atan( $slope) + $RAD360;} else{$theta = atan( $slope) + $RAD180;} $r = get_distance($originX_2,$originY_2,$bx,$by); $radius3 = $r + $Arc_Overhang; $x2 = $radius3 * cos(($theta)); $y2 = $radius3 * sin(($theta)); $x2 += $originX_2; $y2 += $originY_2; dxf_line($originX_2,$originY_2,$x2,$y2); push(@fascia_points,"$x2,$y2"); $r = get_distance($originX_2,$originY_2,$x2,$y2); print "\n\n Hip run # $bi = " .convertTOfeet($r); push(@hip_runs,$r); $bi ++; } print "\n\n"; # left side fascia line ($bx,$by) = split(",",$fascia_points[0],2); dxf_line($bx,$by,$bx,$originY_2); $r = get_distance($bx,$by,$bx,$originY_2); print "\n\n"; print "\n\n Side Fascia Length = " .convertTOfeet($r); push(@fascia_lengths,$r); $bi = 1; # draw fascia line for($i=0; $i<$nsides; $i++){ ($x1,$y1) = split(",",$fascia_points[$i],2); ($x2,$y2) = split(",",$fascia_points[$i+1],2); $r = get_distance($x1,$y1,$x2,$y2); next unless $r > 0; print "\n\n Fascia Length # $bi = " .convertTOfeet($r); push(@fascia_lengths,$r); dxf_line($x1,$y1,$x2,$y2); # fascia line $sfx2 = $x2; $sfy2 = $y2; $bi++; } dxf_line($sfx2,$sfy2,$sfx2,$originY_2); # right side fascia line $r = get_distance($sfx2,$sfy2,$sfx2,$originY_2); push(@fascia_lengths,$r); print "\n\n Side Fascia Length = " .convertTOfeet($r); print "\n\n"; $str= "ENDSEC\n0\nEOF"; print FILE $str; close FILE; print "\n\n Major Common run to fascia = " .convertTOfeet($Major_Run); my $common_run_str = "\n\n Major Common run to plate = " .convertTOfeet($Major_Run-$Bowed_Window_Overhang); ($A,$B,$C) = get_triangle_angles($Major_Run+$Bowed_Window_Overhang,$hip_runs[0],$fascia_lengths[0]); $hip_right_run = $Bowed_Window_Overhang / sin($B); $hip_right_run_to_plate = $hip_runs[0] - $hip_right_run; $mc_A = scalene_triangle_altitudes($hip_right_run_to_plate,$B); my $common_run_altitudes_str = "\n\n Major Common run to plate = " .convertTOfeet($mc_A); my $altitudes_str_saved = $common_run_altitudes_str; for($i=1; $i<(scalar(@hip_runs)); $i++){ my ($ma1,$mb1,$mc1) = scalene_triangle_medians($hip_runs[$i-1],$hip_runs[$i],$fascia_lengths[$i]); ($A,$B,$C) = get_triangle_angles($hip_runs[$i-1],$hip_runs[$i],$fascia_lengths[$i]); $hip_right_run = $Arc_Overhang; $hip_left_run = $Arc_Overhang; $hip_right_run_to_plate = $hip_runs[$i] - $hip_right_run; $hip_left_run_to_plate = $hip_runs[$i-1] - $hip_left_run; $side_C = get_triangle_SAS($hip_left_run_to_plate,$C,$hip_right_run_to_plate); ($ma,$mb,$mc) = scalene_triangle_medians($hip_left_run_to_plate,$hip_right_run_to_plate,$side_C); print "\n\n King hip rafter run to fascia Bay # $i = " .convertTOfeet($mc1); $common_run_str .= "\n\n King hip rafter run to plate Bay # $i = " .convertTOfeet($mc); } print "\n\n"; print "\n\n King hip rafter runs to plate"; print $common_run_str; print "\n\n"; push(@eave_angles,$RAD180 - $fascia_slope_angle_2); for($i=1; $i<$nsides; $i++){ push(@eave_angles,$PIE - ($Bowed_Window_Rad )); } push(@eave_angles,$RAD180 - $fascia_slope_angle_2); print "\n\n Plan Angles"; my($A,$B,$C) = get_triangle_angles($rafter_run_to_fascia,$hip_runs[0],$fascia_lengths[0]); ($ma1,$mb1,$run_to_fascia) = scalene_triangle_medians($rafter_run_to_fascia,$hip_runs[0],$fascia_lengths[0]); $hip_right_run = $Arc_Overhang; $hip_right_run_to_plate = $hip_runs[0] - $hip_right_run; push(@hip_points,"$hip_right_run_to_plate,$C"); print "\n\n Side Plan Angle A = " .roundAngle($A * $RAD_TO_DEGREE) ."°"; print "\n\n Side Plan Angle C = " .roundAngle($C* $RAD_TO_DEGREE) ."°"; print "\n\n Side Plan Angle B = " .roundAngle($B * $RAD_TO_DEGREE) ."°"; print "\n\n Side Eave Angle = " .roundAngle($eave_angles[0] * $RAD_TO_DEGREE) ."°"; $Major_Plan_Angle = $B; #$Hip_Slope_Angle = atan(tan($Major_Slope) * sin ($Major_Plan_Angle)); $Hip_Slope_Angle = atan($Major_Rise / $hip_runs[0]); $major_rafter_length = $Major_Run / cos($Major_Slope); $hip_length_to_fascia = $hip_runs[0] / cos($Hip_Slope_Angle); $hip_overhang_run = $Arc_Overhang; my $hip_overhang_run_saved = $hip_overhang_run; $rafter_overhang_length = $Bowed_Window_Overhang / cos($Major_Slope); $rafter_to_plate = ($Major_Run-$Bowed_Window_Overhang) / cos($Major_Slope); $hip_overhang_length = $hip_overhang_run / cos($Hip_Slope_Angle); $hip_length_to_plate = $hip_length_to_fascia - $hip_overhang_length; push(@common_rafter_slope_angle,$Major_Slope); push(@hip_rafter_slope_angle,$Hip_Slope_Angle); my $angles_major = $A ."," . $B; push(@plan_angles,$angles_major); my $angles_major_swap = $B ."," . $A; my $hip_points_swap = $hip_right_run_to_plate ."," . $C; my $jack_rafter = convertTOfeet(($jack_spacing * tan($B)) / cos($Major_Slope)); my $jack_diff_saved = "Major Jack Rafter Length Difference = $jack_rafter"; push(@jack_diff,$jack_diff_saved); $Major_Common_str = "\n\n Major Common Slope Angle = " .roundAngle($Major_Slope * $RAD_TO_DEGREE) ."°"; #print "\n\n Major Common run To Plate = " .convertTOfeet($Major_Run-$Bowed_Window_Overhang); #print "\n\n Major Common run To Fascia= " .convertTOfeet($Major_Run); $Major_Common_str .= "\n\n Major Common Rafter Length To Plate= " .convertTOfeet($rafter_to_plate); $Major_Common_str .= "\n\n Major Common Rafter Length To Fascia = " .convertTOfeet($major_rafter_length); $Major_Common_str .= "\n\n Major Common Rafter Overhang Length = " .convertTOfeet($rafter_overhang_length); my $Hip_Rafter_str = "\n\n Hip Slope Angle # 1 = " .roundAngle($Hip_Slope_Angle * $RAD_TO_DEGREE) ."°"; #print "\n\n Side Hip run To Plate = " .convertTOfeet($hip_right_run_to_plate); #print "\n\n Side Hip run To Fascia = " .convertTOfeet($hip_runs[0]); $Hip_Rafter_str .= "\n\n Hip Rafter Length To Plate # 1 = " .convertTOfeet($hip_length_to_plate); $Hip_Rafter_str .= "\n\n Hip Rafter Length To Fascia # 1 = " .convertTOfeet($hip_length_to_fascia); $Hip_Rafter_str .= "\n\n Hip Rafter Overhang Run # 1 = " .convertTOfeet($hip_overhang_run); $Hip_Rafter_str .= "\n\n Hip Rafter Overhang Length # 1 = " .convertTOfeet($hip_overhang_length); my $Bay_Layout_str; $Major_Common_str .="\n\n"; $Hip_Rafter_str .= "\n\n"; print "\n\n"; $bi = 1; $hi = 2; $x_offset = 0; $y_offset = 0; for($i=1; $i<(scalar(@hip_runs)); $i++){ ($A,$B,$C) = get_triangle_angles($hip_runs[$i-1],$hip_runs[$i],$fascia_lengths[$i]); ($A2,$B2,$C2) = get_triangle_angles($hip_runs[$i],$hip_runs[$i+1],$fascia_lengths[$i+1]); ($ma1,$mb1,$minor_run_to_fascia) = scalene_triangle_medians($hip_runs[$i-1],$hip_runs[$i],$fascia_lengths[$i]); $hip_left_run = $Arc_Overhang; $hip_right_run = $Arc_Overhang; $hip_overhang_run = $Arc_Overhang; $hip_right_run_to_plate = $hip_runs[$i] - $hip_right_run; $hip_left_run_to_plate = $hip_runs[$i-1] - $hip_left_run; push(@hip_points,"$hip_right_run_to_plate,$C"); $side_C = get_triangle_SAS($hip_left_run_to_plate,$C,$hip_right_run_to_plate); ($ma,$mb,$minor_run_to_plate) = scalene_triangle_medians($hip_left_run_to_plate,$hip_right_run_to_plate,$side_C); $in_out_str = "inside of hips"; $mc_run_to_fascia = scalene_triangle_altitudes($hip_runs[$i],$B) ; $mc_A = scalene_triangle_altitudes($hip_runs[$i]- $Arc_Overhang,$B) ; if($i < floor($Number_Of_Windows/2)+1){ $in_out = $hip_runs[$i-1] * cos($A);} else{$in_out = $hip_runs[$i] * cos($B);} $in_out_str = "outside of hips" if($in_out > $fascia_lengths[$i]); $Minor_Slope_2 = $Major_Rise / $mc_run_to_fascia; $Minor_Slope_Angle_2 = atan($Minor_Slope_2); $common_run_altitudes_str .= "\n\n King Common rafter run to plate ($in_out_str) Bay # $bi = " .convertTOfeet($mc_A); $common_run_altitude_pitches_str .= "\n\n King Common rafter angle Bay # $bi = " .roundAngle($Minor_Slope_Angle_2 * $RAD_TO_DEGREE) ."°"; print "\n\n Plan Angle A Bay # $bi = " .roundAngle($A * $RAD_TO_DEGREE) ."°"; print "\n\n Plan Angle C Bay # $bi = " .roundAngle($C* $RAD_TO_DEGREE) ."°"; print "\n\n Plan Angle B Bay # $bi = " .roundAngle($B * $RAD_TO_DEGREE) ."°"; print "\n\n Eave Angle Bay # $bi = " .roundAngle($eave_angles[$i] * $RAD_TO_DEGREE) ."°"; $Minor_Slope = $Major_Rise / $minor_run_to_fascia; $Minor_Slope_Angle = atan($Minor_Slope); push(@common_rafter_slope_angle,$Minor_Slope_Angle); my $angles = $A ."," . $B; push(@plan_angles,$angles); $jack_pitch_angle = roundAngle2($Minor_Slope_Angle_2 * $RAD_TO_DEGREE) ."°"; $jack_run = abs($jack_spacing * tan($A)); $jack_run1 = convertTOfeet($jack_run); $jack_rafter = convertTOfeet($jack_run / cos($Minor_Slope_Angle_2)); $jack_rafter = "unconstructable - jack run is longer than king common run" if($jack_run >= $hip_left_run_to_plate); push(@jack_diff,"Bay # $bi Left Side Jack Rafter (run $jack_run1)(pitch $jack_pitch_angle) Length Difference = $jack_rafter"); $jack_run = abs($jack_spacing * tan($B)); $jack_run2 = convertTOfeet($jack_run); $jack_rafter = convertTOfeet($jack_run / cos($Minor_Slope_Angle_2)); $jack_rafter = "unconstructable - jack run is longer than king common run" if($jack_run >= $hip_right_run_to_plate); push(@jack_diff,"Bay # $bi Right Side Jack Rafter (run $jack_run2) (pitch $jack_pitch_angle)Length Difference = $jack_rafter"); $Minor_Plan_Angle = $B; #$Hip_Slope_Angle = atan($Minor_Slope * sin ($Minor_Plan_Angle)); $Hip_Slope_Angle = atan($Major_Rise / $hip_runs[$i]); push(@hip_rafter_slope_angle,$Hip_Slope_Angle); $rafter_length_to_fascia = $minor_run_to_fascia / cos($Minor_Slope_Angle); $hip_length_to_fascia = $hip_runs[$i] / cos($Hip_Slope_Angle); $rafter_overhang_run = $minor_run_to_fascia - $minor_run_to_plate; $rafter_overhang_length = $rafter_overhang_run / cos($Minor_Slope); $rafter_to_plate_length = $minor_run_to_plate / cos($Minor_Slope_Angle); $hip_overhang_length = $hip_overhang_run / cos($Hip_Slope_Angle); $hip_length_to_plate = $hip_length_to_fascia - $hip_overhang_length; $x_offset = abs($Bowed_Window_Wall_Length * cos($Bowed_Window_Max_Rad - ($Bowed_Window_Rad * ($i-1)))); $y_offset = abs($Bowed_Window_Wall_Length * sin($Bowed_Window_Max_Rad - ($Bowed_Window_Rad * ($i-1)))); $xx_offset += $x_offset; if($xx_offset > $rafter_run){$yy_offset -= $y_offset;} else{$yy_offset += $y_offset;} $yyy_offset = abs($yy_offset); $Bay_Slope_Angle = abs($Bowed_Window_Max_Rad - ($Bowed_Window_Rad * ($i-1))); if($Bowed_Window_Max_Rad - ($Bowed_Window_Rad * ($i-1)) == 0){ $x_offset = 0; $y_offset = $Bowed_Window_Offset; $Bay_Slope_Angle = 0; } $Major_Common_str .= "\n\n King Hip Rafter Slope Angle Bay # $bi = " .roundAngle($Minor_Slope_Angle * $RAD_TO_DEGREE) ."°"; #print "\n\n Minor Common Rafter Run To Plate Bay # $bi = " .convertTOfeet($minor_run_to_plate); #print "\n\n Minor Common Rafter Run To Fascia Bay # $bi = " .convertTOfeet($minor_run_to_fascia); $Major_Common_str .= "\n\n King Hip Rafter Length To Plate Bay # $bi = " .convertTOfeet($rafter_to_plate_length); $Major_Common_str .= "\n\n King Hip Rafter Length To Fascia Bay # $bi = " .convertTOfeet($rafter_length_to_fascia); $Major_Common_str .= "\n\n King Hip Rafter Overhang Length Bay # $bi = " .convertTOfeet($rafter_overhang_length); $Hip_Rafter_str .= "\n\n Hip Slope Angle # $hi = " .roundAngle($Hip_Slope_Angle * $RAD_TO_DEGREE) ."°"; $Hip_Rafter_str .= "\n\n Hip Rafter Run To Plate # $hi = " .convertTOfeet($hip_right_run_to_plate); $Hip_Rafter_str .= "\n\n Hip Run To Fascia # $hi = " .convertTOfeet($hip_runs[$i]); $Hip_Rafter_str .= "\n\n Hip Rafter Length To Plate # $hi = " .convertTOfeet($hip_length_to_plate); $Hip_Rafter_str .= "\n\n Hip Rafter Length To Fascia # $hi = " .convertTOfeet($hip_length_to_fascia); $Hip_Rafter_str .= "\n\n Hip Rafter Overhang Run # $hi = " .convertTOfeet($hip_overhang_run); $Hip_Rafter_str .= "\n\n Hip Rafter Overhang Length # $hi = " .convertTOfeet($hip_overhang_length); $Bay_Layout_str .= "\n\n Bay Window X Offset # $bi = " .convertTOfeet($x_offset); $Bay_Layout_str .= "\n\n Bay Window Y Offset # $bi = " .convertTOfeet($y_offset); $Bay_Layout_str .= "\n\n Bay Window X Layout Offset # $bi = " .convertTOfeet($xx_offset); $Bay_Layout_str .= "\n\n Bay Window Y Layout Offset # $bi = " .convertTOfeet($yyy_offset); $Bay_Layout_str .= "\n\n Bay Window Angle Bay # $bi = " .roundAngle($Bay_Slope_Angle * $RAD_TO_DEGREE) ."°"; $Major_Common_str .="\n\n"; $Hip_Rafter_str .= "\n\n"; $Bay_Layout_str .= "\n\n"; $hi++; $bi++; print "\n\n"; } $common_run_altitudes_str .= $altitudes_str_saved; push(@jack_diff,$jack_diff_saved); push(@plan_angles,$angles_major_swap); #push(@hip_points,$hip_points_swap); print "\n\n King Hip Rafter Lengths"; print $Major_Common_str; print "\n\n"; print "\n\n Hip Rafter Lengths"; print $Hip_Rafter_str; print "\n\n"; print "\n\n Angles On the surface of the roof"; my($A,$B,$C) = get_triangle_angles($rafter_run_to_fascia,$hip_runs[0],$fascia_lengths[0]); $Major_Plan_Angle = $B; $Hip_Slope_Angle = atan(tan($Major_Slope) * sin ($Major_Plan_Angle)); $Major_Rafter_length = $Major_Run / cos($Major_Slope); $hip_length = $hip_runs[0] / cos($Hip_Slope_Angle); ($A,$B,$C) = get_triangle_angles($Major_Rafter_length,$hip_length,$fascia_lengths[0]); push(@surface_angles,$C); print "\n\n Side Roof Surface Angle A = " .roundAngle($A * $RAD_TO_DEGREE) ."°"; print "\n\n Side Roof Surface Angle C = " .roundAngle($C* $RAD_TO_DEGREE) ."°"; print "\n\n Side Roof Surface Angle B = " .roundAngle($B * $RAD_TO_DEGREE) ."°"; print "\n\n"; $bi = 1; for($i=1; $i<(scalar(@hip_runs)); $i++){ ($A,$B,$C) = get_triangle_angles($hip_runs[$i-1],$hip_runs[$i],$fascia_lengths[$i]); $Minor_run = get_triangle_SAS($hip_runs[$i-1],$A,$fascia_lengths[$i]/2); $Minor_Slope = $Major_Rise / $Minor_run; $Minor_Slope_Angle = atan($Minor_Slope); $Minor_Plan_Angle_1 = $A; $Minor_Plan_Angle_2 = $B; $Hip_Slope_Angle_1 = atan($Minor_Slope * sin ($Minor_Plan_Angle_1)); $Hip_Slope_Angle_2 = atan($Minor_Slope * sin ($Minor_Plan_Angle_2)); $hip_length_1 = $hip_runs[$i-1] / cos($Hip_Slope_Angle_1); $hip_length_2 = $hip_runs[$i] / cos($Hip_Slope_Angle_2); ($A,$B,$C) = get_triangle_angles($hip_length_1,$hip_length_2,$fascia_lengths[$i]); push(@surface_angles,$C); print "\n\n Roof Surface Angle A Bay # $bi = " .roundAngle($A * $RAD_TO_DEGREE) ."°"; print "\n\n Roof Surface Angle C Bay # $bi = " .roundAngle($C* $RAD_TO_DEGREE) ."°"; print "\n\n Roof Surface Angle B Bay # $bi = " .roundAngle($B * $RAD_TO_DEGREE) ."°"; $bi++; print "\n\n"; } ($A,$B,$C) = get_triangle_angles($Major_Rafter_length,$hip_length,$fascia_lengths[0]); push(@surface_angles,$C); print "\n\n"; $bi = 1; $bi2 = 2; my $jack_rafter_str; my $sheathing_str; for($i=0; $i<(scalar(@hip_runs)); $i++){ ($angle_A,$angle_B) = split(",",$plan_angles[$i],2); ($angle_A2,$angle_B2) = split(",",$plan_angles[$i+1],2); $str = "Left Side of Hip # $bi"; $test = backing_angles($common_rafter_slope_angle[$i],$hip_rafter_slope_angle[$i],$angle_B,$surface_angles[$i],$str); $sheathing_str .= sheathing_angles($common_rafter_slope_angle[$i],$angle_B,$str); $jack_rafter_str .= jack_rafter_side_cuts($common_rafter_slope_angle[$i],$angle_B,$str); $str = "Right Side of Hip # $bi"; $common_rafter_slope_angle[$i+1] = $Major_Slope if($common_rafter_slope_angle[$i+1] <= 0.00); $test = backing_angles($common_rafter_slope_angle[$i+1],$hip_rafter_slope_angle[$i],$angle_A2,$surface_angles[$i+1],$str); $sheathing_str .= sheathing_angles($common_rafter_slope_angle[$i+1],$angle_A2,$str); $jack_rafter_str .= jack_rafter_side_cuts($common_rafter_slope_angle[$i+1],$angle_A2,$str); my $hip_adjustment = hip_drop ($eave_angles[$i],$common_rafter_slope_angle[$i],$common_rafter_slope_angle[$i],$hip_width); print "\n\n Hip Rafter Drop Adjustment for Hip # $bi = " .convertTOfeet($hip_adjustment); $bi2 ++; $bi++; print "\n\n"; } print "\n\n Roof Sheathing Angles"; print $sheathing_str; print "\n\n"; print "\n\n Jack Rafter Side Cut Angles"; print $jack_rafter_str; print "\n\n"; print "\n\n Jack Rafter Length Difference"; for($i=0; $i<(scalar(@jack_diff)); $i++){ print "\n\n$jack_diff[$i]"; } print "\n\n"; print "\n\n Bay Window Layout"; print $Bay_Layout_str; print "\n\n"; =head for($i=0; $i<(scalar(@bay_points)); $i++){ print "\n$i bay points = " .$bay_points[$i]; } print "\n\n"; my $theta2 = 0; for($i=0; $i<(scalar(@hip_points)); $i++){ ($run,$angle) = split(",",$hip_points[$i],2); print "\n$i hip points = " .$run .", " .($angle * $RAD_TO_DEGREE); $theta2 += $angle; } print "\ntheta = " .($theta2 * $RAD_TO_DEGREE); print "\n\n Hip Rafter Layout at bay window plate line"; print "\n\n"; $theta2 = $PIE; $bi = 1; for($i=0; $i<(scalar(@hip_points)); $i++){ ($bx,$by) = split(",",$bay_points[$i],2); ($run,$angle) = split(",",$hip_points[$i],2); $theta2 += $angle; $x2 = $run * cos(($theta2)); $y2 = $run * sin(($theta2)); $x2 += $originX_2; $y2 += $originY_2; #print "\n$i hip points = " .$x2 ."," .$y2; $offset = get_distance($bx,$by,$x2,$y2); print "\nHip Rafter # $bi offset from bay corner = " .convertTOfeet($offset); my $slope = getLineSlope($x2,$y2,$bx,$by); $slope_angle = atan($slope); #print "\n$i $slope_angle = " .roundAngle($slope_angle * $RAD_TO_DEGREE); $bi++; } print "\n\nSee the auto generated DXF file for the direction of offset\nfrom each of the bay corners for Hip Rafter Layout Offset"; =cut print "\n\n"; print "\n\nKing common rafter runs clarification.\n"; print "\nEach bay window roof plan triangle, formed by the fascia line and 2 bay hips, is a scalene triangle."; print "\nWhich means all 3 sides of the triangle are unequal in length. Because of the unequal sides of the triangle the normal"; print "\nking common rafter run is often located outside of the bay hips when drawn at a 90° to the fascia line."; print "\n\nOPTION # 1: King Hip Rafter"; print "\nKing hip rafter runs for each bay are located in the center of the bays hip rafters."; print "\nThis is the same as the median of a triangle.\nThe king hip rafter runs are not located in the center of the baywindow wall framing."; print "\nThe king hip rafters are not at 90° degrees to the plate line or fascia line."; print "\nBy locating the king hip rafters in the center of the bays hip rafters,"; print "\neach king hip rafter will be centered in the fascia line of each bay."; print "\n\nOPTION # 2: King Common Rafter \nOr if you prefer to use the altitude of each bay for king common rafter runs."; print "\nYou can use the information below to calculate the king common rafter lengths."; print "\n\nKing Common Runs using the Altitude of Bays for Runs"; print "\n"; print $common_run_altitudes_str; print "\n\n"; print "\n\nKing Common Slope Angles using the Altitude of Bays for Runs"; print "\n"; print $common_run_altitude_pitches_str; print "\n\n"; exit; ################################### # library sub routines follow ################################### #=============================================================================# sub getLineSlope { my $x1 = $_[0]; my $y1 = $_[1]; my $x2 = $_[2]; my $y2 = $_[3]; return 0 if($x2 == $x1 && $y2 != $y1); return 0 if($y2 == $y1); return 0 unless(abs($x2 - $x1) > 0.01); return 0 unless(abs($y2 - $y1) > 0.01); my $slope = ($y2 - $y1) / ($x2 - $x1); return $slope; } # http://ca.geocities.com/web_sketches/framing_math_notes/hip_valley_roof_ratios/hip_valley_roof_ratios.html #=============================================================================# sub jack_rafter_side_cuts{ my ($rafter_pitch_angle,$plan_angle,$str_txt) = @_; return 0 if($rafter_pitch_angle == 0 || $plan_angle == 0 ); my $angle = abs(atan (cos($rafter_pitch_angle) / tan($plan_angle))); return "\n\n Jack Rafter Side Cut Angle $str_txt = " .roundAngle($angle * $RAD_TO_DEGREE); } #=============================================================================# sub sheathing_angles{ my ($rafter_pitch_angle,$plan_angle,$str_txt) = @_; return 0 if($rafter_pitch_angle == 0 || $plan_angle == 0 ); my $angle = abs(atan (tan($plan_angle) / cos($rafter_pitch_angle))); return "\n\n Sheathing Angle $str_txt = " .roundAngle($angle * $RAD_TO_DEGREE); } #=============================================================================# =head http://www.gomath.com/algebra/angleradian.php The radian measure of the angle x is the ratio of arc length to radius. 9° x (pie ÷ 180) = 1*pie/20 10° x (pie ÷ 180) = 1*pie/18 12° x (pie ÷ 180) = 1*pie/15 15° x (pie ÷ 180) = 1*pie/12 22.5° x (pie ÷ 180) = 11.25*pie/90 45° x (pie ÷ 180) = 1*pie/4 90° x (pie ÷ 180) = 1*pie/2 arclength = (theta * pie * radius) ÷ 180 chordlength = 2 * radius * sin(theta/2) d = Apothem chordlength = 2 * sqrt(radius² - d²) =cut #=============================================================================# # rafter_pitch_angle = pitch in Radians # hip_pitch_angle = hip pitch in Radians # plan_angle = plan angle in Radians # roof_surface_angle in Radians sub backing_angles{ my ($rafter_pitch_angle,$hip_pitch_angle,$plan_angle,$roof_surface_angle,$str_txt) = @_; # print "\n\n rafter_pitch_angle $str_txt = " .roundAngle($rafter_pitch_angle * $RAD_TO_DEGREE); # print "\n\n hip_pitch_angle $str_txt = " .roundAngle($hip_pitch_angle * $RAD_TO_DEGREE); # print "\n\n plan_angle $str_txt = " .roundAngle($plan_angle * $RAD_TO_DEGREE); # print "\n\n roof_surface_angle $str_txt = " .roundAngle($roof_surface_angle * $RAD_TO_DEGREE); return 0 if($rafter_pitch_angle == 0 || $hip_pitch_angle == 0 || $plan_angle == 0 || $roof_surface_angle==0); my $tan_Pitch_Angle = tan($rafter_pitch_angle); my $sin_Hip_Pitch_Angle = sin($hip_pitch_angle); my $Hip_Pitch_RAD = $hip_pitch_angle; my $Plan_Angle_RAD = $plan_angle; my $Surface_Angle_RAD = $roof_surface_angle; my $tan_Plan_Angle_RAD = tan($Plan_Angle_RAD); my $Frieze_Block_Angle = atan (sin (atan($tan_Pitch_Angle)) / $tan_Plan_Angle_RAD); if($Frieze_Block_Angle < 0){ $Frieze_Block_Angle = abs($Frieze_Block_Angle); } $Frieze_Block_Bevel_Angle = atan (sin ($Frieze_Block_Angle / $tan_Pitch_Angle)); my $angle_on_the_stick = abs(atan(sin($Surface_Angle_RAD) / tan($Frieze_Block_Angle))); my $saw_miter_angle = abs(atan(tan($Frieze_Block_Angle) / sin($Surface_Angle_RAD))); my $saw_blade_bevel = abs(atan(sin($angle_on_the_stick) / tan($Surface_Angle_RAD))); print "\n\n Frieze Block Angle $str_txt = " .roundAngle($Frieze_Block_Angle * $RAD_TO_DEGREE); print "\n\n Frieze Block Bevel Angle $str_txt = " .roundAngle($Frieze_Block_Bevel_Angle * $RAD_TO_DEGREE); print "\n\n Wall Angle On The Stick $str_txt = " .roundAngle($angle_on_the_stick * $RAD_TO_DEGREE); print "\n\n Wall Saw Miter Angle $str_txt = " .roundAngle($saw_miter_angle * $RAD_TO_DEGREE); print "\n\n Wall Saw Blade Bevel $str_txt = " .roundAngle($saw_blade_bevel * $RAD_TO_DEGREE); #Backing Angle = arctan (sin Hip Pitch Angle ÷ tan Plan Angle) $Backing_Angle = atan (sin($Hip_Pitch_RAD) / tan($Plan_Angle_RAD)); if($Backing_Angle < 0){ $Backing_Angle = abs($Backing_Angle); } print "\n\n Hip Rafter Backing Angle $str_txt = " .roundAngle($Backing_Angle * $RAD_TO_DEGREE); return 0; } #=============================================================================# sub hip_drop{ my ($roof_eave_angle,$major_pitch_angle,$minor_pitch_angle,$hip_width) = @_; my $Eave_Angle = $roof_eave_angle * $DEGREE_TO_RAD; my $tan_Major_Pitch_Angle = tan($major_pitch_angle * $DEGREE_TO_RAD); my $major_pitch = (tan($major_pitch_angle * $DEGREE_TO_RAD) ) * 12; my $tan_Minor_Pitch_Angle = tan($minor_pitch_angle * $DEGREE_TO_RAD); my $minor_pitch = (tan($minor_pitch_angle * $DEGREE_TO_RAD) ) * 12; my $sin_Eave_Angle = sin ($Eave_Angle); my $cos_Eave_Angle = cos ($Eave_Angle); my $MajorPitch_divide_by_MinorPitch = $tan_Major_Pitch_Angle / $tan_Minor_Pitch_Angle; my $MinorPitch_divide_by_MajorPitch = $tan_Minor_Pitch_Angle / $tan_Major_Pitch_Angle; my $tan_Major_Plan_Angle = ($sin_Eave_Angle / ($MajorPitch_divide_by_MinorPitch + $cos_Eave_Angle)); my $tan_Minor_Plan_Angle = ($sin_Eave_Angle / ($MinorPitch_divide_by_MajorPitch + $cos_Eave_Angle)); my $Major_Plan_Angle_RAD = atan($tan_Major_Plan_Angle); my $Minor_Plan_Angle_RAD = atan($tan_Minor_Plan_Angle); if($roof_eave_angle > 90 && $Major_Plan_Angle_RAD < 0){ $Major_Plan_Angle_RAD = $PIE + $Major_Plan_Angle_RAD; } if($roof_eave_angle > 90 && $Minor_Plan_Angle_RAD < 0){ $Minor_Plan_Angle_RAD = $PIE + $Minor_Plan_Angle_RAD; } my $sin_Major_Plan_Angle = sin($Major_Plan_Angle_RAD); my $sin_Minor_Plan_Angle = sin($Minor_Plan_Angle_RAD); my $Major_Plan_Angle_Unit_Rise = $tan_Major_Plan_Angle; my $Minor_Plan_Angle_Unit_Rise = $tan_Minor_Plan_Angle; my $Hip_Unit_Rise_Run = 12 / $sin_Major_Plan_Angle; my $Major_Side_Shift_Unit_Ratio = $Major_Plan_Angle_Unit_Rise / ($Major_Plan_Angle_Unit_Rise + $Minor_Plan_Angle_Unit_Rise); my $Minor_Side_Shift_Unit_Ratio = $Minor_Plan_Angle_Unit_Rise / ($Major_Plan_Angle_Unit_Rise + $Minor_Plan_Angle_Unit_Rise); my $Major_Side_Shift = 0.5 * ($Major_Side_Shift_Unit_Ratio - $Minor_Side_Shift_Unit_Ratio); my $Minor_Side_Shift = 0.5 * ($Minor_Side_Shift_Unit_Ratio - $Major_Side_Shift_Unit_Ratio); my $Unit_Hip_Drop = $major_pitch / ($Hip_Unit_Rise_Run * ($Major_Plan_Angle_Unit_Rise + $Minor_Plan_Angle_Unit_Rise)); my $Hip_Drop = $hip_width * $Unit_Hip_Drop; return $Hip_Drop; } #=============================================================================# sub solve_theta{ my ($projection,$span,$bays) = @_; my $half_span = 0.5 * $span; my $theta = 0.01; my $limit = 0.5 * ($bays - 1); my $ratio = 10.0; my $difference = 10; my $numerator = 0; my $denominator = 0; my $i = 0; my $odd_bay_add = 0.5; my $odd_even = $bays %2; if($odd_even == 0){ $odd_bay_add = 0.0; $limit = 0.5 * $bays; } OUTTER: for($si=0; $si<1000; $si++){ my $n_sum = 0; my $d_sum = 0; my $n_calc = 0; my $d_calc = 0; do{ for (my $n=1; $n<=$limit; $n++){ if($odd_even > 0){ $n_calc = cos($n * $theta); $d_calc = sin($n * $theta); }else{ $n_calc = cos(((($n * 2)-1)* $theta)/2); $d_calc = sin(((($n * 2)-1)* $theta)/2); } $n_sum = $n_sum + $n_calc; $d_sum = $d_sum + $d_calc; } if($d_sum == 0){last OUTTER;} $numerator = $half_span /($odd_bay_add + $n_sum); $denominator = $projection / $d_sum; $ratio = $numerator / $denominator; $difference = $denominator - $numerator; $i++; $theta = $theta / $ratio; if($ratio < 1){next;} }while($difference > 0); if(abs($difference) < 0.0000000000001){last;} } my $central_angle = $theta * $bays; $radius = $span /(2 * sin($central_angle / 2)); my $apothem = $radius * cos($theta / 2); my $side_angle = ($PIE - $central_angle) /2; my $offset = $apothem - (($span/2) * tan($side_angle)); if($odd_even == 0){$offset = $radius - (($span/2) * tan($side_angle));} $theta = 0 if(abs($projection - $offset) > $projection_precision); #print "\n\ntheta $i = " .($theta * $RAD_TO_DEGREE); #print "\n\noffset = " .($offset); #print "\n\n"; return ($theta); } #=============================================================================# sub check_projection{ my ($Bowed_Window_Projection,$Bowed_Window_Span,$Number_Of_Windows,$Bowed_Window_Rad ) = @_; my $Bowed_Window_Central_Angle_Rad = $Bowed_Window_Rad * $Number_Of_Windows; my $Radius = $Bowed_Window_Span /(2 * sin($Bowed_Window_Central_Angle_Rad / 2)); my $Apothem = $Radius * cos($Bowed_Window_Rad / 2); my $Bowed_Window_Central_Side_Angle_Rad = ($PIE - $Bowed_Window_Central_Angle_Rad) /2; my $Radius_Offset = ($Bowed_Window_Span/2) * tan($Bowed_Window_Central_Side_Angle_Rad); #my $Bowed_Window_Wall_Length = ($Apothem * tan($Bowed_Window_Rad/2)*2); my $Bowed_Window_Offset = $Apothem - $Radius_Offset; #my $Side_Wall_Length = ($Bowed_Window_Span/2) - $Bowed_Window_Offset; my $diff = $Bowed_Window_Projection - $Bowed_Window_Offset; return $diff; } #=============================================================================# sub scalene_triangle_altitudes{ my ($side,$sin_opposite) = @_; return (0) if($side == 0); my $h = $side * sin($sin_opposite); return ($h); } #=============================================================================# =head http://mathforum.org/dr.math/faq/formulas/faq.triangle.html scalene triangle medians angles of Medians of Scalene triangle ma = sqrt(2b²+2c²-a²)/2 mb = sqrt(2a²+2c²-b²)/2 mc = sqrt(2a²+2b²-c²)/2 =cut #=============================================================================# sub scalene_triangle_medians{ my ($side_a,$side_b,$side_c) = @_; return (0,0,0) if($side_a == 0 || $side_b == 0 || $side_c == 0); my $ma = sqrt((2*sq($side_b)) + (2*sq($side_c)) - sq($side_a)) / 2; my $mb = sqrt((2*sq($side_a)) + (2*sq($side_c)) - sq($side_b)) / 2; my $mc = sqrt((2*sq($side_b)) + (2*sq($side_a)) - sq($side_c)) / 2; return ($ma,$mb,$mc); } #=============================================================================# sub sq_sqrt{ my ($side) = @_; return sqrt($side * $side); } #=============================================================================# sub get_distance{ my ($x1,$y1,$x2,$y2) = @_; my $A = abs($x2 - $x1); my $B = abs($y2 - $y1); my $C = sqrt(sq($A) + sq($B)); #print "\n\n A = " .$A; #print "\n\n B = " .$B; return $C; } #=============================================================================# sub get_triangle_SAS{ my ($side_b,$angle_C,$side_a) = @_; my $side_c = 0; return $side_c if($side_a == 0 || $side_b == 0 || $angle_C == 0); my $side_c = (sq($side_a) + sq($side_b)) - (2 * $side_a * $side_b * cos($angle_C)); return sqrt($side_c); } #=============================================================================# sub get_triangle_angles{ my ($side_a,$side_b,$side_c) = @_; return (0,0,0) if($side_a == 0 || $side_b == 0 || $side_c == 0); my $cos_A = (sq($side_b) + sq($side_c) - sq($side_a)) / (2 * $side_b * $side_c); my $cos_B = (sq($side_a) + sq($side_c) - sq($side_b)) / (2 * $side_a * $side_c); my $cos_C = (sq($side_a) + sq($side_b) - sq($side_c)) / (2 * $side_a * $side_b); my $angle_A = acos($cos_A); my $angle_B= acos($cos_B); my $angle_C= acos($cos_C); return ($angle_B,$angle_A,$angle_C); } #=============================================================================# sub get_distance{ my ($x1,$y1,$x2,$y2) = @_; my $A = abs($x2 - $x1); my $B = abs($y2 - $y1); my $C = sqrt(sq($A) + sq($B)); #print "\n\n A = " .$A; #print "\n\n B = " .$B; return $C; } #=============================================================================# =head SAS -- Side, included Angle, and Side (Law of Cosines) SSA -- Two sides, and a non-included Angle (Law of Sines) AAS -- Any two angles, and one side (Law of Sines) C /\ / \ b / \a / h \ A /________\B c cos A = (b² + c² - a²) / 2*b*c cos B = (a² + c² - b²) / 2*a*c cos C = (a² + b² - c²) / 2*a*b a² = (b² + c²) - 2*b*c * cos A b² = (a² + c²) - 2*a*c * cos B c² = (a² + b²) - 2*a*b * cos C =cut #=============================================================================# sub get_triangle_height{ my ($side_a,$side_b,$side_c) = @_; my $cos_A = (sq($side_b) + sq($side_c) - sq($side_a)) / (2 * $side_b * $side_c); my $cos_B = (sq($side_a) + sq($side_c) - sq($side_b)) / (2 * $side_a * $side_c); my $cos_C = (sq($side_a) + sq($side_b) - sq($side_c)) / (2 * $side_a * $side_b); my $angle_A = acos($cos_A); my $height = sin($angle_A) * $side_b; return $height; } #=============================================================================# sub get_triangle_C_angle{ my ($side_a,$side_b,$side_c) = @_; my $cos_C = (sq($side_a) + sq($side_b) - sq($side_c)) / (2 * $side_a * $side_b); my $angle_A = acos($cos_C); return $angle_A; } #=============================================================================# sub sq{ my ($side) = @_; return ($side * $side); } #=============================================================================# sub get_octagon_run{ my ($radius) = @_; my $face_wall = (sin(22.5 * $DEGREE_TO_RAD)* $radius) * 2; my $face_wall_half = $face_wall / 2; my $span = ($face_wall_half / tan(22.5 * $DEGREE_TO_RAD)) * 2; my $run = $span / 2; return $run; } #=============================================================================# sub deg2rad { my $degreeNum = $_[0]; my $radianNum = $degreeNum * ($PIE / 180); return $radianNum; } #=============================================================================# sub rad2deg { my $radianNum = $_[0]; my $degreeNum = $radianNum * (180 / $PIE); return $degreeNum; } #=============================================================================# sub dxf_line { my ($x1,$y1,$x2,$y2) = @_; $color=0; $dxf_line_count++; $str = sprintf("LINE\n5\n%dD\n8\n%d\n6\nCONTINOUS\n62\n%d\n10\n%lf\n20\n%lf\n30\n0.0\n11\n%lf\n21\n%lf\n31\n0.0\n0\n", $dxf_line_count,$DXF_LAYER,$DFX_COLOR,$x1,$y1,$x2,$y2); print FILE $str; } #=============================================================================# sub dxf_line_dashed { my ($x1,$y1,$x2,$y2) = @_; $color=12; $dxf_line_count++; $str = sprintf("LINE\n5\n%dD\n8\n%d\n6\nACAD_ISO02W100\n62\n%d\n10\n%lf\n20\n%lf\n30\n0.0\n11\n%lf\n21\n%lf\n31\n0.0\n0\n", $dxf_line_count,$DXF_LAYER,$color,$x1,$y1,$x2,$y2); print FILE $str; } #=============================================================================# 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) = @_; my $str = sprintf("%.14f",$decimal); return $str 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); } $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("%.14f",$angle); return $str unless $show_feet_inches eq 'yes'; $str = sprintf("%.5f",$angle); return $str; } #=============================================================================# sub roundAngle2{ 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; }