PROCEDURE KandinskysGambit; CONST dim = 120; (* dimesion of grid *) scale = 4; (* width of mesh *) diameter = 3.5; (* diameter of spiral *) length = 8; (* length of spiral *) VAR currentCell:HANDLE; (* variables for parsing of input data *) _tag,_data:STRING; _flag,id:INTEGER; x,y,value:REAL; _fileName:STRING; z : ARRAY[0..dim-1,0..dim-1] OF REAL; (* variables for line drawing *) sequence : ARRAY[0..length] OF VECTOR; h : HANDLE; u,v,i : INTEGER; (* --- read data from xml-file --- *) PROCEDURE readData(VAR _dData,_dTag:STRING; VAR _OCFlag:INTEGER); VAR _rString:STRING; _rChar:CHAR; _f1:INTEGER; BEGIN _f1:=0; _OCFlag:=0; _dData:=''; _rString:=''; _dTag:=''; WHILE ((_f1=0) AND (NOT EOF(_fileName))) DO BEGIN Read(_rChar); IF _rChar='/' THEN BEGIN IF _OCFlag=1 THEN _OCFlag:=2; _rString:=''; END ELSE BEGIN IF _rChar='<' THEN BEGIN _OCFLag:=1; _dData:=_rString; _rString:=''; END ELSE BEGIN IF _rChar='>' THEN BEGIN _dTag:=_rString; _f1:=1; END ELSE BEGIN _rString:=Concat(_rString,_rChar); END; END; END; END; IF EOF(_fileName) THEN _dTag:='xx'; END; (* --- initialize array --- *) PROCEDURE Init(VAR DataFile:ARRAY[0..dim-1,0..dim-1] OF REAL); VAR temp : ARRAY[0..dim-1,0..dim-1] OF REAL; u,v : LONGINT; BEGIN GetFile(_fileName); Open(_fileName); WHILE _tag<>'xx' DO BEGIN readData(_data,_tag,_flag); IF (_flag=2) THEN BEGIN IF _tag='CELL' THEN BEGIN temp[u,v]:=value; Message('Init: ',u,' ',v,' : ',value); END; IF _tag='VALUE' THEN value := Str2Num(_data); IF _tag='X' THEN u := Trunc(Str2Num(_data)); IF _tag='Y' THEN v := Trunc(Str2Num(_data)); END; END; Close(_fileName); _tag:=' '; DataFile:=temp; END; (* --- calculate next point of sequence --- *) FUNCTION DirectTo(value:REAL):VECTOR; VAR direction : VECTOR; gridpoint : INTEGER; BEGIN gridpoint:=1; WHILE value > gridpoint/8 DO gridpoint:=gridpoint+1; (* calculate zone of gray scale ... *) CASE gridpoint OF (* ... and assign corner of grid *) 1,3,5,7 : direction.x:=-1*diameter; 2,4,6,8 : direction.x:=1*diameter; END; CASE gridpoint OF 1,2,5,6 : direction.y:=1*diameter; 3,4,7,8 : direction.y:=-1*diameter; END; direction.z:=0; DirectTo:=direction; END; (* --- generate curl --- *) PROCEDURE GenerateHair(u,v:INTEGER); VAR dposition : VECTOR; i,ui,vi : INTEGER; h1,h2,h3 : HANDLE; x,y : INTEGER; BEGIN PenFore(65535*z[u,v],0,0); (* set color using only red chanel *) sequence[0].x:=u*scale; (* point on grid as starting point *) sequence[0].y:=-v*scale; sequence[0].z:=0; dposition:=DirectTo(z[u,v]); FOR i:=1 TO length DO BEGIN dposition.x:=(-1)^i*dposition.x*(0.5+random); (* rotate vector ... *) dposition.y:=(-1)^(i+1)*dposition.y*(0.5+random); dposition.z:=0; sequence[i]:=sequence[i-1]+dposition; (* ... and describe new control point *) END; h1:=CreateNurbsCurve(sequence[0].x,sequence[0].y,sequence[0].z,TRUE,2); FOR i:=1 TO length DO AddVertex3D(h1,sequence[i].x,sequence[i].y,sequence[i].z); DSelectAll; END; (* --- main program --- *) BEGIN FillPat(0); init(z); FOR v:=0 TO dim-1 DO FOR u:=0 TO dim-1 DO BEGIN Message('GenerateHair: ',u,' ',v); GenerateHair(u,v); END; END; RUN(KandinskysGambit);