5 DEFVERT = 12; (* Vertex count *)
\r
6 DEFREPL = 3; (* Repetition count *)
\r
7 DEFQIXS = 2; (* Qixs *)
\r
18 Vert : array[ 0..DEFVERT-1, 0..DEFREPL-1 ] of TPoint;
\r
19 Delta: array[ 0..DEFVERT-1 ] of TPoint;
\r
25 Qix : array[ 0..DEFQIXS-1 ] of TQix;
\r
26 Pal : array[ byte ] of TRGB;
\r
33 TMatrix = array[ 0..3, 0..3 ] of TReal;
\r
36 G: array[ 0..DEFVERT-1 ] of TRPoint;
\r
37 C: array[ 0..DEFVERT-1 ] of TRPoint;
\r
39 procedure BumpPal( Idx, DR, DG, DB, Steps: integer );
\r
43 for I:=1 to Steps do begin
\r
44 Pal[Idx+1].R := Pal[Idx].R + DR;
\r
45 Pal[Idx+1].G := Pal[Idx].G + DG;
\r
46 Pal[Idx+1].B := Pal[Idx].B + DB;
\r
51 procedure InitPalette;
\r
53 with Pal[0] do begin R:=0; G:=0; B:=0; end;
\r
54 with Pal[1] do begin R:=0; G:=0; B:=62; end;
\r
55 BumpPal( 1, 0, 2, -2, 31 );
\r
56 BumpPal( 32, 2, -2, 0, 31 );
\r
57 BumpPal( 63, -2, 2, 2, 31 );
\r
58 BumpPal( 94, 2, 0, -2, 31 );
\r
59 BumpPal( 125, -2, -2, 2, 31 );
\r
62 procedure Init( var Qix: TQix; Color: integer );
\r
66 FillChar( Qix.Vert, SizeOf(Qix.Vert), 0 );
\r
67 for I:=0 to DEFVERT-1 do begin
\r
68 Qix.Vert[I, DEFREPL-1].X := Random( MaxX );
\r
69 Qix.Vert[I, DEFREPL-1].Y := Random( MaxY );
\r
70 Qix.Delta[I].X := Random(5)+1;
\r
71 Qix.Delta[I].Y := Random(5)+1;
\r
75 (* Initialize matrix (Catmull-Rom) *)
\r
76 M[0,0] := -1/2; M[0,1] := 3/2; M[0,2] := -3/2; M[0,3] := 1/2;
\r
77 M[1,0] := 1; M[1,1] := -5/2; M[1,2] := 2; M[1,3] := -1/2;
\r
78 M[2,0] := -1/2; M[2,1] := 0; M[2,2] := 1/2; M[2,3] := 0;
\r
79 M[3,0] := 0; M[3,1] := 1; M[3,2] := 0; M[3,3] := 0;
\r
82 procedure mxBezier( var Qix: TQix; I0, Idx, N: integer );
\r
86 X0, Y0, X, Y: TReal;
\r
89 (* Compute coefficients *)
\r
90 for I:=0 to 3 do begin
\r
92 for J:=0 to 3 do C[I].X := C[I].X + M[I,J]*Qix.Vert[(I0+J) mod DEFVERT,Idx].X;
\r
94 for J:=0 to 3 do C[I].Y := C[I].Y + M[I,J]*Qix.Vert[(I0+J) mod DEFVERT,Idx].Y;
\r
100 for I:=1 to N do begin
\r
104 X := C[0].X*T3 + C[1].X*T2 + C[2].X*T + C[3].X;
\r
105 Y := C[0].Y*T3 + C[1].Y*T2 + C[2].Y*T + C[3].Y;
\r
106 mxLine( Round(X0), Page+Round(Y0), Round(X), Page+Round(Y), Qix.Color, OP_SET );
\r
112 procedure Plot( var Qix: TQix; Idx: integer );
\r
116 for I:=0 to DEFVERT-1 do begin
\r
117 mxBezier( Qix, I, Idx, 12 );
\r
121 procedure Update( var Qix: TQix; Idx: integer );
\r
125 for I:=0 to DEFVERT-1 do with Qix do begin
\r
126 Inc( Vert[I,Idx].X, Delta[I].X );
\r
127 if( Vert[I,Idx].X < 0 ) then begin
\r
128 Vert[I,Idx].X := 0;
\r
129 Delta[I].X := Random( 5 )+1;
\r
131 if( Vert[I,Idx].X > MaxX ) then begin
\r
132 Vert[I,Idx].X := MaxX;
\r
133 Delta[I].X := -Random( 5 )-1;
\r
135 Inc( Vert[I,Idx].Y, Delta[I].Y );
\r
136 if( Vert[I,Idx].Y < 0 ) then begin
\r
137 Vert[I,Idx].Y := 0;
\r
138 Delta[I].Y := Random( 5 )+1;
\r
140 if( Vert[I,Idx].Y > MaxY ) then begin
\r
141 Vert[I,Idx].Y := MaxY;
\r
142 Delta[I].Y := -Random( 5 )-1;
\r
147 procedure Copy( var Qix: TQix; Dest, Src: integer );
\r
151 for I:=0 to DEFVERT-1 do with Qix do begin
\r
152 Vert[I,Dest].X := Vert[I,Src].X;
\r
153 Vert[I,Dest].Y := Vert[I,Src].Y;
\r
157 procedure AnimateQix;
\r
159 Q, Idx, I, J, P, Count: integer;
\r
166 mxSetClipRegion( 0, Page, MaxX+1, MaxY+1 );
\r
168 mxFillBox( 0, Page, MaxX+1, MaxY+1, 0, OP_SET );
\r
169 for Q:=0 to DEFQIXS-1 do begin
\r
170 Copy( Qix[Q], I, P );
\r
171 Update( Qix[Q], I );
\r
172 for Idx:=0 to DEFREPL-1 do begin
\r
173 Plot( Qix[Q], Idx );
\r
176 I := (I+1) mod DEFREPL;
\r
177 J := (J+1) mod DEFREPL;
\r
178 P := (P+1) mod DEFREPL;
\r
180 mxStartLine( Page );
\r
181 if( Count >= FADESPEED ) then begin
\r
182 for Q:=0 to DEFQIXS-1 do begin
\r
183 Inc( Qix[Q].Color );
\r
184 if( Qix[Q].Color > 156 ) then
\r
190 until( KeyPressed );
\r
198 mxSetMode( MX_320x240 );
\r
199 mxGetScreenSize( MaxX, MaxY );
\r
200 for I:=0 to DEFQIXS-1 do
\r
201 Init( Qix[I], (I*(155 div DEFQIXS)) mod 155 + 1 );
\r
203 mxSetPalette( @Pal, 0, 157 );
\r
208 mxSetMode( MX_TEXT );
\r