1 rem error in line 1045 -- last two rgb #s unknown 10 rem ** 3D Line Plotting System 20 rem ** Original from Analog Magazine Feb.84 30 rem ** Modified by R. Grokett, Jr. 11/85 40 rem ** Amiga version 1.1 100 screen 1,2,0 110 ? inverse(1) "3-D IMAGE PLOT SYSTEM" 120 ? :?:? 130 ?"Original by Tom Hudson Analog Magazine #16 February 1984" 140 ?:? 150 print"Amiga version by R.Grok ------ Dec 85" 154 ?" This is a modified version of Analog Magazine's SOLID STATES program. 156 ?"This version has NOT been fully optimized to maximize ABasiC's speed. Even" 157 ?"so, this version runs considerably faster than even the compiled Atari" 158 ?"version. Plus, this version is running with twice the resolution of the 159 ?"original. Feel free to alter the coding of this program any way you wish!" 160 DIM r$(1),A$(5),F$(20),DMA$(1),O$(1),EG$(2),IN$(1):EG$=CHR$(27) 170 XL=0:XR=639:YT=0:yB=199 180 ? at (15,23);"Press to begin "; 185 getkey a$:if a$<>chr$(13) then 185 200 scnclr 210 ? inverse(1) " 3D-PLOTS " 220 ?:?"(D)isk file or (K)eyboard input? (D or K)"; 224 getkey a$:if a$="d" or a$="D" then 1100 230 if a$="k" or a$="K" then 240 else 224 240 ?:?"How many points are there";:input PS 250 DIM X(PS),Y(PS),Z(PS),P(PS,2),VIS(PS) 260 ? "Enter X,Y,Z coordinates for each point" 270 FOR I=1 TO PS:? "POINT ";I;:INPUT Q1,Q2,Q3:X(I)=Q1:Y(I)=Q2:Z(I)=Q3:NEXT I 280 ? :? "How many LINES are there";:INPUT LS:DIM LN(LS,1),z%(3,LS) 290 ? :? "Now enter POINT information" 300 ? "for each line." 310 FOR I=1 TO LS:? :? "Line ";I:? "From POINT";:INPUT Q1:LN(I,0)=Q1:? " To POINT";:INPUT Q1:LN(I,1)=Q1:NEXT I 320 ? :? "Do you want to SAVE this object";:INPUT A$:IF A$="y" THEN 1250 330 IF A$<>"n" THEN 320 340 REM *************************** 350 REM * TIME FOR NEW PLOT * 360 REM *************************** 370 ?:?"Do you wish to (V)iew, (E)dit, or (Q)uit? (V, E, or Q)"; 374 getkey a$:if a$="v" or a$="V" then 380 else if a$="e" or a$="E" then 1340 else if a$="q" or a$="Q" then scnclr:end else 374 380 ?:?"Enter Observer location (X,Y,Z) : "; 390 ZOOM=1 400 INPUT OX,OY,OZ 410 ? :? "Enter coordinates looked at X,Y,Z" 420 input VX,VY,VZ 430 ? :? "Enter ZOOM factor (1= normal)":on error goto 430:INPUT ZOOM:on error goto 0 434 ? :? "Do you want to do an X-Y loop";:INPUT R$:IF R$<>"y" THEN 440 436 ?:? "How many degrees TOTAL ROTATION";:INPUT AN2:AN2=(AN2/360)*6.28 438 ? "How many degrees rotation per frame";:INPUT AN3:AN3=(AN3/360)*6.28 439 GOTO 2000 440 X(0)=VX:Y(0)=VY:Z(0)=VZ 450 D0=1 460 REM *************************** 470 REM * CALCULATE PERSPECTIVE * 480 REM *************************** 490 DX=VX-OX:DY=VY-OY:DZ=VZ-OZ 500 U1=SQR(DX*DX+DY*DY+DZ*DZ):IF U1=0 THEN U1=1E-06 510 CX=DX/U1:CY=DY/U1:CZ=DZ/U1 520 S3=SQR(1-CZ*CZ):S2=SQR(1-CY*CY) 530 QX=OX+D0*CX:QY=OY+D0*CY:QZ=OZ+D0*CZ 540 FOR I=0 TO PS:XW=X(I):YW=Y(I):ZW=Z(I):GOSUB 610:NEXT I 550 FOR I=0 TO PS:IF VIS(I)=0 THEN 570 560 XW=X(I):YW=Y(I):ZW=Z(I):GOSUB 610:GOSUB 670 570 NEXT I:GOTO 740 580 REM *************************** 590 REM * IS THE POINT VISIBLE? * 600 REM *************************** 610 VIS(I)=1:VCX=XW-OX:VCY=YW-OY:VCZ=ZW-OZ 620 IF DX*VCX+DY*VCY+DZ*VCZ>0 THEN RETURN 630 VIS(I)=0:RETURN 640 REM *************************** 650 REM * NOW CALC PLOT COORDS * 660 REM *************************** 670 K=D0/(VCX*CX+VCY*CY+VCZ*CZ) 680 AX=OX+K*VCX:AY=OY+K*VCY:AZ=OZ+K*VCZ 690 IF S3=0 THEN 720 700 P(I,1)=((AX-QX)*CY-(AY-QY)*CX)/S3 710 P(I,2)=(AZ-QZ)/S3:RETURN 720 P(I,1)=((QX-AX)*CZ+(AZ-QZ)*CX)/S2 730 P(I,2)=(AY-QY)/S2:RETURN 740 REM *************************** 750 REM * SCALE THE IMAGE * 760 REM *************************** 770 T=450*ZOOM:FOR I=0 TO PS 780 P(I,1)=P(I,1)*(T*2) 790 P(I,2)=P(I,2)*T 800 NEXT I 810 XAD=320-P(0,1):YAD=100-P(0,2):FOR I=1 TO PS:P(I,1)=P(I,1)+XAD:P(I,2)=P(I,2)+YAD:NEXT I 820 REM *************************** 830 REM * NOW DRAW THE IMAGE! * 840 REM *************************** 850 rgb 0,0,0,0:rgb 2,0,0,0: rgb 3,15,15,15:pena 3 860 gosub 2200 870 FOR I=1 TO LS:TV=VIS(LN(I,0))+VIS(LN(I,1)):IF TV=0 THEN 1010 880 IF TV=2 THEN 980 890 QT=0:ISAVE=I:IF VIS(LN(I,0))=0 THEN I1=LN(I,0):I2=LN(I,1):I=LN(I,0):GOTO 910 900 I1=LN(I,1):I2=LN(I,0):I=LN(I,1) 910 XT1=X(I1):YT1=Y(I1):ZT1=Z(I1):XT2=X(I2):YT2=Y(I2):ZT2=Z(I2):FV=0:FH=0 920 XW=(XT1+XT2)/2:YW=(YT1+YT2)/2:ZW=(ZT1+ZT2)/2:GOSUB 610 930 IF VIS(I)>0 THEN XT2=XW:YT2=YW:ZT2=ZW:GOTO 950 940 XT1=XW:YT1=YW:ZT1=ZW 950 QT=QT+1:IF QT<15 THEN 920 960 XW=XT2:YW=YT2:ZW=ZT2:GOSUB 610 970 GOSUB 670:P(I,1)=P(I,1)*T+XAD:P(I,2)=P(I,2)*T+YAD:VIS(I)=0:I=ISAVE 980 X1=P(LN(I,0),1):Y1=191-P(LN(I,0),2):X2=P(LN(I,1),1):Y2=191-P(LN(I,1),2):GOSUB 1550 1010 NEXT I 1012 scnclr 1015 for i%=1 to LS:draw(z%(0,i%),z%(1,i%) to z%(2,i%),z%(3,i%)):next i% 1020 rem 1035 IF FLAG THEN 2100 1040 get a$: if a$="" then 1035 1045 scnclr:rgb 0,6,8,15:rgb 2,1,8,15 1050 ?"LAST PARAMETERS:" 1060 ? :? "OBSERVER: ";OX;",";OY;",";OZ:? "VIEWPOINT:";VX;",";VY;",";VZ:? "ZOOM:";ZOOM:GOTO 340 1070 REM *************************** 1080 REM * LOAD 3-D IMAGE FILE * 1090 REM *************************** 1100 gosub 1800:CLOSE #1:?:?:? "Enter Drive: Filename to load. (df_: filename) ";:INPUT F$:on error goto 1200:OPEN "i",#1,F$:on error goto 1180 1110 INPUT #1,PS:DIM X(PS),Y(PS),Z(PS),P(PS,2),VIS(PS) 1120 FOR X=1 TO PS:INPUT #1,Q1:X(X)=Q1:NEXT X 1130 FOR X=1 TO PS:INPUT #1,Q1:Y(X)=Q1:NEXT X 1140 FOR X=1 TO PS:INPUT #1,Q1:Z(X)=Q1:NEXT X 1150 INPUT #1,LS:DIM LN(LS,1),z%(3,LS) 1160 FOR X=1 TO LS:INPUT #1,Q1:LN(X,0)=Q1:INPUT #1,Q1:LN(X,1)=Q1:NEXT X 1165 a$=" loaded." 1170 CLOSE #1:on error goto 0 1175 ?:?"File ";f$;a$:goto 340 1180 ? :? "}FILE FORMAT ERROR!":GOTO 1210 1190 ? :? "}I/O ERROR - ";err$(err):GOTO 1210 1200 ? :? "}CAN'T OPEN FILE!" 1210 ? "PRESS RETURN":INPUT IN$:clr:goto 100 1220 REM *************************** 1230 REM * SAVE 3-D IMAGE FILE * 1240 REM *************************** 1250 gosub 1800:CLOSE #1:? "Enter Drive: Filename to save. (df_: filename)";:INPUT F$:on error goto 1210:OPEN "o",#1,F$:on error goto 1190 1260 ? #1,PS 1270 FOR X=1 TO PS:? #1,X(X):NEXT X 1280 FOR X=1 TO PS:? #1,Y(X):NEXT X 1290 FOR X=1 TO PS:? #1,Z(X):NEXT X 1300 ? #1,LS:FOR X=1 TO LS:? #1,LN(X,0):? #1,LN(X,1):NEXT X:a$=" saved.":GOTO 1170 1310 REM *************************** 1320 REM * EDIT THE 3-D IMAGE DATA * 1330 REM *************************** 1340 on error goto 0:? :? "(P)rint, (E)dit or (R)eturn";:INPUT A$:IF A$="E" or A$="e" THEN 1410 1350 IF A$="R" or A$="r" THEN 340 1360 if a$="p" or a$="P" then 1370 else 1340 1370 on error goto 1340:PRINT "POINTS:";PS:PRINT 1380 FOR X=1 TO PS:PRINT "POINT ";X;": ";X(X),Y(X),Z(X):NEXT X:PRINT 1390 PRINT "LINES:";LS:PRINT 1400 FOR X=1 TO LS:PRINT "LINE ";X;": ";LN(X,0);" TO ";LN(X,1):NEXT X:PRINT :GOTO 1340 1410 on error goto 0:? :? "Edit (P)oint or (L)ine or (E)xit";:INPUT A$:IF A$="l" THEN 1480 1420 IF A$="e" THEN 320 1430 IF A$<>"p" THEN 1410 1440 ? :? "Enter POINT# or ";:on error goto 1410:INPUT PT:IF PT>PS OR PT<0 THEN 1440 1450 ? :? "X=";X(PT),"Y=";Y(PT),"Z=";Z(PT) 1460 ? :? "Enter NEW X,Y,Z or ":on error goto 1410 1470 INPUT Q1,Q2,Q3:X(PT)=Q1:Y(PT)=Q2:Z(PT)=Q3:GOTO 1410 1480 ? :? "Enter LINE# or ";:on error goto 1410:INPUT LN:IF LN>LS OR LN<0 THEN 1480 1490 ? :? "FROM point:";LN(LN,0):? " TO point:";LN(LN,1) 1500 ? :? "Enter new LINE POINTS or ":on error goto 1410 1510 ? "FROM point:";:INPUT Q1:IF Q1>PS THEN 1510 1520 LN(LN,0)=Q1 1530 ? " TO point:";:INPUT Q1:IF Q1>PS THEN 1530 1540 LN(LN,1)=Q1:GOTO 1410 1550 REM *************************** 1560 REM * GRAPHICS 1570 REM *************************** 1580 L1=0:L2=0:R1=0:R2=0:T1=0:T2=0:B1=0:B2=0:POK=0 1590 IF X1XR THEN R1=1 1610 IF Y1>YB THEN B1=1:GOTO 1630 1620 IF Y1XR THEN R2=1 1650 IF Y2>YB THEN B2=1:GOTO 1670 1660 IF Y2XR OR Y1YB OR XWXR OR YWYB THEN RETURN 1715 z%(0,i)=x1:z%(1,i)=y1:z%(2,i)=xw:z%(3,i)=yw:pok=1:return 1720 draw( X1,Y1 to XW,YW):POK=1:RETURN 1730 IF L1+T1+B1+R1=0 THEN XW=X3:YW=Y3:RETURN 1740 IF L1 THEN XW=XL:YW=Y3+(Y4-Y3)*(XL-X3)/(X4-X3):X3=XW:Y3=YW:IF Y3>=YT AND Y3<=YB THEN RETURN 1750 IF R1 THEN XW=XR:YW=Y3+(Y4-Y3)*(XR-X3)/(X4-X3):X3=XW:Y3=YW:IF Y3>=YT AND Y3<=YB THEN RETURN 1760 IF B1 THEN YW=YB:XW=X3+(X4-X3)*(YB-Y3)/(Y4-Y3):X3=XW:Y3=YW:IF X3>=XR AND X3<=XL THEN RETURN 1770 IF T1 THEN YW=YT:XW=X3+(X4-X3)*(YT-Y3)/(Y4-Y3):X3=XW:Y3=YW 1780 RETURN 1800 rem ---- Disk Directory 1810 rem 1820 ?:?"For Disk Directory, input (df0:), (df1:) or (N)one"; 1830 input drive$:if left$(drive$,2)<>"df" then return 1840 scnclr 1845 on error goto 1190 1847 chdir drive$ 1850 dir drive$ 1855 on error goto 0 1860 return 2000 FLAG=1:R=(OX^2+OY^2)^0.5:AN1=ATN(OY/OX):AN2=AN2+AN1 2100 AN1=AN1+AN3:OX=R*COS(AN1):OY=R*SIN(AN1) 2120 GOTO 440 2200 if flag=0 then return 2201 IF AN1>AN2 THEN FLAG=0:goto 1045 2202 XI=XI+1-2*(XI=2):XA=2-(XI=2) 2250 RETURN 2500 on error goto 0:scnclr :RETURN