(* VERSION 0028 *) (*.......................................................................*) (* HIDELINE *) (* Hideline is a three-dimensional graphics program. The program *) (* was written by Franklin C Crow and published as 'Three-Dimensional *) (* Computer Graphics', BYTE, March/April 1981. The program was adapted *) (* to run with a MicroAngelo graphics terminal by Ray Hopkins, 8 *) (* Chestnut Hill CT., Cinnaminson N.J. (609) 829-4686. *) (* Hl3.src builds the data files used by hl.src,the main display routine *) (* Hl1.src and Hl2 are support modules. Note that Hl1.src must have *) (* recursion turned on. Hl.cmd is the linker command file *) (*.......................................................................*) (*Z*) (*$S+*) {$K1} {$K2} {$K6} {$K7} {$K12} {$K13} {$K14} {$K15} MODULE HIDELINE1; CONST Dotsacross = 511; Dotsdown = 479; Maxpts = 200; Maxpols = 200; Maxvtx = 800; Maxsides =14; Move = $84; Plot = $91; Split = $B8; Clear = $88; TYPE Counter = 0..Maxvtx; Point = RECORD X,Y,Z : REAL END; Vertex = 0..Maxpts; Polygon = RECORD Numvtx : Vertex; START : Counter; END; Onepoly = ARRAY [1..Maxsides] OF Point; Matrix = ARRAY [1..4,1..4] OF REAL; VAR Polygons : EXTERNAL ARRAY [1..Maxpols] OF Polygon; Vertices : EXTERNAL ARRAY [1..Maxvtx] OF Vertex; Points : EXTERNAL ARRAY [1..Maxpts] OF Point; Outpolys : EXTERNAL ARRAY [1..Maxpols] OF Polygon; Outvtces : EXTERNAL ARRAY [1..Maxvtx] OF Point; Eyespace : EXTERNAL Matrix; Window : EXTERNAL Onepoly; Eyept , Cntrint : EXTERNAL Point; Screenscale, Screenctr : EXTERNAL Point; ScreenX, SCREENY : EXTERNAL REAL; Numpols, Numvtces, Windowsize, I : EXTERNAL Counter; Numpts : EXTERNAL Counter; NUMDISPLAY, NumvtxOUT : EXTERNAL Counter; CMDCHAR : EXTERNAL CHAR; Filename : EXTERNAL STRING; DONE : EXTERNAL BOOLEAN; EXTERNAL PROCEDURE GETPLANES(VAR Poly:Onepoly; Numpts:Counter); EXTERNAL PROCEDURE micro2(mode:byte;x,y:real); EXTERNAL PROCEDURE START; PROCEDURE MAKEPICTURE; VAR I,J,NUMCLP: Counter; Tmpoly : Onepoly; FUNCTION DOTPROD(PT1,PT2:Point): REAL; BEGIN {dotprod} DOTPROD := PT1.X*PT2.X+PT1.Y*PT2.Y+PT1.Z*PT2.Z; END; {dotprod} PROCEDURE IDENT(VAR MTX:Matrix); VAR I,J: Counter; BEGIN {ident} FOR I:=1 TO 4 DO BEGIN FOR J:=1 TO 4 DO BEGIN IF I=J THEN MTX[I,J] := 1 ELSE MTX[I,J] := 0; END; END; END; {ident} PROCEDURE MatrixMULT(MT1,MT2:Matrix; VAR RESULT: Matrix); VAR I,J,K: Counter; BEGIN {matrixmult} FOR I:=1 TO 4 DO BEGIN FOR J:=1 TO 4 DO BEGIN RESULT[I,J] := 0; FOR K:=1 TO 4 DO BEGIN RESULT[I,J] := RESULT[I,J]+MT1[K,J]*MT2[I,K]; END; END; END; END; {matrxmult} PROCEDURE TRANSFORM(PT:Point; MTX:Matrix; VAR NEWPT:Point); BEGIN NEWPT.X := PT.X*MTX[1,1]+PT.Y*MTX[1,2]+PT.Z*MTX[1,3]+MTX[1,4]; NEWPT.Y := PT.X*MTX[2,1]+PT.Y*MTX[2,2]+PT.Z*MTX[2,3]+MTX[2,4]; NEWPT.Z := PT.X*MTX[3,1]+PT.Y*MTX[3,2]+PT.Z*MTX[3,3]+MTX[3,4]; END; PROCEDURE GETEyespace(Eyept,Cntrint:Point); VAR MTX: Matrix; C1,C2: Point; HYPOTENUSE,COSA,SINA: REAL; BEGIN IDENT(Eyespace); WITH Eyept DO BEGIN Eyespace[1,4] := -X; Eyespace[2,4] := -Y; Eyespace[3,4] := -Z; END; TRANSFORM(Cntrint,Eyespace,C1); IDENT(MTX); WITH C1 DO HYPOTENUSE := SQRT(X*X+Y*Y); IF HYPOTENUSE > 0 THEN BEGIN COSA := C1.Y/HYPOTENUSE; SINA := C1.X/HYPOTENUSE; MTX[1,1] := COSA; MTX[2,1] := SINA; MTX[1,2] := -SINA; MTX[2,2] := COSA; MatrixMULT(Eyespace,MTX,Eyespace); END; TRANSFORM(Cntrint,Eyespace,C2); IDENT(MTX); WITH C2 DO HYPOTENUSE := SQRT(Y*Y+Z*Z); IF HYPOTENUSE > 0 THEN BEGIN COSA := C2.Y/HYPOTENUSE; SINA := -C2.Z/HYPOTENUSE; MTX[2,2] := COSA; MTX[3,2] := SINA; MTX[2,3] := -SINA; MTX[3,3] := COSA; MatrixMULT(Eyespace,MTX,Eyespace); END; IDENT(MTX); MTX[2,2] := 0; MTX[3,3] := 0; MTX[2,3] := 1; MTX[3,2] := 1; MatrixMULT(Eyespace,MTX,Eyespace); END; PROCEDURE MAKEDISPLAYABLE(VAR PT:Point); BEGIN PT.X := Screenscale.X*PT.X/PT.Z+Screenctr.X; PT.Y := Screenscale.Y*PT.Y/PT.Z+Screenctr.Y; END; FUNCTION FACESEYE(Poly:Onepoly): BOOLEAN; VAR TMPPT: Point; Tmpoly: Onepoly; BEGIN WITH Poly[2] DO BEGIN TMPPT.X := X; TMPPT.Y := Y; TMPPT.Z := Z; END; Tmpoly[1].X := Poly[1].X-Poly[2].X; Tmpoly[1].Y := Poly[1].Y-Poly[2].Y; Tmpoly[1].Z := Poly[1].Z-Poly[2].Z; Tmpoly[2].X := Poly[3].X-Poly[2].X; Tmpoly[2].Y := Poly[3].Y-Poly[2].Y; Tmpoly[2].Z := Poly[3].Z-Poly[2].Z; GETPLANES(Tmpoly,2); IF DOTPROD(TMPPT,Tmpoly[1]) <=0 THEN FACESEYE := FALSE ELSE FACESEYE := TRUE; END; PROCEDURE CLIPIN(VAR Poly:Onepoly; VAR Numpts:Counter); VAR I,J,LstJ,TMPPTS: Counter; D1,D2,A: REAL; Tmpoly: Onepoly; BEGIN FOR I:=1 TO Windowsize DO IF Numpts >0 THEN BEGIN D1 := DOTPROD(Poly[Numpts],Window[I]); LstJ := Numpts; TMPPTS := 0; FOR J:=1 TO Numpts DO BEGIN IF D1 >0 THEN BEGIN TMPPTS := TMPPTS+1; WITH Tmpoly[TMPPTS] DO BEGIN X := Poly[LstJ].X; Y := Poly[LstJ].Y; Z := Poly[LstJ].Z; END; END; D2 := DOTPROD(Poly[J],Window[I]); IF D1*D2<0 THEN BEGIN A := D1/(D1-D2); TMPPTS := TMPPTS+1; WITH Tmpoly[TMPPTS] DO BEGIN X := A*Poly[J].X+(1-A)*Poly[LstJ].X; Y := A*Poly[J].Y+(1-A)*Poly[LstJ].Y; Z := A*Poly[J].Z+(1-A)*Poly[LstJ].Z; END; END; LstJ := J; D1 := D2; END; FOR J:=1 TO TMPPTS DO BEGIN WITH Tmpoly[J] DO BEGIN Poly[J].X := X; Poly[J].Y := Y; Poly[J].Z := Z; END; END; Numpts := TMPPTS; END; END; PROCEDURE INSERTSORT(Poly:Onepoly;Numpts:Counter); VAR I,J,K: Counter; AVDEPTH,Nptsr : REAL; BEGIN AVDEPTH := 0; Nptsr := 0; FOR I:=1 TO Numpts DO BEGIN WITH Poly[I] DO BEGIN Outvtces[NumvtxOUT+I+1].X := X; Outvtces[NumvtxOUT+I+1].Y := Y; Outvtces[NumvtxOUT+I+1].Z := Z; AVDEPTH := AVDEPTH+ Z; Nptsr := Nptsr +1; END; END; AVDEPTH := AVDEPTH /Nptsr; Outvtces[NumvtxOUT+1].Z := AVDEPTH; J := 0; I := (NUMDISPLAY+1) DIV 2; K := NUMDISPLAY; WHILE (J<>I) DO IF AVDEPTH0 THEN INSERTSORT(Tmpoly,NUMCLP); END; END; START; FOR I:=1 TO NUMDISPLAY DO WITH Outpolys[I] DO BEGIN FOR J:=1 TO Numvtx DO WITH Outvtces[START+J] DO BEGIN Tmpoly[J].X := X; Tmpoly[J].Y := Y; Tmpoly[J].Z := Z; END; CLIPOUT(Tmpoly,Numvtx,I); IF Numvtx>0 THEN BEGIN GETPLANES(Tmpoly,Numvtx); FOR J:=1 TO Numvtx DO WITH Outvtces[START+J] DO BEGIN X := Tmpoly[J].X; Y := Tmpoly[J].Y; Z := Tmpoly[J].Z; END; END; END; END; {MAKEPICTURE} MODEND.