home *** CD-ROM | disk | FTP | other *** search
- program Globe(input,output);
-
- { ---- Globe program by Karl Koessel ----
-
- Published in PC WORLD Vol.1, No. 1
- Original BASIC program by Karl Koessel
- Program Translated to Turbo by Lars Ecklund
-
- ---- Turbo version written 9/15/85 ---- }
-
- type
- ArrayOne = array[1..11] of integer;
-
- var
- BCK,PAL : byte;
- L,LX,LY,LZ,R,RC0,X,XC,Y,YC,Z : integer;
- A,A1,A3,ASP,B,B2,B3,C,C1,C2,CF,CX,CY,CZ,DR,I,J,SX,SY,SZ : real;
- XObs,XRot,YObs,YRot,ZObs,ZRot,ZS : real;
- SStr : char;
- BStr : string[2];
- CStr : string[3];
- RC : ArrayOne;
- Q : boolean;
-
- procedure SampleRun; forward;
- procedure ProcessInput; forward;
-
- procedure SetupAndInitializeVariables;
- label ExitSAIV;
- begin
- TextMode;
- ClrScr;
- GotoXY(23,1);
- WriteLn('Perspective image of Rotated Globe');
- for X:=1 to 11 do { Prepare an array holding the colors }
- begin { of parallels, pattern reverses after }
- RC[X]:=(X-1) mod 3+1; { equator which is brown or white. }
- if (X>6) then
- RC[X]:=(5-RC[X]) mod 3+1;
- end;
- CF:=Pi/180;
- WriteLn;
- Write('Want to see a sample run? (Y/N): ');
- ReadLn(SStr);
- SStr:=UpCase(Copy(SStr,1,1));
- if (SStr='Y') then
- begin
- SampleRun;
- goto ExitSAIV;
- end;
- GotoXY(1,5);
- WriteLn('Enter screen location of center of globe');
- Write ('(e.g. 160 100) ? ');
- Read (XC,YC);
- WriteLn;
- WriteLn('Enter relative coordinates of observer:');
- WriteLn('points left(-)/right(+) of X, below(-)/above(+) Y,');
- WriteLn('and distance from the screen');
- Write ('(e.g. -9 0 456) ? ');
- Read (XObs,YObs,ZObs);
- WriteLn;
- WriteLn('Enter parallel, meridian, & image''s tilt');
- Write ('(e.g. 37 -123 23) ? ');
- Read (XRot,YRot,ZRot);
- WriteLn;
- WriteLn('Enter sphere''s radius');
- Write ('(e.g. 100) ? ');
- Read (R);
- WriteLn;
- WriteLn('Enter background colour and palette');
- Write ('(e.g. 1 1) ? ');
- Read (BCK,PAL);
- WriteLn;
- WriteLn('Enter this screen''s aspect ratio');
- Write ('(e.g. 1.21875) ? ');
- Read (ASP);
- ProcessInput;
- repeat until (KeyPressed=True );
- ExitSAIV:
- end;
-
- procedure SampleRun;
- begin
- XC:=160; YC:=100; { Data for sample run }
- XObs:=-9.0; YObs:= 0.0; ZObs:=456.0;
- XRot:=37.0; YRot:=-123.0; ZRot:= 23.0;
- R:=100;
- BCK:=1; PAL:=1;
- ASP:=1.21875;
- GotoXY(1,5); { Screen for sample run }
- WriteLn('Enter screen location of center of globe');
- WriteLn('(e.g. 160,100) ? ',XC,',',YC);
- WriteLn;
- WriteLn('Enter relative coordinates of observer:');
- WriteLn('points left(-)/right(+) of X, below(-)/above(+) Y,');
- WriteLn('and distance from the screen');
- WriteLn('(e.g. -9,0,456) ? ',XObs:0,',',YObs:0,',',ZObs:0);
- WriteLn;
- WriteLn('Enter parallel, meridian, & image''s tilt');
- WriteLn('(e.g. 37,-123,23) ? ',XRot:0,',',YRot:0,',',ZRot:0);
- WriteLn;
- WriteLn('Enter sphere''s radius');
- WriteLn('(e.g. 100) ? ',R);
- WriteLn;
- WriteLn('Enter background colour and palette');
- WriteLn('(e.g. 1,1) ? ',BCK,',',PAL);
- WriteLn;
- WriteLn('Enter this screen''s aspect ratio');
- WriteLn('(e.g. 1.21875) ? ',ASP:6);
- GotoXY(1,25);
- Write('HIT ANY KEY TO CONTINUE...');
- ProcessInput;
- repeat until (KeyPressed=True );
- end;
-
- procedure ProcessInput;
- begin
- CX:=Cos(CF*XRot+ArcTan(YObs/ZObs));
- SX:=Sin(CF*XRot+ArcTan(YObs/ZObs));
- CY:=Cos(CF*YRot+ArcTan(XObs/ZObs));
- SY:=Sin(CF*YRot+ArcTan(XObs/ZObs));
- CZ:=Cos(CF*ZRot);
- SZ:=Sin(CF*ZRot);
- ZObs:=Sqrt(Sqr(XObs)+Sqr(YObs)+Sqr(ZObs)); { Observer's distance from globe's center }
- ZS:=Sqr(R)/ZObs; { Can't see if point's Z coordinate < ZS }
- end;
-
- procedure PlotPoint; forward;
- procedure WriteVisiblePoint; forward;
-
- procedure DrawGlobe;
- begin
- ClrScr; GraphColorMode; TextColor(BCK); TextBackGround(PAL);
- I:=0;
- while (I<=3) do
- begin
- RC0:=Round((I*12/Pi+2)) mod 3+1;
- Str(RC0,CStr);
- J:=0;
- while (J<=2.0001*Pi) do
- begin
- A:=R*Sin(I)*Sin(J);
- B:=R*Cos(J);
- C:=R*Cos(I)*Sin(J);
- PlotPoint;
- WriteVisiblePoint;
- J:=J+(Pi/24);
- end;
- I:=I+(Pi/12);
- end;
- I:=Pi/12;
- while (I<=11*Pi/12) do
- begin
- RC0:=RC[Round(I*12/Pi)];
- Str(RC0,CStr);
- J:=0;
- while (J<=2.0001*Pi) do
- begin
- A:=R*Sin(I)*Sin(J);
- B:=R*Cos(I);
- C:=R*Sin(i)*Cos(J);
- PlotPoint;
- WriteVisiblePoint;
- J:=J+(Pi/24);
- end;
- I:=I+(Pi/12);
- end;
- end;
-
- procedure PlotPoint;
- begin
- A1:=A*CY-C*SY; { Turn requested meridian to observer at 0,0,0 }
- C1:=A*SY+C*CY; { (B1=B, so B is used for B1)}
- B2:=B*CX-C1*SX; { Turn requested parallel to observer at 0,0,0 }
- C2:=B*SX+C1*CX; { (A2=A1, so A1 is used for A2)}
- A3:=A1*CZ-B2*SZ; { Turn image on axis perpendicular to screen }
- B3:=A1*SZ+B2*CZ; { (C3=C2, so C2 is used for C3)}
- DR:=C2/(ZObs-C2)+1; { Distance ratio for computing perpective }
- X:=Round(A3*DR*ASP+XC); { Screen's x (with perspective & aspect ratios)}
- Y:=Round(B3*-DR+YC); { Screen's y (with perspective, direction ratio }
- end; { (Z=C3=C2, so C2 is used for Z) }
-
- procedure WriteVisiblePoint;
- label 840;
- begin
- if (C2<ZS) or (LZ<ZS) then
- begin
- goto 840;
- end;
- Q:=(X<0) or (X>319) or (Y<0) or (Y>199) or (LX<0) or (LX>319) or (LY<0) or (LY>199);
- if (Q or (J=0)) then { Off screen? }
- Plot(X,Y,RC0)
- else
- Draw(LX,LY,X,Y,RC0);
- 840:
- LX:=X; LY:=Y; LZ:=Round(C2); { LX, LY, LZ are X, Y, Z of last referenced point }
- end;
-
- procedure RubberStamp;
- begin
- GotoXY(1,1); WriteLn('PC WORLD');
- Draw(32,1,38,1,0); Draw(32,2,38,2,3);
- Draw(32,3,38,3,0); Draw(32,4,38,4,3);
- Draw(32,5,38,5,0);
- repeat until (KeyPressed=True );
- end;
-
- BEGIN
- SetupAndInitializeVariables;
- DrawGlobe;
- RubberStamp;
- END.