ETH Zuerich - Startseite
Professur für CAAD

 


caad d-arch


Caad Teaching
 

 
Bachelor of Architecture: CAAD II ss07

 
Master of Advanced Studies
in Architecture, CAAD


 
DWF-Processing
Programmieren statt Zeichnen


 
Graustufen - Ein Atlas
Schweizer Wohngebäude als XML Daten


 
DWF- Denken in Systemen:
In Collaboration with the Technical University Vienna


 
Seminarwoche:
BlowUp


 
Archiv

 
Caad Projects
 

 
Theory
 
Design
 
Building
 
Practice

 
Related pages
 

 
Swiss Federal Institute of Technology Zurich
 
Institute of Building Technology
 
Faculty of Architecture

 
Other pages

 










hbt d-arch

MAS ETH ARCH/CAAD - 2005/06 - STUDENT PAGES
Master of Advanced Studies in Architecture, Specialization in Computer Aided Architectural Design | 065-0005/6
Supervision: Prof. Dr. Ludger Hovestadt, Philipp Schaerer
Chair of CAAD, ETH Zurich





Toni Kotnik Module 1: Scripting|Assignment 2
programming of pattern and further development


MainPattern.jpg


programming of pattern


The basic idea of how to generate all possible permutations of the 4 elements (compare Assignment 1) was the parallel use of an array list of all possible positions for the next entry. A pointer and an infill of zeros was introduced to avoid a dynamic array. The generation of a new permutation is then carried out in the procedure Generate and the function Reorder. With the function NewPattern the generated permuation is compared to the list of already exiting permutations, added to it if the pattern is new and printed out by procedure PrintOut . After generating all 24 different permutations the programm terminats.


GenPermSmall.jpg


PROCEDURE pattern;

VAR
   i,j : INTEGER;
   element : ARRAY[1..4] OF INTEGER;    (* basic and generated one*)
   pattern : ARRAY[1..24,1..4] OF INTEGER; (* possible pattern *)
   
   (* --- function for reordering of the list of available positions --- *)
   
   FUNCTION Reorder(olist:ARRAY[1..4] OF INTEGER):ARRAY[1..4] OF INTEGER;
         
   VAR
      i : INTEGER; (* counter *)
      s : INTEGER; (* storage *)

   BEGIN
      FOR i:=4 DOWNTO 2 DO
         IF olist[i]=0 THEN
            BEGIN
               olist[i]:=olist[i-1];
               olist[i-1]:=0;
            END;   
      Reorder:=olist;   
   END;


   (* --- procedure to generate a permutation of the basic element --- *)

   PROCEDURE Generate(VAR NewElement:ARRAY[1..4] OF INTEGER);

   VAR
      i : INTEGER;                    (* counter *)
      basic : ARRAY[1..4] OF INTEGER; (* basic element*)
      list : ARRAY[1..4] OF INTEGER;  (* list of available positions *)
      r,n : INTEGER;                  (* range and generated random number *)
      lpos : INTEGER;                 (* position in list *)   

   BEGIN
      FOR i:=1 TO 4 DO (* initialization of basic elements and available positions *)
      BEGIN
         basic[i]:=i;
         list[i]:=i;
      END;
      r:=3;
      FOR i:=1 TO 4 DO (* generate a pattern *)
         BEGIN
            n:=i+Random*r; (* take an available position in the list *) 
            lpos:=list[n]; (* read the corresponding entry *)
            list[n]:=0;    (* erase entry *)
            NewElement[lpos]:=basic[i]; (* place basic element at that position *)
            list := Reorder(list);
            r:=r-1;
         END;
   END;


   (* ---- function to compare the generated element with existing patterns --- *)

   FUNCTION NewPattern(list: ARRAY[1..4] OF INTEGER; n: INTEGER):BOOLEAN;

   VAR
      i,j : INTEGER; (* counter *)
      t : INTEGER; 
      test : BOOLEAN;

   BEGIN
      test:=TRUE;
      FOR i:=1 TO n DO
         BEGIN
            t:=0;
            FOR j:=1 TO 4 DO
               IF pattern[i,j]=list[j] THEN t:=t+1;
            IF t=4 THEN test:=FALSE;
         END;
      NewPattern:=test;
   END;
            

   (* --- print the new pattern --- *)

   PROCEDURE PrintOut(NewElement:ARRAY[1..4] OF INTEGER; i: INTEGER);

   VAR 
      j: INTEGER; (* counter *)
      h,v,r,c : INTEGER; (* horizontal and vertical shift for print out *)

   BEGIN
      FillPat(0);
      PenSize(10);
      r:=0;c:=i;
      WHILE c>6 DO (* calculate the row r and colummn i of the element *)
         BEGIN
            r:=r+1;
            c:=c-6;
         END;
      FOR j:= 1 TO 4 DO
         BEGIN 
            IF j<3 THEN v:=0 ELSE v:=1; (* vertical position in a 2x2-array *)
            IF (j MOD 2 = 1) THEN h:=0 ELSE h:=1; (* horizontal position in a 2x2-array *)
            ArcByCenter(10*c+5*h,5*v+10*r,5,0,90);
            Rotate(90*NewElement[j]); 
            ReDrawAll;
            DSelectAll;
         END;
   END;


(* --- main body --- *)

BEGIN
   i:=1;
   REPEAT
      Generate(element);
      IF NewPattern(element,i-1) THEN
         BEGIN
            FOR j:=1 TO 4 DO
               pattern[i,j]:=element[j];
            PrintOut(element,i);
            i:=i+1;
         END;
   UNTIL i=25;
END;
RUN(pattern);


Pattern.jpg




further development


ProgramArchMod.jpg animation (1.1 MB)


Using six elements to choose from the alphabet of 24 different letters out of four elements was then extended to an alphabet of 360 possible letters. This way, the whole ASCII-table could be coded and used to generate a pattern by reading a textfile sequentially. In order to receive a highly connected pattern, that is a pattern with smooth pathes along the arcs, the translated textfile was used as input for a cellular automata with the goal to optimize the amount of smooth connections. For this purpose the function CellType was developed to obtain a measure for the ability to move through the cell along a smooth path. The function checks the connection at the center point of each cell and returns 0 if it is non-smooth and 1 otherwise. Similarly, the function CCheck calculates the amount of smooth connections between a cell and its surrounding neighborhood. The automata then takes up the type of a cell as main criteria: a cell of type 0 is regarded as dead, a cell of type 1 as alive. In every generation the automata replaces non-isolated dead cells or badly connected living cells by a new candidate out of a pool of cells of type one. This way, the pattern improves gradually.


DataStructureSmallMod.jpg


The expression of the final object depends essentially on the density of the pattern. This particular feature can be influenced by three of the five paramters. With the breadth of the arcs the density of the pattern can be adjusted directly. The radius and the amount of cells per row have an influence on the size of each cell, therewith affecting the density of the pattern and the height of the cylinder indirectly. These paramaters act diametrically: an increasing radius leads to an increasing cell size, hence to a decreasing density; an increasing amount of cells per row leads to a decreasing cell size and therefore to an increasing density. With the two remaining parameters the number of rows and the thickness of the wall can be adjusted.


Parameter.jpg


PROCEDURE pattern1;

CONST
   columns = 8;    (* cells per row *)
   rows = 3;       (* number of layers of cylinder *)
   radius = 80;    (* radius on the outside of cylinder *) 
   thickness = 7.5;(* breadth of arcs *)
   depth = 8;      (* wall thickness of cylinder *)   
                                             

VAR
   i,i_plus,i_p,j,l,nc,cc,k : INTEGER;
   max_i,m_i,cr : INTEGER;
   col_i,row_i : REAL;
   InputText,data : STRING;
   letter : CHAR;
   lnumber,loops : INTEGER;
   element : ARRAY[1..4] OF INTEGER;    
   alphabet : ARRAY[0..255,1..4] OF INTEGER; 
   alphabetplus : ARRAY[0..255] OF INTEGER;   
   GoOn : BOOLEAN;   
   pattern, patternTemp : DYNARRAY[,] OF INTEGER; 
   d,factor : REAL;
   alpha,beta, base,height : REAL; 
   hl : HANDLE;   
   r,g,b : LONGINT;
   
   
   (* --- reordering of the list of available positions --- *)
   
   FUNCTION Reorder(olist:ARRAY[1..4] OF INTEGER):ARRAY[1..4] OF INTEGER;
         
   VAR
      i : INTEGER; (* counter *)
      s : INTEGER; (* storage *)

   BEGIN
      FOR i:=4 DOWNTO 2 DO
         IF olist[i]=0 THEN
            BEGIN
               olist[i]:=olist[i-1]; (* shift content down ... *)
               olist[i-1]:=0;        (* ... and fill up rest with zero *)
            END;   
      Reorder:=olist;   
   END;


   (* --- generate a permutation of basic elements --- *)

   PROCEDURE Generate(VAR NewElement:ARRAY[1..4] OF INTEGER);

   VAR
      i : INTEGER;                    (* counter *)
      basic : ARRAY[1..6] OF INTEGER; (* basic element*)
      list : ARRAY[1..4] OF INTEGER;  (* list of available positions *)
      r,n : INTEGER;                  (* range and generated random number *)
      lpos : INTEGER;                 (* position in list *)   

   BEGIN
      FOR i:=1 TO 6 DO basic[i]:=i;          (* six different elements *)
      n:=1+random*5;                         (* choose one ... *)
      FOR i:=n TO 5 DO basic[i]:=basic[i+1]; (* ... erase it out of the list of available elements *)
      n:=1+random*4;                         (* chose another one ... *)
      FOR i:=n TO 4 DO basic[i]:=basic[i+1]; (* ... erase it out of the list of available elements = basic[1] ... basic[4] *)
      FOR i:=1 TO 4 DO list[i]:=i;
      r:=3;
      FOR i:=1 TO 4 DO     (* generate a pattern *)
         BEGIN
            n:=i+Random*r; (* take an available position in the list *) 
            lpos:=list[n]; (* read the corresponding entry *)
            list[n]:=0;    (* erase entry *)
            NewElement[lpos]:=basic[i]; (* place basic element at that position *)
            list := Reorder(list);
            r:=r-1;
         END;
   END;


   (* ---- compare the generated element with existing patterns --- *)

   FUNCTION NewPattern(list: ARRAY[1..4] OF INTEGER; n: INTEGER):BOOLEAN;

   VAR
      i,j : INTEGER; 
      t : INTEGER; 
      test : BOOLEAN;

   BEGIN
      test:=TRUE;
      FOR i:=1 TO n DO
         BEGIN
            t:=0;   (* amount of equal entries *)
            FOR j:=1 TO 4 DO
               IF alphabet[i,j]=list[j] THEN t:=t+1;
            IF t=4 THEN test:=FALSE; (* all entries equal = permutation exists already *)
         END;
      NewPattern:=test;
   END;
            

   (* --- print element using arcs --- *)

   PROCEDURE PrintOutArc(NewElement:ARRAY[1..4] OF INTEGER; i: INTEGER);

   VAR 
      j: INTEGER; 
      h,v,r,c : INTEGER; (* horizontal and vertical shift for print out *)
      
   BEGIN
      FillBack(0,0,0);
      PenFore(0,0,0);
      r:=0;c:=i;
      WHILE c>columns DO (* calculate the row r and colummn i of the element *)
         BEGIN
            r:=r+1;
            c:=c-columns;
         END;
      FOR j:= 1 TO 4 DO
         BEGIN 
            IF j<3 THEN v:=0 ELSE v:=1;           (* vertical position in a 2x2-array *)
            IF (j MOD 2 = 1) THEN h:=0 ELSE h:=1; (* horizontal position in a 2x2-array *)   
            CASE NewElement[j] OF
               1..4:BEGIN
                     FillPat(0);
                     ArcByCenter(10*c+5*h,5*v+10*r,5,0,90);   
                     Rotate(-90*NewElement[j]); 
                   END;   
                  5:BEGIN
                     FillPat(0);
                     ArcByCenter(10*c+5*h,5*v+10*r,5,0,90);   
                     Duplicate(0,0);
                     Rotate(180);
                     END;   
                  6:BEGIN   
                     FillPat(0);
                     ArcByCenter(10*c+5*h,5*v+10*r,5,0,90);   
                     Rotate(90);
                     Duplicate(0,0);
                     Rotate(180);
                   END;
            END;
            ReDraw;
            DSelectAll;
         END;
   END;

   (* ---  arc with breadth --- *)

   PROCEDURE BasicElement2d(n:INTEGER);

   VAR
      ptX,ptY,arcRadius : REAL;
      vertexType,test : INTEGER;

   BEGIN
      ClosePoly;
      BeginPoly;                  (* define element as polyline *)
         AddPoint(base-d,0);      (* base = dimension of square; d = amount of overlapping with next cell *) 
         AddPoint(base-d,-d);
         AddPoint(base+d,-d);
         AddPoint(base+d,0);
         AddPoint(base+d,base+d);
         AddPoint(0,base+d);
         AddPoint(-d,base+d);
         AddPoint(-d,base-d);
         AddPoint(0,base-d);
         AddPoint(base-d,base-d);
      EndPoly;
      GetPolylineVertex(LNewObj,2,ptX,ptY,vertexType,arcRadius); (* pick vertex ... *)
      SetPolylineVertex(LNewObj,2,ptX,ptY,3,d,true);             (* ... and make it round *) 
      GetPolylineVertex(LNewObj,3,ptX,ptY,vertexType,arcRadius);
      SetPolylineVertex(LNewObj,3,ptX,ptY,3,d,true);
      GetPolylineVertex(LNewObj,5,ptX,ptY,vertexType,arcRadius);
      SetPolylineVertex(LNewObj,5,ptX,ptY,3,base+d,true);
      GetPolylineVertex(LNewObj,7,ptX,ptY,vertexType,arcRadius);
      SetPolylineVertex(LNewObj,7,ptX,ptY,3,d,true);
      GetPolylineVertex(LNewObj,8,ptX,ptY,vertexType,arcRadius);
      SetPolylineVertex(LNewObj,8,ptX,ptY,3,d,true);
      GetPolylineVertex(LNewObj,10,ptX,ptY,vertexType,arcRadius);
      SetPolylineVertex(LNewObj,10,ptX,ptY,3,base-d,true);
      RotatePoint(base/2,base/2,90*n);
   END;


   (* --- print arcs with thickness --- *)

   PROCEDURE PrintOutArcThick(NewElement:ARRAY[1..4] OF INTEGER; i: INTEGER);

   VAR 
      j: INTEGER; (* counter *)
      h,v,r,c : INTEGER; (* horizontal and vertical shift for print out *)
      a,b,inter : HANDLE;

   BEGIN
      FillBack(0,0,0);
      PenFore(0,0,0);
      FillPat(1);
      r:=0;c:=i;
      WHILE c>columns DO (* calculate the row r and colummn i of the element *)
         BEGIN
            r:=r+1;
            c:=c-columns;
         END;
      FOR j:= 1 TO 4 DO
         BEGIN 
            IF j<3 THEN v:=0 ELSE v:=1;           (* vertical position in a 2x2-array *)
            IF (j MOD 2 = 1) THEN h:=0 ELSE h:=1; (* horizontal position in a 2x2-array *)   
            CASE NewElement[j] OF
               1..4:BEGIN
                     BasicElement2d(NewElement[j]); 
                     MoveObjs(2*base*c+base*h,base*v+2*base*r,FALSE,FALSE);
                     DSelectAll;
                   END;   
                  5:BEGIN
                     BasicElement2d(2);
                     MoveObjs(2*base*c+base*h,base*v+2*base*r,FALSE,FALSE);
                     DSelectAll;
                     BasicElement2d(4);
                     MoveObjs(2*base*c+base*h,base*v+2*base*r,FALSE,FALSE);
                     DSelectAll;
                     END;   
                  6:BEGIN   
                     BasicElement2d(1);
                     MoveObjs(2*base*c+base*h,base*v+2*base*r,FALSE,FALSE);
                     DSelectAll;
                     BasicElement2d(3);
                     MoveObjs(2*base*c+base*h,base*v+2*base*r,FALSE,FALSE);
                     DSelectAll;
                   END;
            END;
            ReDraw;
            DSelectAll;
         END;
   END;


   (* --- print pattern in bw-blocks --- *)

   PROCEDURE PrintOutColor(NewElement:ARRAY[1..4] OF INTEGER; i: INTEGER);

   VAR 
      j: INTEGER; (* counter *)
      h,v,r,c : INTEGER; (* horizontal and vertical shift for print out *)

   BEGIN
      FillPat(1);
      r:=0;c:=i;
      WHILE c>columns DO (* calculate the row r and colummn i of the element *)
         BEGIN
            r:=r+1;
            c:=c-columns;
         END;
      IF NewElement[1]<>0 
         THEN FillBack(0,0,0)   
         ELSE FillBack(65535,65535,65535);
      Rect(10*c,10*r,10*c+10,10*r+10); 
      ReDraw;
      DSelectAll;
   END;


   (* --- calculate the celltype --- *)

   FUNCTION CellType(NewElement:ARRAY[1..4] OF INTEGER):INTEGER;

   VAR
      t : INTEGER;

   BEGIN
      t:=0; (* count number of bad connections *)
      CASE NewElement[1] OF (* check list of good combinations *)
         1:IF NOT ((((NewElement[4]=3) OR (NewElement[4]=6)) OR (NewElement[3]=4)) OR (NewElement[3]=5)) THEN t:=t+1; 
         3:IF NOT ((((NewElement[4]=1) OR (NewElement[4]=6)) OR (NewElement[2]=4)) OR (NewElement[2]=5)) THEN t:=t+1;
         6:IF NOT ((((((NewElement[4]=1) OR (NewElement[4]=3)) OR (NewElement[2]=4)) OR (NewElement[2]=5)) OR (NewElement[3]=4)) OR (NewElement[3]=5)) THEN t:=t+1;
      END;   
      CASE NewElement[2] OF
         2:IF NOT ((((NewElement[3]=4) OR (NewElement[3]=5)) OR (NewElement[4]=3)) OR (NewElement[4]=6)) THEN t:=t+1; 
         4:IF NOT ((((NewElement[3]=2) OR (NewElement[3]=5)) OR (NewElement[2]=3)) OR (NewElement[2]=6)) THEN t:=t+1;
         5:IF NOT ((((((NewElement[3]=2) OR (NewElement[3]=4)) OR (NewElement[1]=3)) OR (NewElement[1]=6)) OR (NewElement[4]=3)) OR (NewElement[4]=6)) THEN t:=t+1;
      END;
      CASE NewElement[3] OF
         2:IF NOT ((((NewElement[2]=4) OR (NewElement[2]=5)) OR (NewElement[4]=1)) OR (NewElement[4]=6)) THEN t:=t+1; 
         4:IF NOT ((((NewElement[2]=2) OR (NewElement[2]=5)) OR (NewElement[1]=1)) OR (NewElement[1]=6)) THEN t:=t+1;
         5:IF NOT ((((((NewElement[2]=2) OR (NewElement[2]=4)) OR (NewElement[1]=1)) OR (NewElement[1]=6)) OR (NewElement[4]=1)) OR (NewElement[4]=6)) THEN t:=t+1;
      END;      
      CASE NewElement[4] OF
         1:IF NOT ((((NewElement[1]=3) OR (NewElement[1]=6)) OR (NewElement[3]=2)) OR (NewElement[3]=5)) THEN t:=t+1; 
         3:IF NOT ((((NewElement[1]=1) OR (NewElement[1]=6)) OR (NewElement[2]=2)) OR (NewElement[2]=5)) THEN t:=t+1;
         6:IF NOT ((((((NewElement[1]=1) OR (NewElement[1]=3)) OR (NewElement[2]=2)) OR (NewElement[2]=5)) OR (NewElement[3]=2)) OR (NewElement[3]=5)) THEN t:=t+1;
      END;
      IF t>0 
         THEN CellType:=0
         ELSE CellType:=1; (* CellType 1 = good flow through cell *)
   END;


   (* --- check for living cells in the neighborhood  --- *)

   Procedure NCheck(i:INTEGER; VAR n:INTEGER);

   VAR
      seed : INTEGER;

   BEGIN
      seed:=0; (* count number of living neighbors *)
      IF (i<m_i) THEN (* does neighbor exist? *)
         BEGIN
            IF (pattern[i+1,2]=1) THEN seed:=seed+1;
         END;
      IF (i>1) THEN
         BEGIN 
            IF (pattern[i-1,2]=1) THEN seed:=seed+1;
         END;
      IF (i+columns<=m_i) THEN
         BEGIN
            IF (pattern[i+columns,2]=1) THEN seed:=seed+1;
         END;
      IF (i-columns>0) THEN
         BEGIN
            IF (pattern[i-columns,2]=1) THEN seed:=seed+1;
         END;
      n:=seed;
   END;


   (* --- connection between cells smooth? --- *)

   FUNCTION SmoothConnect(a,b,pos:INTEGER):BOOLEAN;

   VAR
      t : BOOLEAN;
      ct : INTEGER;
      element : ARRAY[1..4] OF INTEGER;

   BEGIN
      t:=FALSE;
      CASE a OF  (* check list of good combinations *)
         1: CASE pos OF
               1,5: IF ((b=3) OR (b=6)) THEN t:=TRUE;
               6  : IF ((b=4) OR (b=5)) THEN t:=TRUE;
               8  : IF ((b=2) OR (b=5)) THEN t:=TRUE;
            END;
         2: CASE pos OF
               3,7: IF ((b=4) OR (b=5)) THEN t:=TRUE;
               4  : IF ((b=1) OR (b=6)) THEN t:=TRUE;
               6  : IF ((b=3) OR (b=6)) THEN t:=TRUE;
            END;
         3: CASE pos OF
               1,5: IF ((b=1) OR (b=6)) THEN t:=TRUE;
               2  : IF ((b=2) OR (b=5)) THEN t:=TRUE;
               4  : IF ((b=4) OR (b=5)) THEN t:=TRUE;
            END;
         4: CASE pos OF
               3,7: IF ((b=2) OR (b=5)) THEN t:=TRUE;
               2  : IF ((b=1) OR (b=6)) THEN t:=TRUE;
               8  : IF ((b=3) OR (b=6)) THEN t:=TRUE;
            END;
         5: CASE pos OF
               3,7: IF (((b=2) OR (b=4)) OR (b=5)) THEN t:=TRUE;
               2,4: IF ((b=1) OR (b=6)) THEN t:=TRUE;
               6,8: IF ((b=3) OR (b=6)) THEN t:=TRUE;
            END;
         6: CASE pos OF
               1,5: IF (((b=1) OR (b=3)) OR (b=6)) THEN t:=TRUE;
               2,8: IF ((b=2) OR (b=5)) THEN t:=TRUE;
               4,6: IF ((b=4) OR (b=5)) THEN t:=TRUE;
            END;
      END;
      SmoothConnect:=t;
   END;


   (* --- check amount of existing external connections --- *)

   PROCEDURE CCheck (i:INTEGER; VAR n:INTEGER);   

   VAR
      c : INTEGER;

   BEGIN
      c:=0; (* count number of smooth connections *)
      IF i>1 THEN
         IF pattern[i-1,2]=1 THEN
             BEGIN 
               IF SmoothConnect(alphabet[pattern[i,1],1],alphabet[pattern[i-1,1],2],8) THEN c:=c+1;
               IF SmoothConnect(alphabet[pattern[i,1],1],alphabet[pattern[i-1,1],4],7) THEN c:=c+1;
               IF SmoothConnect(alphabet[pattern[i,1],3],alphabet[pattern[i-1,1],4],8) THEN c:=c+1;
               IF SmoothConnect(alphabet[pattern[i,1],3],alphabet[pattern[i-1,1],2],1) THEN c:=c+1;
            END;
      IF i<m_i THEN
         IF pattern[i+1,2]=1 THEN 
            BEGIN 
               IF SmoothConnect(alphabet[pattern[i,1],2],alphabet[pattern[i+1,1],1],4) THEN c:=c+1;
               IF SmoothConnect(alphabet[pattern[i,1],2],alphabet[pattern[i+1,1],3],5) THEN c:=c+1;
               IF SmoothConnect(alphabet[pattern[i,1],4],alphabet[pattern[i+1,1],3],4) THEN c:=c+1;
               IF SmoothConnect(alphabet[pattern[i,1],4],alphabet[pattern[i+1,1],1],3) THEN c:=c+1;
            END;
      IF i+columns<=m_i THEN
         IF pattern[i+columns,2]=1 THEN 
            BEGIN
               IF SmoothConnect(alphabet[pattern[i,1],3],alphabet[pattern[i+columns,1],1],6) THEN c:=c+1;
               IF SmoothConnect(alphabet[pattern[i,1],3],alphabet[pattern[i+columns,1],2],5) THEN c:=c+1;
               IF SmoothConnect(alphabet[pattern[i,1],4],alphabet[pattern[i+columns,1],2],6) THEN c:=c+1;
               IF SmoothConnect(alphabet[pattern[i,1],4],alphabet[pattern[i+columns,1],1],7) THEN c:=c+1;
            END;
      IF i-columns>0 THEN
         IF pattern[i-columns,2]=1 THEN 
            BEGIN
               IF SmoothConnect(alphabet[pattern[i,1],1],alphabet[pattern[i-columns,1],3],2) THEN c:=c+1;
               IF SmoothConnect(alphabet[pattern[i,1],1],alphabet[pattern[i-columns,1],4],3) THEN c:=c+1;
               IF SmoothConnect(alphabet[pattern[i,1],2],alphabet[pattern[i-columns,1],4],2) THEN c:=c+1;
               IF SmoothConnect(alphabet[pattern[i,1],2],alphabet[pattern[i-columns,1],3],1) THEN c:=c+1;
            END;
      n:=c;
   END;



   (* --- Basic form of final project --- *)

   FUNCTION BasicForm:HANDLE;

      VAR
         r  : REAL;
         f1,f2,f3 : HANDLE;
         test : INTEGER;
         ptX,ptY,arcRadius : REAL;
         vertexType : INTEGER;
   

      BEGIN
         r:=radius;
         BeginMXtrd(0,3*base); (* define cylinder as subtraction of two solids *)
         BeginPoly;
            AddPoint(-r,r);
            AddPoint(-r,-r);
            AddPoint(r,-r);
            AddPoint(r,r);
         EndPoly;
         GetPolylineVertex(LNewObj,1,ptX,ptY,vertexType,arcRadius);
         SetPolylineVertex(LNewObj,1,ptX,ptY,3,r,true);
         GetPolylineVertex(LNewObj,2,ptX,ptY,vertexType,arcRadius);
         SetPolylineVertex(LNewObj,2,ptX,ptY,3,r,true);
         GetPolylineVertex(LNewObj,3,ptX,ptY,vertexType,arcRadius);
         SetPolylineVertex(LNewObj,3,ptX,ptY,3,r,true);
         GetPolylineVertex(LNewObj,4,ptX,ptY,vertexType,arcRadius);
         SetPolylineVertex(LNewObj,4,ptX,ptY,3,r,true);
         BeginPoly;
            AddPoint(-r,r);
            AddPoint(-r,-r);
            AddPoint(r,-r);
            AddPoint(r,r);
         EndPoly;
         GetPolylineVertex(LNewObj,1,ptX,ptY,vertexType,arcRadius);
         SetPolylineVertex(LNewObj,1,ptX,ptY,3,r,true);
         GetPolylineVertex(LNewObj,2,ptX,ptY,vertexType,arcRadius);
         SetPolylineVertex(LNewObj,2,ptX,ptY,3,r,true);
         GetPolylineVertex(LNewObj,3,ptX,ptY,vertexType,arcRadius);
         SetPolylineVertex(LNewObj,3,ptX,ptY,3,r,true);
         GetPolylineVertex(LNewObj,4,ptX,ptY,vertexType,arcRadius);
         SetPolylineVertex(LNewObj,4,ptX,ptY,3,r,true);
         EndMXtrd;   
         f1:=LNewObj;
         DSelectAll;
         r:=radius-depth;
         BeginMXtrd(0,3*base);
         BeginPoly;
            AddPoint(-r,r);
            AddPoint(-r,-r);
            AddPoint(r,-r);
            AddPoint(r,r);
         EndPoly;
         GetPolylineVertex(LNewObj,1,ptX,ptY,vertexType,arcRadius);
         SetPolylineVertex(LNewObj,1,ptX,ptY,3,r,true);
         GetPolylineVertex(LNewObj,2,ptX,ptY,vertexType,arcRadius);
         SetPolylineVertex(LNewObj,2,ptX,ptY,3,r,true);
         GetPolylineVertex(LNewObj,3,ptX,ptY,vertexType,arcRadius);
         SetPolylineVertex(LNewObj,3,ptX,ptY,3,r,true);
         GetPolylineVertex(LNewObj,4,ptX,ptY,vertexType,arcRadius);
         SetPolylineVertex(LNewObj,4,ptX,ptY,3,r,true);
         BeginPoly;
            AddPoint(-r,r);
            AddPoint(-r,-r);
            AddPoint(r,-r);
            AddPoint(r,r);
         EndPoly;
         GetPolylineVertex(LNewObj,1,ptX,ptY,vertexType,arcRadius);
         SetPolylineVertex(LNewObj,1,ptX,ptY,3,r,true);
         GetPolylineVertex(LNewObj,2,ptX,ptY,vertexType,arcRadius);
         SetPolylineVertex(LNewObj,2,ptX,ptY,3,r,true);
         GetPolylineVertex(LNewObj,3,ptX,ptY,vertexType,arcRadius);
         SetPolylineVertex(LNewObj,3,ptX,ptY,3,r,true);
         GetPolylineVertex(LNewObj,4,ptX,ptY,vertexType,arcRadius);
         SetPolylineVertex(LNewObj,4,ptX,ptY,3,r,true);
         EndMXtrd;   
         f2:=LNewObj;
         DSelectAll;
         test:=SubtractSolid(f1,f2,f3);
         Rotate3D(-90,0,0);
         Move3D(0,-base,0);
         BasicForm:=f3;
         DSelectAll;
      END;


   (* --- construction of Basic element --- *)

   PROCEDURE BasicElement3d(n:INTEGER);

   VAR
      test : INTEGER;
      h1,h2,h3 : HANDLE;
      factor_top,factor_bottom,top,bottom: REAL;
      
   BEGIN
      bottom:=radius-1.5*depth;      (* calculate factors for extrusion *)
      factor_bottom:=bottom/radius;
      top:=1.5*radius;
      factor_top:=top/radius;
      BeginMXtrd(top,bottom);        (* extrude object as cone *)
         BasicElement2d(n);
         Scale(factor_top,factor_top);
         DSelectAll;
         BasicElement2d(n);
         Scale(factor_bottom,factor_bottom);
         DSelectAll;
      EndMXtrd;
      SetSelect(LNewObj);   
      Move3D(-base/2,0,0);
      h1:=LNewObj;
      h2:=BasicForm;
      test:=IntersectSolid(h1,h2,h3);
   END;


   (* --- print the pattern in 3d --- *)

   PROCEDURE PrintOutWall(NewElement:ARRAY[1..4] OF INTEGER; i: INTEGER);

   VAR 
      j,test: INTEGER; (* counter *)
      h,v,r,c,ref : INTEGER; (* horizontal and vertical shift for print out *)
      hnew : HANDLE;
      f1,f2,f3 : LONGINT;

   BEGIN
      FillPat(1);
      ColorIndexToRGB(19,f1,f2,f3);
      FillBack(f1,f2,f3);
      FillFore(f1,f2,f3);
      r:=0;c:=i;
      WHILE c>columns DO (* calculate the row r and colummn i of the element *)
         BEGIN
            r:=r+1;
            c:=c-columns;
         END;
      FOR j:= 1 TO 4 DO
         BEGIN 
            IF j<3 THEN v:=0 ELSE v:=1;           (* vertical position in a 2x2-array *)
            IF (j MOD 2 = 1) THEN h:=0 ELSE h:=1; (* horizontal position in a 2x2-array *)   
            FillPat(1);
            CASE NewElement[j] OF
               1..4:BEGIN
                     BasicElement3d(NewElement[j]);
                     MoveObjs(0,base*v+2*base*r,FALSE,FALSE);
                     Rotate3D(0,alpha*c+alpha/2*h,0);
                     DSelectAll;
                   END;   
                  5:BEGIN
                     BasicElement3d(2);
                     MoveObjs(0,base*v+2*base*r,FALSE,FALSE);
                     Rotate3D(0,alpha*c+alpha/2*h,0);
                     DSelectAll;
                     BasicElement3d(4);
                     MoveObjs(0,base*v+2*base*r,FALSE,FALSE);
                     Rotate3D(0,alpha*c+alpha/2*h,0);
                     DSelectAll;
                        END;   
                  6:BEGIN   
                     BasicElement3d(1);
                     MoveObjs(0,base*v+2*base*r,FALSE,FALSE);
                     Rotate3D(0,alpha*c+alpha/2*h,0);
                     DSelectAll;
                     BasicElement3d(3);
                     MoveObjs(0,base*v+2*base*r,FALSE,FALSE);
                     Rotate3D(0,alpha*c+alpha/2*h,0);
                     DSelectAll;
                   END;
            END;
            ReDraw;
            FillPat(0);
         END;
   END;



(* --- main body --- *)

BEGIN
   SelectAll;
   DeleteObjs;
   DoMenuTextByName('Standard Views',1); (* top view *)

   (* --- generate alphabet --- *)
   
   Message('computer generates the alphabet');
   i:=0;i_plus:=0; 
   REPEAT (* generate the alphabet *)
      Generate(element);
      IF NewPattern(element,i-1) THEN
         BEGIN
            FOR j:=1 TO 4 DO alphabet[i,j]:=element[j];
            IF CellType(element)>0
               THEN 
                  BEGIN
                     i_plus:=i_plus+1;
                     alphabetplus[i_plus]:=i;
                  END;
            i:=i+1;
         END;
   UNTIL i=256;

   (* --- read length of data --- *)
   
   GetFile(InputText);
   max_i:=0;
   Open(InputText);
   WHILE NOT Eof(InputText) DO
      BEGIN
         Readln(data);
         max_i:=max_i+Len(data);
      END;
      Close(InputText);
   col_i:=Trunc(Sqrt(max_i))+1; (* display input close to square *)
   row_i:=1;l:=max_i;
   WHILE l > col_i DO
      BEGIN
         l:=l-col_i;
         row_i:=row_i+1;
      END;
   
   (* --- generate the print out using arcs --- *)
   
   m_i:=col_i*row_i;cr:=columns*rows;
   IF m_i<cr THEN m_i:=cr;
   ALLOCATE pattern[1..m_i,1..2];
   ALLOCATE patternTemp[1..m_i,1..2];
   Open(InputText);
   For i:= 1 TO m_i DO
      BEGIN
         IF i<=max_i 
            THEN BEGIN
                    Read(letter);
                    lnumber:=Ord(letter); 
                    FOR j:=1 TO 4 DO element[j]:=alphabet[lnumber,j];
                 END
            ELSE FOR j:=1 TO 4 DO element[j]:=alphabet[32,j]; (* add ' ' to make field a rectangle *) 
         PrintOutArc(element,i);
         pattern[i,1]:=lnumber;
         pattern[i,2]:=CellType(element);
      END;
   Close(InputText);
   hl:=GetLayer(LNewObj);
   SetLayerRenderMode(hl,0,FALSE,TRUE); (* wireframe *)
   
   (* --- generate the print out using colors --- *)
   
         loops:=50;
         SelectAll;
         DeleteObjs;
         For i:= 1 TO m_i DO  (* generate input for automata, display type of each cell *) 
            BEGIN
               IF i<=max_i 
                  THEN BEGIN
                          lnumber:=pattern[i,1]; 
                          FOR j:=1 TO 4 DO element[j]:=alphabet[lnumber,j];
                         END
                  ELSE FOR j:=1 TO 4 DO element[j]:=alphabet[32,j];
               IF CellType(element)=0 
                  THEN BEGIN
                        FOR j:=1 TO 4 DO element[j]:=0;
                        pattern[i,2]:=0;
                       END;
               PrintOutColor(element,i);
            END;
         Close(InputText); 
                              
         (* --- calculate new pattern using cellular automata --- *)
         
         FOR l:=1 TO loops DO (* start automata *)
            BEGIN
               Message('l=',l);
               For i:=1 TO m_i DO
                  BEGIN   
                     NCheck(i,nc);
                     CCheck(i,cc);
                     CASE pattern[i,2] OF 
                           0: IF nc>0
                               THEN BEGIN
                                    i_p:=trunc(1+Random*(i_plus-1)); (* replace cell by a randomly picked cell of type 1 *)
                                    patternTemp[i,1]:=alphabetplus[i_p]; 
                                    FOR j:=1 TO 4 DO element[j]:=alphabet[patternTemp[i,1],j];
                                    patternTemp[i,2]:=CellType(element);
                                   END;
                        1:IF cc<3 THEN patternTemp[i,2]:=0;                   
                     END;
                     IF patternTemp[i,2]=1 
                        THEN BEGIN
                              FOR j:=1 TO 4 DO element[j]:=alphabet[patternTemp[i,1],j]; 
                              PrintOutColor(element,i)   
                             END
                        ELSE BEGIN
                              FOR j:=1 TO 4 DO element[j]:=0;
                              PrintOutColor(element,i);
                             END;
                  END; 
               pattern:=patternTemp;
            END; 
         SelectAll;
         DeleteObjs;

         (* calculate data *)

         m_i:=columns*rows;
         d:=thickness/2;
         alpha:=pi/columns;
         beta:=alpha/2;
         height:=radius*Cos(alpha/2);
         base:=2*radius*sin(alpha/2);
         alpha:=360/columns;

         (* --- printout 2d --- *)

         FOR i:=1 TO m_i DO
             BEGIN
               FOR j:=1 TO 4 DO element[j]:=alphabet[patternTemp[i,1],j];
               PrintOutArcThick(element,i);
             END;
         DSelectAll;      
      

   (* --- printout 3d --- *)

   GoOn:=YNDialog('Do you wish to continue?');
   IF GoOn 
      THEN BEGIN
            SelectAll;
            DeleteObjs;
            FOR i:= 1 TO m_i DO
               BEGIN
                  FOR j:=1 TO 4 DO element[j]:=alphabet[pattern[i,1],j];
                  PrintOutWall(element,i);
                 END;
           END;
   DoMenuTextByName('Standard Views',8); (* top right *)
   hl:=GetLayer(LNewObj);
   SetLayerRenderMode(hl,12,FALSE,TRUE); (* quick render *) 

END;
RUN(pattern1);






Revision r1.16 - 21 Dec 2005 - 08:46 - NDSToniKotnik
Parents: NDSToniKotnik
Copyright © 1999-2003 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.

This website has been archived and is no longer maintained.