aUCBLogo Demos and Tests / woven_patterns_t


to woven_patterns_t
 
comment
  [These patterns are made by starting with a list of numbers, of length "modulus",
   generated by random selections from the numbers: 1, 2, ....modulus. To this list is
   appended its reverse (gives additional symmetry) e.g. [3 2 1 2 2 1 2 3]. These numbers are the lengths of
   segments. A segment is plotted, but the next segment is then plotted at a given angle, x(say).
   When the list is exhausted, the process is repeated with the same list until closure is
   is obtained. The plot either returns to its starting point or proceeds in a line (to infinity).
   x is calculated from values of the variables: polygon, modulus, ang_factor and mod_factor.
   polygon_n: integer values 3..8 determines the overall symmetry of the pattern.
   modulus: the length of the initial list. 
   mod_factor: determines how many repetitions of the plotted list there are.
   ang_factor: more interesting results are found by using 2 angles in turn. If the
      first is x, the second is ang_factor*x. This variable governs the finer details
      of a plot.
   p_size: pen size
   magnification: maximum value fixed to keep the plot within the screen boundaries
   
   The larger the values of polygon_n and modulus the more complicated the design. I suggest
   polygon_n = 5, modulus = 6, ang_factor = 200 and mod_factor = 73 as a start. 
   Press shuffle&go repeatedly. This shuffles the modulus list.
]

 
setUpdateGraph false
 
erns
 
closeall 
 
(ss 0.8)
 
vars_list read_file "vars_file.txt
 
if empty? vars_list[vars_list = [5 85 28 8 6 2    [7 4 6 7 4 3 7 5]]]
 
factor = (item vars_list )/100
 
multiplier item vars_list
 
dilation = (item vars_list)*10
 
modulus item vars_list
 
polygon1 item vars_list
 
p_size =item vars_list
 
shuff item vars_list
 
mult=multiplier 
 
my_f=frame [][my_windowwxcaption+wxresize_border+wxclose_box+wxsystem_menu [10 70][200 470]
 
FrameSetClientSize my_f 200 470 
 
bshuffle = (Button my_f [shuffle&&go][go_shuffle updategraphwxbu_left [5 0][60 20])
 
bweave = (Button my_f [&weave][weave updategraph wxbu_left [5 25][60 20])
 
bgo = (Button my_f[&go][go updategraphwxbu_left [5 50][60 20])
 
bnew_list = (Button my_f [new_list][new_listwxbu_left [90 0][60 20])
 
sfactor = (Slider my_f [ang_factor0 1 1000 [factor SliderValue/100 go updategraphwxsl_horizontal+wxsl_labels [5 80] [150 60])
; SliderSetLineSize sfactor 1 
; SliderSetPageSize sfactor 25 
 
WindowOnMouseWheel sfactor 
 
[   tmp=Int (SliderValue sfactor)+MouseZ/120
   
SliderSetValue sfactor tmp
   
factor tmp/100 go updategraph
 
]
 
smultiplier = (Slider my_f [mod_factor1 36 100 [multiplier SliderValue go updategraph]wxsl_horizontal+wxsl_labels  [5 140] [150 60])
 
sdilation = (Slider my_f [magnification10 29 29 [dilation SliderValue*10 go updategraph]wxsl_horizontal+wxsl_labels  [5 200] [150 60]) 
 
smodulus = (Slider my_f [modulus4 6 8 [modulus SliderValue new_list go updategraph]wxsl_horizontal+wxsl_labels  [5 260] [150 60]) 
 
spolygon = (Slider my_f [polygon_n3 5 7 [polygon1 SliderValue new_list go updategraph]wxsl_horizontal+wxsl_labels  [5 320] [150 60]) 
 
sp_size = (Slider my_f [p_size2 2 5 [p_size SliderValue go updategraph]wxsl_horizontal+wxsl_labels  [5 380] [150 60])
 
bexit = (Button my_f [save&&exit][file_vars "vars_file.txt framedestroy my_fwxbu_left [5 440][60 20])
 
bsavepic = (Button my_f [save_pict][save_pict wxbu_left [130 440][60 20]) 
 
(foreach (list sfactor smultiplier sdilation smodulus spolygon sp_size)   butlast vars_list [SliderSetValue ?1 ?2]) 
end 

to save_pict
 
savepic (word "weave "_ factor*100 "_ multiplier "_ modulus "_ polygon1 "_ list_to_word shuff)
end


to list_to_word list#
 
if empty? list#[op ]
 
op word first listlist_to_word bf list#
end 

to read_file v_file
 
local "d_list
 
if not File? v_file [output []]
 
openread v_file
 
setreader v_file
 
d_list readlist
 
close v_file
 
setreader []
 
op d_list
end 



to file_vars v_file 
 
openwrite v_file
 
setwriter v_file
 
pr (list factor*100 multiplier dilation/10 modulus polygon1 p_size shuff) 
 
close  v_file
 
setwriter [] 
end
 

to extend :n :list#
 
if :n==0[op[]]
 
op se :listextend :n-:list#
end


to if_factor
  
if  (remainder multiplier modulus) == 0
   
[multiplier multiplier +signum (multiplier-mult)
    
SliderSetValue smultiplier multiplier
    
if_factor stop 
   
]
 
if  (remainder multiplier polygon1) == 0
   
[multiplier multiplier +signum (multiplier-mult)
       
SliderSetValue smultiplier multiplier
   
if_factor
   
]
end
 

to go
 
cs
 
if_factor 
 
mult multiplier
 
local "ang0 
 
make "ang0 :multiplier*360/((1+:factor)*:modulus*:polygon1)
 
make "ang_list list :ang0 :factor*:ang0
 
make "len_ang_list count :ang_list
 
local [f_list p polygon_list p_list]
 
make "f_list extend  :polygon1 se :shuff reverse :shuff
 
make "p [] make "polygon_list []
 
ht pu home 
 
setpc setpensize list 1 0
 
make "start_pos pos
 
make "p_list fput :start_pos plot :f_list
 
centre_plot :p_list ;DETERMINES C.OF G.
 ;setpos centre
 ;make "start_pos pos 
 
p_list map [?+centre]p_list
 
centre_plot p_list pu
 
make "seg_list p_list*size_corr 
 
plot1  :seg_list
 
pu
end

to centre_plot :p_list
 
local[len p 2nd 1st ]
 
make "len count :p_list
 
make "p first :p_list
 
make "1st first :p
 
make "2nd last :p
 
make "xmin :1st
 
make "xmax :1st
 
make "ymin :2nd
 
make "ymax :2nd
 
h_centre_plot :p_list
end

to h_centre_plot :p_list
 
if empty? :p_list
    
[size_corr dilation/ifelse ymax==0[0.1][ymax]
     
centre list 0-(:xmin+:xmax)/2 0-(:ymin+:ymax)/2
     
stop]
 
local[1st x ymake "1st first :p_list
 
make "x first :1st make "y last :1st
 
if :xmin>:x[make "xmin :x]
 
if :xmax<:x[make "xmax :x]
 
if :ymin>:y[make "ymin :y]
 
if :ymax<:y[make "ymax :y]
  
h_centre_plot bf :p_list
end

to go_shuffle
 
;if not :mult==multiplier[make "mult multiplier new_list] ;
 
shuff my_shuffle :shuff
 
go
 
show :shuff
end

to h_make_pf :el :list:k1 :k2 :p_list :flag
 
if empty? bf :p_liststop]
 
if empty? :list[h_make_pf first :p_list bf bf :p_list :k1 :k1 bf :p_list stop]
 
local "soln make "soln solve :el first :list#
 
(if not empty? :soln
     
[local[1st 2nd]
      
make "1st first :soln make "2nd last :soln
      
(if and (and  0<:1st  :1st<1) (and  0<:2nd :2nd<1)
         
[make "pf_list subst :1st :k1 :pf_list
          
make "pf_list subst :2nd :k2 :pf_list
         
])
     
])
 
h_make_pf :el bf :list:k1 :k2 :p_list 1
end

to h_sort :el :list#
 
if empty? :list#[op (list :el)]
 
if :el<first :list#[op fput :el :list#]
 
op fput first :listh_sort :el bf :list#
end

to h_weave :ci :pf_list
 
if empty? :pf_list[stop]
 
local[1st p f p1 p2]
 
make "1st first :pf_list
 
make "p first :1st make "f last :1st
 
make "p1 first :p make "p2 last :p
 
if not empty? :f[make "ci 1-:ci]
 
if :ci==0[h_weave bf :pf_list]
 
segment :p1 :p2
 
if :ci==1[h_weave bf :pf_list stop]
end

to make_initial_pf_pr_list :list#
 
if empty?  :list#[op []]
 
op fput list  first :list#  [] make_initial_pf_pr_list bf :list#
end

to make_p_pr_list :list#
 
if empty? bf :list#[op[]]
 
op fput list first :listfirst bf :listmake_p_pr_list bf :list#
end

to make_pf_pr_list :p_pr_list
 
local "pf_list
 
make "pf_list make_initial_pf_pr_list :p_pr_list ;GENERATED BY PLOT AND TRIMMED 
 
h_make_pf first :p_pr_list bf bf :p_pr_list 1 3 bf :p_pr_list 0
 
op :pf_list    
end

to modify_item  :f_list
 
if empty? bf :f_list[op[]] 
 
local[f1 f2 fm]
 
make "f1 first :f_list
 
make "f2 first bf :f_list
 
make "fm (:f1 :f2) / 2
 
op  fput  :p1*(:fm)  + :p2*:fm modify_item bf :f_list
end

to modify_pf_list :pf_list
 
if empty? :pf_list [op[]]
 
local[1st p_list f_list p1 p2]
 
make "1st first :pf_list
 
make "p_list first :1st
 
make "f_list my_sort last :1st
 
make "p1 first :p_list
 
make "p2 last :p_list
 
if empty? :f_list[op fput :1st modify_pf_list bf :pf_list]
 
make "p_list fput :p1 lput :p2 modify_item :f_list
 
;show :p_list stop
 
(op se pf_extend :p_list  :f_list  modify_pf_list bf :pf_list)
end

to my_remove :i :list#
 
if empty? :list#[op[]]
 
if :i==first :list#[op bf :list#]
 
op fput first :listmy_remove :i bf :list#
end

to my_shuffle :list#
 
if empty? :list#[op[]]
 
local "i i=pick :list#
 
op fput :i my_shuffle my_remove :i :list#
end

to my_sort :list#
 
if empty? :list#[op[]]
 
if empty? bf :list#[op :list#]
 
op h_sort first :listmy_sort bf :list#
end

to new_list
 
ct
 
make "shuff pick_list modulus  [1 2 4 3;iseq 1 3
 
show :shuff
end

to pf_extend :p_list :f_list
 
if empty? bf :p_list[op[]]
 
(op fput list (list first :p_list first bf :p_list)
               
(list first :f_list)
          
pf_extend bf :p_list :f_list)
end

to pick_list :n :list#
 
if :n==0[op[]]
 
op fput pick :listpick_list :n-:list#
end

to plot  :f_list [0] 
 
if empty? :f_list[op[]]
 
lt item 1+remainder :k :ang_list
 
fd 30*first :f_list
 
op fput pos (plot  bf :f_list k+)
end

to plot1  :p_list
 
if empty? :p_list [stop]
 
if empty? bf :p_list [stop]
 
segment first :p_list first bf :p_list 
 
;setpos first :p_list
 ;pd
 
plot1  bf :p_list
end

to segment :p1 :p2
 
local "d
 
t1=newturtle t2=newturtle
 
setturtle t1 ht pu setpos :p1 
 
seth towards :p2
 
make "d distance :p2
 
setturtle t2 ht pu setpos :p1
 
seth towards :p2
 
setpensize [1 1setpc 1
 
pu lt 90 fd  ifelse 1==remainder :p_size 2[:p_size/2][:p_size/2]
 
rt 90 pd fd :d pu
 
rt 90 fd  :p_size ;ifelse 1==remainder :p_size 2[:p_size/1][:p_size] ;1.5 1 
 
rt 90 pd fd :d pu
 
setturtle t1
 
setpensize list :p_size :p_size
 
setpc pd fd :d pu
end

to solve :pr1 :pr2
 
local[p1 p1 p3 p4 x1 y1 
       
x2 y2 x3 y3 x4 y4
       
f1 f2 p0 p  delta]
 
make "p1 first :pr1
 
make "p2 last :pr1
 
make "p3 first :pr2
 
make "p4 last :pr2
 
make "x1 first :p1
 
make "y1 last  :p1
 
make "x2 first :p2
 
make "y2 last  :p2
 
make "x3 first :p3
 
make "y3 last  :p3
 
make "x4 first :p4
 
make "y4 last  :p4
 
make "f1 make "p0 []  make "p []
 
make "f2 0  make "delta (:x2 :x1) * (:y3 :y4) - (:y2 :y1) * (:x3 :x4)
 
if  0.001 abs :delta [op []]
 
make "f1 ((:x3 :x1) * (:y3 :y4) - (:y3 :y1) * (:x3 :x4)) / :delta
 
make "f2 ((:x2 :x1) * (:y3 :y1) - (:y2 :y1) * (:x3 :x1)) / :delta
 
op list :f1 :f2 
end

to subst :f :k :pf_pr_list
 
if :k>count :pf_pr_list[op "ERROR]
 
(if :k==1
   
[local "1st make "1st first :pf_pr_list
    
(op fput list first :1st fput :f last :1st
             
bf :pf_pr_list)
   
])
 
op fput first :pf_pr_list  subst :f :k-bf :pf_pr_list
end

to trim_p_list :p_list
 
if empty? :p_list[op[]]
 
if equal? :start_pos first :p_list[op (list first :p_list)]
 
op fput first :p_list trim_p_list bf :p_list
end

to weave
 
go
 
pu cs home
 
;make "pf_pr_list  
 
h_weave modify_pf_list make_pf_pr_list make_p_pr_list :seg_list
end