/*----------------------------------------------------------------------*/
/* */
/* 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 */