/*----------------------------------------------------------------------*/ /* */ /* File : scribner.c */ /* */ /* Programmer : Peter Isensee */ /* Project : Modoc Lumber Scaler Program */ /* Compiler : Borland Turbo C V2.0 */ /* Date : 1/90 */ /* */ /* Description : scribner functions used to compute log volumes */ /* */ /*----------------------------------------------------------------------*/ /* */ /* Function : gross */ /* */ /* Description : computes the gross volume of a log based on the */ /* Scribner Decimal C Rule */ /* */ /* Arguments : length log total length */ /* dia1 one end diameter */ /* dia2 other end diameter */ /* butt butt log marker */ /* */ /* Returns : the volume of a given log based on its end */ /* diameters. This volume is computed according */ /* to the Scribner Decimal C Rule */ /* */ /* Algorithm : */ /* */ /* if neither diameter has been entered or */ /* length has not been entered or */ /* length is too large */ /* return (0) */ /* */ /* if log length is less than or equal to the max. scaling length */ /* return volume based on length and MIN(dia1, dia2) */ /* */ /* if log length is less than or equal to 2*max. scaling length */ /* divide log into two segments */ /* compute taper = MAX(dia1, dia2) - MIN(dia1, dia2) */ /* if taper is not divisible by two then add an inch */ /* if log is a butt log then taper is assigned according */ /* to log length */ /* return the sum of the volumes of the top and bottom */ /* segments based on length, the small diameter, and the */ /* taper */ /* */ /* if log length is greater than 2*max. scaling length */ /* divide log into three segments */ /* compute taper */ /* raise the total taper to a number divisible by 3 and */ /* divide. Assign this to the top seg. Distribute */ /* remainder of taper as in a two seg. log. */ /* if log is a butt log then taper is assigned according */ /* to log length */ /* return the sum of the volumes of the top, middle and */ /* bottom segments */ /* */ int gross(int length, int dia1, int dia2, char *butt) { int taper, /* total log taper */ top_taper, /* taper assigned in 3 seg. logs */ sm_dia, /* small end diameter */ lg_dia, /* large end diameter */ top_seg, /* top segment length */ mid_seg, /* middle segment length */ btm_seg; /* bottom segment length */ /* if neither diameter has been entered or length field is too large */ /* or length field has not been entered then return zero */ if (dia1 == 0 && dia2 == 0 || length > MAX_LENGTH || length == 0) return (0); /* determine large and small diameters */ sm_dia = MIN(dia1, dia2); lg_dia = MAX(dia1, dia2); /* --- SINGLE SEGMENT LOG --- */ if (length <= MAX_SCALING_LENGTH) return (vol(length, lg_dia)); /* --- TWO SEGMENT LOG --- */ else if (length <= 2*MAX_SCALING_LENGTH) { /* divide log into two segments */ btm_seg = logdivision[length-(MAX_SCALING_LENGTH+1)][0]; top_seg = logdivision[length-(MAX_SCALING_LENGTH+1)][1]; if (*butt != SPACE && *butt != NULLCHAR) { /* butt log */ taper = (length < 27) ? 2 : 4; sm_dia = lg_dia; } else { /* non-butt log */ taper = lg_dia - sm_dia; if (taper % 2 == 1) taper++; } /* return the sum of the volumes of the top and bottom segments */ return (vol(top_seg, sm_dia) + vol(btm_seg, sm_dia + taper/2)); } /* --- THREE SEGMENT LOG --- */ else { /* divide log into three segments */ btm_seg = logdivision[length-(MAX_SCALING_LENGTH+1)][0]; mid_seg = logdivision[length-(MAX_SCALING_LENGTH+1)][1]; top_seg = logdivision[length-(MAX_SCALING_LENGTH+1)][2]; if (*butt != SPACE && *butt != NULLCHAR) { /* butt log */ taper = (length < 47) ? 4 : 6; sm_dia = lg_dia; } else { /* non-butt log */ taper = lg_dia - sm_dia; } /* raise the total taper to a number divisible by 3 and divide. */ /* This is the amount of taper assigned to the top segment. */ /* Distribute the remainder of the taper as in a two-segment log */ top_taper = taper; while (top_taper % 3 != 0) top_taper++; taper -= top_taper/3; if (taper % 2 == 1) taper++; /* return the sum of the volumes of the top, middle, */ /* and bottom segments */ return (vol(top_seg, sm_dia) + vol(mid_seg, sm_dia + top_taper/3) + vol(btm_seg, sm_dia + top_taper/3 + taper/2)); } /* end else */ } /* end gross */ /*----------------------------------------------------------------------*/ /* */ /* Function : vol */ /* */ /* Description : computes the volume of a single log segment */ /* based on the segment length and diameter */ /* */ /* Arguments : length segment length */ /* dia segment diameter */ /* */ /* Returns : the volume of a log segment */ /* */ /* Notes : this function utilizes an array of Scribner */ /* table factors to compute volumes. Before */ /* returning the volume it is rounded to the */ /* nearest tens place. */ /* */ int vol(int length, int dia) { /* logs having diameters 6" through 11" have a separate diameter */ /* factor for lengths 1' thru 15' and 16' thru 20' */ if ((length > 15 && length < 32) && (dia > 5 && dia < 12)) return (ROUND((int)(length * factor16[dia-6]))); else return (ROUND((int)(length * factor[dia-1]))); } /*----------------------------------------------------------------------*/ /* */ /* Function : net */ /* */ /* Description : computes the net volume of a log based on the */ /* Scribner Decimal C Rule */ /* */ /* Arguments : gross gross volume of the log */ /* length log total length */ /* dia1 one end diameter */ /* dia2 other end diameter */ /* butt butt log marker */ /* seg#_l seg. # length defect */ /* seg#_d seg. # diameter defect */ /* seg#_s seg. # square defect */ /* seg#_g seg. # grade */ /* */ /* Returns : the net volume of a given log based on its end */ /* diameters. This volume is computed according */ /* to the Scribner Decimal C Rule */ /* */ /* Algorithm : */ /* */ /* if gross volume equals zero */ /* return (0) */ /* */ /* if none of the defect fields has been entered and none of the */ /* log segments are cull */ /* return (0); */ /* */ /* if log length is less than or equal to the max. scaling length */ /* return volume based on length - length defect and */ /* MAX(dia1, dia2) - diameter defect and square defect */ /* */ /* if log length is less than or equal to 2*max. scaling length */ /* divide log into two segments */ /* compute taper = MAX(dia1, dia2) - MIN(dia1, dia2) */ /* if taper is not divisible by two then add an inch */ /* if log is a butt log then taper is assigned according */ /* to log length */ /* return the sum of the volumes of the top and bottom */ /* segments based on length, the small diameter, the */ /* taper, and the defects of the segment */ /* */ /* if log length is greater than 2*max. scaling length */ /* divide log into three segments */ /* compute taper */ /* raise the total taper to a number divisible by 3 and */ /* divide. Assign this to the top seg. Distribute */ /* remainder of taper as in a two seg. log. */ /* if log is a butt log then taper is assigned according */ /* to log length */ /* return the sum of the volumes of the top, middle and */ /* bottom segments */ /* */ int net(int gross, int length, int dia1, int dia2, char *butt, int seg1_l, int seg1_d, int seg1_s, char *seg1_g, int seg2_l, int seg2_d, int seg2_s, char *seg2_g, int seg3_l, int seg3_d, int seg3_s, char *seg3_g) { int taper, /* total log taper */ top_taper, /* taper assigned in 3 seg. logs */ sm_dia, /* small end diameter */ lg_dia, /* large end diameter */ top_seg, /* top segment length */ mid_seg, /* middle segment length */ btm_seg, /* bottom segment length */ top_vol, /* top segment volume */ mid_vol, /* middle segment volume */ btm_vol; /* bottom segment volume */ /* if the gross volume is zero then net volume is zero */ if (gross == 0) return(0); /* if none of the defect fields has been entered and no segments are */ /* CULL logs, then the net volume is the same as the gross volume */ if (seg1_l==0 && seg1_d==0 && seg1_s==0 && strcmpi(seg1_g, CULL)!=0 && seg2_l==0 && seg2_d==0 && seg2_s==0 && strcmpi(seg2_g, CULL)!=0 && seg3_l==0 && seg3_d==0 && seg3_s==0 && strcmpi(seg3_g, CULL)!=0) return(gross); /* determine large and small diameters */ sm_dia = MIN(dia1, dia2); lg_dia = MAX(dia1, dia2); /* --- SINGLE SEGMENT LOG --- */ if (length <= MAX_SCALING_LENGTH) if (strcmpi(seg1_g, CULL) == 0) return (0); else { top_vol = vol(length-seg1_l, lg_dia-seg1_d) - 10*seg1_s; if (top_vol > 0) return (top_vol); else return (0); } /* --- TWO SEGMENT LOG --- */ else if (length <= 2*MAX_SCALING_LENGTH) { /* divide log into two segments */ btm_seg = logdivision[length-(MAX_SCALING_LENGTH+1)][0]; top_seg = logdivision[length-(MAX_SCALING_LENGTH+1)][1]; if (*butt != SPACE && *butt != NULLCHAR) { /* butt log */ taper = (length < 27) ? 2 : 4; sm_dia = lg_dia; } else { /* non-butt log */ taper = lg_dia - sm_dia; if (taper % 2 == 1) taper++; } /* compute volume of bottom segment */ if (strcmpi(seg1_g, CULL) == 0) btm_vol = 0; else btm_vol = vol(btm_seg-seg1_l, sm_dia + taper/2 - seg1_d) - 10*seg1_s; /* compute volume of top segment */ if (strcmpi(seg2_g, CULL) == 0) top_vol = 0; else top_vol = vol(top_seg-seg2_l, sm_dia - seg2_d) - 10*seg2_s; /* return the sum of the volumes of the top and bottom segments */ if (top_vol + btm_vol > 0) return (top_vol + btm_vol); else return (0); } /* --- THREE SEGMENT LOG --- */ else { /* divide log into three segments */ btm_seg = logdivision[length-(MAX_SCALING_LENGTH+1)][0]; mid_seg = logdivision[length-(MAX_SCALING_LENGTH+1)][1]; top_seg = logdivision[length-(MAX_SCALING_LENGTH+1)][2]; if (*butt != SPACE && *butt != NULLCHAR) { /* butt log */ taper = (length < 47) ? 4 : 6; sm_dia = lg_dia; } else { /* non-butt log */ taper = lg_dia - sm_dia; } /* raise the total taper to a number divisible by 3 and divide. */ /* This is the amount of taper assigned to the top segment. */ /* Distribute the remainder of the taper as in a two-segment log */ top_taper = taper; while (top_taper % 3 != 0) top_taper++; taper -= top_taper/3; if (taper % 2 == 1) taper++; /* compute volume of bottom segment */ if (strcmpi(seg1_g, CULL) == 0) btm_vol = 0; else btm_vol = vol(btm_seg-seg1_l, sm_dia+top_taper/3+taper/2-seg1_d) - 10*seg1_s; /* compute volume of middle segment */ if (strcmpi(seg2_g, CULL) == 0) mid_vol = 0; else mid_vol = vol(mid_seg-seg2_l, sm_dia + top_taper/3 - seg2_d) - 10*seg2_s; /* compute volume of top segment */ if (strcmpi(seg3_g, CULL) == 0) top_vol = 0; else top_vol = vol(top_seg-seg3_l, sm_dia - seg3_d) - 10*seg3_s; /* return the sum of the volumes of the top, middle, */ /* and bottom segments */ if (top_vol + mid_vol + btm_vol > 0) return (top_vol + mid_vol + btm_vol); else return (0); } /* end else */ } /* end net */