1 ! FILE NAME: TRIANGLE.BAS ! AUTHOR: R.W.MCDOUGALL ! CREATION DATE: 3/18/85 ! REVISION DATE: 3/18/85 ! LOCATION: HSTC ! MAIN FRAME: VAX 11/780 ! SYSTEM: VAX/VMS V3.7 ! LANGUAGE: VAX-11 BASIC V2.2 ! DESCRIPTION: NUMERICAL CONTROL TRIANGLE !---------------------------------------------------------------------! OPTION TYPE = REAL, & SIZE = (REAL DOUBLE) EXTERNAL REAL FUNCTION MTH$SIND, & MTH$COSD, & MTH$TAND, & MTH$ASIND, & MTH$ACOSD, & MTH$ATAND !OUTPUT TO FILE NORMAL ----------------------------------------------- DEF FNG(TABPOS%,ARG) !PRINT VALUE GIVEN PRINT #2%, CR;TAB(TABPOS%);FORMAT$(ARG," ###.### "); FNEND !OUTPUT TO FILE IN PARENTHESIS --------------------------------------- DEF FNF(TABPOS%,ARG) !PRINT VALUE FOUND PRINT #2%, CR;TAB(TABPOS%);"(";FORMAT$(ARG,"###.###");")"; FNEND !OUTPUT TO SCREEN IN REVERSE VIDEO ----------------------------------- DEF FNP$(ARG)=ESC+"[7m"+FORMAT$(ARG,"###.###")+ESC+"[0m" !OUTPUT TO SCREEN NORMAL --------------------------------------------- DEF FNR$(ARG)=FORMAT$(ARG,"###.###") DEF FNI(SPOS$) !---------------------------------------------------------------------! !USER DEFINED INPUT FUNCTION: ! !Input: a screen postion for input ! !Output: a posetive real number ! !---------------------------------------------------------------------! AA=-1 UNTIL(AA>=0) !STAY IN UNTIL POSETIVE PNT=0 PRINT SPOS$;" |" !CLEAR POSITION PRINT SPOS$; !RE POSITION LINPUT #1%, AA$ !ACCEPT INPUT FOR L = 1 TO LEN(AA$) !CHECK EVERY CHARACTER AAA = ASCII(MID(AA$,L,1)) !TAKE ASCII OF Lth CHAR PRINT #99%, CHR$(AAA);"-";AAA !***DEBUG_STATEMENT*** SELECT AAA !CASE THE ASCII VAL CASE 46 !IF DECIMAL PNT = PNT+1 !COUNT IT CASE 48 TO 57 !IF NUMERIC THEN NO-OP CASE ELSE !ANYTHING ELSE PNT=2 !FORCE COUNT TOO HIGH END SELECT NEXT L IF PNT>1 !IF COUNT TOO HIG THEN AA=-1 !SET TO NEGATIVE PRINT ESC;"[16;25H"; & "POSITIVE NUMERIC INPUT REQUIRED!";BEL;BEL;BEL; PRINT #2%, CR;TAB(ERRTAB%); & "POSITIVE NUMERIC INPUT REQUIRED!"; ELSE AA=VAL(AA$) END IF NEXT FNI=AA FNEND ! ! MAINLINE: ! ! !---------------------------------------------------------------------! ! R U L E S A P P L I E D ! ! SIN(THETA) = OPPOSITE/HYPOTENUSE ! ! COS(THETA) = ADJACENT/HYPOTENUSE ! ! TAN(THETA) = OPPOSITE/ADJACENT ! ! ANGLEA + ANGLEB + ANGLEC = 180 degrees ! ! SIDEA^2 + SIDEB^2 = SIDEC^2 ! !_____________________________________________________________________! OPEN "TT:" AS FILE #1% OPEN "TRIANGLE.OUT" FOR OUTPUT AS FILE #2%, RECORDSIZE 512% !OPEN "TXI7:" AS FILE #99% ***DEBUG_STATEMENT*** OPEN "NLA0:" AS FILE #99% !***DEBUG_STATEMENT*** PRINT ESC;"[2J"; !CLEAR SCREEN PRINT ESC;"[0;0H"; !HOME CURSOR ERRTAB%=64% !TAB FOR ERRORS TO FILE TABB$ = ESC+"[22C" !POS. FOR PICTURE TABBB$ = ESC+"[11C" !POS. FOR DBL SIZE LINE PRINT ESC;"[7m"; !REVERSE VIDEO PRINT TABB$;" TRIANGLE BY R.W.MCDOUGALL " PRINT TABBB$;ESC;"#6 NUMERICAL CONTROL " PRINT TABBB$;ESC;"#6 TRIANGLE PROBLEM " PRINT TABB$;" " PRINT TABB$;" A " PRINT TABB$;" |\ " PRINT TABB$;" | \ " PRINT TABB$;" | \ " PRINT TABB$;" b | \ c " PRINT TABB$;" | \ " PRINT TABB$;" | \ " PRINT TABB$;" |_90 \ " PRINT TABB$;" C |_|_____\ B " PRINT TABB$;" a " PRINT TABB$;" Return for unknown values. " PRINT ESC;"[0m" PRINT TABBB$;"+---------+---------+---------+---------+---------+---------+" PRINT TABBB$;"| SIDE a | SIDE b | SIDE c | ANGLE A | ANGLE B | ANGLE C |" PRINT TABBB$;"| | | | | | |" PRINT TABBB$;"| | | | | | |" PRINT TABBB$;"| | | | | | |" PRINT TABBB$;"| | | | | | |" PRINT TABBB$;"| | | | | | |" PRINT TABBB$;"+---------+---------+---------+---------+---------+---------+"; PRINT #2%, " TRIANGLE BY R.W.MCDOUGALL " PRINT #2%, " NUMERICAL CONTROL TRIANGLE PROBLEM " PRINT #2%, " SIDE a SIDE b SIDE c ANGLE A ANGLE B ANGLE C " PRINT #2%, " ------ ------ ------ ------- ------- -------" SAFTAB%=01% !SET TAB POSITIONS FOR SBFTAB%=11% !OUTPUT FILE SCFTAB%=21% AAFTAB%=31% ABFTAB%=41% ACFTAB%=51% PRINT ESC;"[19;24r" !SET SCROLLING REGION ROW = 18 !INIT ROW COUNTER ANGLEC = 90 !INIT ANGLE C SIDECOUNT=1 !INIT SICE COUNTER UNTIL (ANGLECOUNT=0 AND SIDECOUNT=0) !EXIT ON ALL ZERO ENTRY SIDECOUNT,ANGLECOUNT,SIDEA,SIDEB,SIDEC,ANGLEA,ANGLEB = 0 ROW = ROW + 1 !INC ROW COUNTER IF ROW > 23 !IF ROW 23 THEN ROW = 23 !THEN SCROLL PRINT ESC;"[19;23r" !RESET SCROLLING REGION PRINT ESC;"[23;0H"; !POSITOIN CURSOR PRINT !PRINT BLANK LINE PRINT " | | | | | | |"; PRINT ESC;"[19;24r" !RESET SCROLLING REGION END IF SAPOS$=ESC+"["+NUM1$(ROW)+";14H" !SET SCREEN POSITIONS SBPOS$=ESC+"["+NUM1$(ROW)+";24H" !RELATIVE TO ROW SCPOS$=ESC+"["+NUM1$(ROW)+";34H" AAPOS$=ESC+"["+NUM1$(ROW)+";44H" ABPOS$=ESC+"["+NUM1$(ROW)+";54H" ACPOS$=ESC+"["+NUM1$(ROW)+";64H" PRINT SAPOS$; !POSTION CURSOR PRINT ACPOS$;FNR$(ANGLEC) !OUTPUT ANGLE C Y = FNG(ACFTAB%,ANGLEC) SIDEA=FNI(SAPOS$) !INPUT SIDEA IF SIDEA<>0 THEN Y = FNG(SAFTAB%,SIDEA) END IF PRINT ESC;"[16;0H";ESC;"[2K" !CLEAR ERROR WINDOW SIDEB=FNI(SBPOS$) !INPUT SIDEB IF SIDEB<>0 THEN Y = FNG(SBFTAB%,SIDEB) END IF PRINT ESC;"[16;0H";ESC;"[2K" !CLEAR ERROR WINDOW SIDEC=FNI(SCPOS$) !INPUT SIDEC IF SIDEC<>0 THEN Y = FNG(SCFTAB%,SIDEC) END IF PRINT ESC;"[16;0H";ESC;"[2K" !CLEAR ERROR WINDOW ANGLEA=FNI(AAPOS$) !INPUT ANGLEA IF ANGLEA<>0 THEN Y = FNG(AAFTAB%,ANGLEA) END IF PRINT ESC;"[16;0H";ESC;"[2K" !CLEAR ERROR WINDOW ANGLEB=FNI(ABPOS$) !INPUT ANGLEB IF ANGLEB<>0 THEN Y = FNG(ABFTAB%,ANGLEB) END IF PRINT ESC;"[16;0H";ESC;"[2K" !CLEAR ERROR WINDOW !MINIMUM 1 ANGLE AND 1 SIDE ! OR 2 SIDES SIDECOUNT = SGN(SIDEA)+SGN(SIDEB)+SGN(SIDEC) !COUNT SIDES ANGLECOUNT = SGN(ANGLEA)+SGN(ANGLEB) !COUNT ANGLES IF SIDECOUNT>0 OR ANGLECOUNT>0 !CHECK FOR SUFF INFO THEN IF (SIDECOUNT < 1 OR ANGLECOUNT <1) AND & SIDECOUNT<2 THEN PRINT ESC;"[16;26H"; & "INSUFFICIENT INFORMATION ERROR!";BEL;BEL;BEL; PRINT #2%, CR;TAB(ERRTAB%); & "INSUFFICIENT INFORMATION ERROR!"; ELSE GOSUB ANALYZE_DATA !FIND MISSING VALUES END IF END IF PRINT #2% NEXT GOTO BOT_CODE ! ! ANALYZE_DATA: ! ! !CHECK FOR AMBIGOUS SPECIFICATIONS--------------------- IF (INT(SIDEC^2+.1)<>INT(SIDEA^2+SIDEB^2+.1) AND SIDECOUNT=3) OR & (INT(ANGLEA+ANGLEB+ANGLEC+.1)<>180% AND ANGLECOUNT=2) OR & (SIDEA >= SIDEC AND SIDEA<>0 AND SIDEC<>0) OR & (SIDEB >= SIDEC AND SIDEB<>0 AND SIDEC<>0) THEN PRINT ESC;"[16;23H"; & "INVALID RIGHT TRIANGLE SPECIFICATION";BEL;BEL;BEL; PRINT #2%, CR;TAB(ERRTAB%); & "INVALID RIGHT TRIANGLE SPECIFICATION"; RETURN END IF !LOOP UNTIL ALL VALUES ARE FOUND ------------------------ UNTIL (SIDEA<>0 AND & SIDEB<>0 AND & SIDEC<>0 AND & ANGLEA<>0 AND & ANGLEB<>0) IF ANGLEA=0 !GET ANGLE A IF UNKNOWN THEN GOSUB GET_ANGLEA IF ANGLEA<>0 THEN PRINT AAPOS$;FNP$(ANGLEA) Y = FNF(AAFTAB%,ANGLEA) END IF END IF IF ANGLEB=0 !GET ANGLE B IF UNKNOWN THEN GOSUB GET_ANGLEB IF ANGLEB<>0 THEN PRINT ABPOS$;FNP$(ANGLEB) Y = FNF(ABFTAB%,ANGLEB) END IF END IF IF SIDEA=0 !GET SIDE A IF UNKNOWN THEN GOSUB GET_SIDEA IF SIDEA<>0 THEN PRINT SAPOS$;FNP$(SIDEA) Y = FNF(SAFTAB%,SIDEA) END IF END IF IF SIDEB=0 !GET SIDE B IF UNKNOWN THEN GOSUB GET_SIDEB IF SIDEB<>0 THEN PRINT SBPOS$;FNP$(SIDEB) Y = FNF(SBFTAB%,SIDEB) END IF END IF IF SIDEC=0 !GET SIDE C IF UNKNOWN THEN GOSUB GET_SIDEC IF SIDEC<>0 THEN PRINT SCPOS$;FNP$(SIDEC) Y = FNF(SCFTAB%,SIDEC) END IF END IF NEXT !CHECK FOR AMBIGOUS SPECIFICATIONS--------------------- IF (INT(SIDEC^2+.1)<>INT(SIDEA^2+SIDEB^2+.1)) OR & (INT(ANGLEA+ANGLEB+ANGLEC+.1)<>180%) OR & (SIDEA >= SIDEC) OR & (SIDEB >= SIDEC) THEN PRINT ESC;"[16;23H"; & "INVALID RIGHT TRIANGLE SPECIFICATION";BEL;BEL;BEL; PRINT #2%, CR;TAB(ERRTAB%); & "INVALID RIGHT TRIANGLE SPECIFICATION"; END IF RETURN ! ! GET_ANGLEA: ! ! PRINT #99%, "GET_ANGLEA:" !***DEBUG_STATEMENT*** IF SIDEA<>0 AND SIDEC<>0 THEN ANGLEA = MTH$ASIND(SIDEA/SIDEC) !ASIN(O/H) RETURN END IF IF SIDEB<>0 AND SIDEC<>0 THEN ANGLEA = MTH$ACOSD(SIDEB/SIDEC) !ACOS(A/H) RETURN END IF IF SIDEA<>0 AND SIDEB<>0 THEN ANGLEA = MTH$ATAND(SIDEA/SIDEB) !ATAN(O/A) RETURN END IF IF ANGLEB<>0 THEN ANGLEA=180-ANGLEB-ANGLEC !A=180-B-C RETURN END IF ANGLEA=0 RETURN ! ! GET_ANGLEB: ! ! PRINT #99%, "GET_ANGLEB:" !***DEBUG_STATEMENT*** IF SIDEB<>0 AND SIDEC<>0 THEN ANGLEB = MTH$ASIND(SIDEB/SIDEC) !ASIN(O/H) RETURN END IF IF SIDEA<>0 AND SIDEC<>0 THEN ANGLEB = MTH$ACOSD(SIDEA/SIDEC) !ACOS(A/H) RETURN END IF IF SIDEA<>0 AND SIDEB<>0 THEN ANGLEB = MTH$ATAND(SIDEB/SIDEA) !ATAN(O/A) RETURN END IF IF ANGLEA<>0 THEN ANGLEB=180-ANGLEA-ANGLEC !B=180-A-C RETURN END IF ANGLEB=0 RETURN ! ! GET_SIDEA: ! ! PRINT #99%, "GET_SIDEA:" !***DEBUG_STATEMENT*** IF SIDEB<>0 AND ANGLEA<>0 THEN SIDEA=SIDEB*MTH$TAND(ANGLEA) !O=A*TAN(ANGLEA) RETURN END IF IF SIDEB<>0 AND ANGLEB<>0 THEN SIDEA=SIDEB/MTH$TAND(ANGLEB) !A=O/TAN(ANGLEB) RETURN END IF IF SIDEC<>0 AND ANGLEA<>0 THEN SIDEA=SIDEC*MTH$SIND(ANGLEA) !O=H*SIN(ANGLEA) RETURN END IF IF SIDEC<>0 AND ANGLEB<>0 THEN SIDEA=SIDEC*MTH$COSD(ANGLEB) !A=H*COS(ANGLEB) RETURN END IF IF SIDEB<>0 AND SIDEC<>0 THEN SIDEA=SQR(SIDEC^2-SIDEB^2) !A=SQR(C^2-B^2) RETURN END IF SIDEA=0 RETURN ! ! GET_SIDEB: ! ! PRINT #99%, "GET_SIDEB:" !***DEBUG_STATEMENT*** IF SIDEA<>0 AND ANGLEA<>0 THEN SIDEB=SIDEA/MTH$TAND(ANGLEA) !A=O/TAN(ANGLEA) RETURN END IF IF SIDEA<>0 AND ANGLEB<>0 THEN SIDEB=SIDEA*MTH$TAND(ANGLEB) !O=A*TAN(ANGLEB) RETURN END IF IF SIDEC<>0 AND ANGLEA<>0 THEN SIDEB=SIDEC*MTH$COSD(ANGLEA) !A=H*COS(ANGLEA) RETURN END IF IF SIDEC<>0 AND ANGLEB<>0 THEN SIDEB=SIDEC*MTH$SIND(ANGLEB) !H=A*SIN(ANGLEB) RETURN END IF IF SIDEA<>0 AND SIDEC<>0 THEN SIDEB=SQR(SIDEC^2-SIDEA^2) !B=SQR(C^2-A^2) RETURN END IF SIDEB=0 RETURN ! ! GET_SIDEC: ! ! PRINT #99%, "GET_SIDEC:" !***DEBUG_STATEMENT*** IF SIDEA<>0 AND ANGLEA<>0 THEN SIDEC=SIDEA/MTH$SIND(ANGLEA) !H=O/SIN(ANGLEA) RETURN END IF IF SIDEA<>0 AND ANGLEB<>0 THEN SIDEC=SIDEA/MTH$COSD(ANGLEB) !H=A/COS(ANGLEB) RETURN END IF IF SIDEB<>0 AND ANGLEA<>0 THEN SIDEC=SIDEB/MTH$COSD(ANGLEA) !H=A/COS(ANGLEA) RETURN END IF IF SIDEB<>0 AND ANGLEB<>0 THEN SIDEC=SIDEB/MTH$SIND(ANGLEB) !H=O/SIN(ANGLEB) RETURN END IF IF SIDEA<>0 AND SIDEB<>0 THEN SIDEC=SQR(SIDEA^2+SIDEB^2) !C=SQR(A^2+B^2) RETURN END IF SIDEC=0 RETURN ! ! BOT_CODE: ! ! PRINT ESC;"[H"; PRINT ESC;"[0;24r"; END_MESSAGE$ = "THANKS FOR RUNNING THE TRIANGLE PROGRAM." PRINT ESC;"[J";END_MESSAGE$ PRINT #2% PRINT #2%, END_MESSAGE$ CLOSE #1%, #2%, #99% END