OSDN Git Service

12313
[psychlops/silverlight.git] / test4 / PsychlopsMain.cs
1 //Two types of plaid motion\r
2 //E. H. Adelson and J. A. Movshon (1982).\r
3 //Phenomenal coherence of moving visual patterns. Nature 300, 523-525\r
4 \r
5 ///+ Prefix\r
6 //// Include Psychlops Package\r
7 using Psychlops;\r
8 \r
9         namespace PsychlopsSilverlightApp\r
10         {\r
11 \r
12                 public class PsychlopsMain\r
13                 {\r
14                         ///- Prefix\r
15 \r
16                         ///+ Global\r
17                         // Struct for component paremeters\r
18                         struct component\r
19                         {\r
20                                 public double contrast;\r
21                                 public double orientation;\r
22                                 public double lambda;\r
23                                 public double tf;\r
24                         }\r
25                         ///- Global\r
26 \r
27                         ///+ Stimulus drawing function\r
28                         //// A function for stimulus drawing (main body)\r
29                         void drawgratingmovie(Image[] img, component c1, component c2, double contrast, int start, int maxframe, double bg_lum, double alpha)\r
30                         {\r
31                                 double _xp, _xp2, col1, col2;\r
32                                 double contrast1, contrast2;\r
33                                 double imageheight, imagewidth;\r
34 \r
35                                 contrast1 = contrast*c1.contrast/(c1.contrast+c2.contrast);\r
36                                 contrast2 = contrast*c2.contrast/(c1.contrast+c2.contrast);\r
37 \r
38                                 imageheight = img[0].getHeight();\r
39                                 imagewidth = img[0].getWidth();\r
40 \r
41                                 for(int frame=start; frame<start+maxframe+1; frame++){\r
42                                         //Display.progressbar(frame, maxframe+1);\r
43                                         //img[frame].convert(Image::RGBA);\r
44                                         for(int i=0; i<imagewidth; i++){\r
45                                                 for(int j=0; j<imageheight; j++){\r
46                                                         _xp = Math.sin(c1.orientation)*(i-imagewidth*0.5) + Math.cos(c1.orientation) * (j-imageheight *0.5);\r
47                                                         _xp2 = Math.sin(c2.orientation)*(i-imagewidth*0.5) + Math.cos(c2.orientation) * (j-imageheight *0.5);\r
48                                                         col1 = bg_lum*contrast1*Math.sin(2*Math.PI*_xp/c1.lambda + 2*Math.PI*c1.tf*frame/(double)refresh);\r
49                                                         col2 = bg_lum*contrast2*Math.sin(2*Math.PI*_xp2/c2.lambda + 2*Math.PI*c2.tf*frame/(double)refresh);\r
50                                                         img[frame].pix(i,j,new Color(col1+col2+bg_lum));\r
51                                                         img[frame].alpha(i,j,alpha);\r
52                                                 }\r
53                                         }\r
54                                         //img[frame].cache();\r
55                                 }\r
56                         }\r
57 \r
58                         ///+ Stimulus drawing function\r
59                         //// A function for stimulus drawing (main body)\r
60                         void drawplaid() {\r
61                                 Canvas display = new Canvas(Canvas.window);\r
62                                 ///+ Preperation\r
63                                 //// Declare and initialize local variables\r
64                                 int rect_size = 150;\r
65                                 double rect_lum  = 0.5;\r
66                                 double bg_lum    = 0.2;\r
67                                 double duration = 400;\r
68 \r
69                                 double[] lambda = new double[2], contrast = new double[2], tf = new double[2];\r
70                                 double center_orientation = 0.0;\r
71                                 Image[,] movie = StaticFunctions.NewArray<Image>(2, 120);\r
72                                 Image[,] component_movie = StaticFunctions.NewArray<Image>(4, 120);\r
73                                 Image envelope = new Image(), envelope_small = new Image();\r
74 \r
75                                 for(int i=0; i<120; i++)\r
76                                 {\r
77                                         movie[0, i].set(rect_size, rect_size);\r
78                                         movie[1, i].set(rect_size, rect_size);\r
79                                         component_movie[0, i].set(rect_size/2, rect_size/2);\r
80                                         component_movie[1, i].set(rect_size/2, rect_size/2);\r
81                                         component_movie[2, i].set(rect_size/2, rect_size/2);\r
82                                         component_movie[3, i].set(rect_size/2, rect_size/2);\r
83                                 }\r
84                                 envelope.set(rect_size, rect_size);\r
85                                 envelope_small.set(rect_size/2, rect_size/2);\r
86 \r
87                                 Letters let1 = new Letters(), let2 = new Letters(), let3 = new Letters();\r
88                                 let1.str = "Component1";\r
89                                 let2.str = "Component2";\r
90                                 let3.str = "Superposition";\r
91                                 let1.centering().shift(-rect_size*1.25, -rect_size);\r
92                                 //let1.cache();\r
93                                 let2.centering().shift(rect_size*1.25, -rect_size);\r
94                                 //let2.cache();\r
95                                 let3.centering().shift(0.0, rect_size*0.75);\r
96                                 //let3.cache();\r
97 \r
98                                 component c1, c2, c0;\r
99                                 c0 = new component{ 0.0,0.0,1.0,1.0 }; //dummy for component movie\r
100                                 ///+ type-I\r
101                                 // Prepare Type-I plaid movie\r
102                                 center_orientation = 0.0;\r
103                                 orientation_offset = Math.PI/6;\r
104                                 contrast[0] = 1.0, contrast[1] = 1.0;\r
105                                 lambda[0] = 30.0, lambda[1] = 30.0;\r
106                                 tf[0] = 1.0; tf[1] = 1.0;\r
107 \r
108                                 c1 = {contrast[0], center_orientation-orientation_offset, lambda[0], tf[0]};\r
109                                 c2 = {contrast[1], center_orientation+orientation_offset, lambda[1], tf[1]};\r
110 \r
111                         drawgratingmovie(movie[0],c1, c2, 0.5, 0, refresh_int, bg_lum, 1.0);\r
112                         drawgratingmovie(component_movie[0],c0, c2, 0.5, 0, refresh_int, bg_lum, 1.0);\r
113                         drawgratingmovie(component_movie[1],c1, c0, 0.5, 0, refresh_int, bg_lum, 1.0);\r
114                         ///- type-I\r
115 \r
116                         ///+ type-II\r
117                         // Prepare Type-II plaid movie\r
118                         center_orientation = -0.0, orientation_offset = Math.PI/12;\r
119                         contrast[0] = 1.0, contrast[1] = 1.0;\r
120                         lambda[0] = 30.0, lambda[1] = 30.0;\r
121                         tf[0] = 1.0; tf[1] = 4.0;\r
122 \r
123                         c1 = {contrast[0], center_orientation-orientation_offset, lambda[0], tf[0]};\r
124                         c2 = {contrast[1], center_orientation+orientation_offset, lambda[1], tf[1]};\r
125 \r
126                         drawgratingmovie(movie[1],c1, c2, 0.5, 0, refresh_int, bg_lum, 1.0);\r
127                         drawgratingmovie(component_movie[2],c0, c2, 0.5, 0, refresh_int, bg_lum, 1.0);\r
128                         drawgratingmovie(component_movie[3],c1, c0, 0.5, 0, refresh_int, bg_lum, 1.0);\r
129                         ///- type-II\r
130 \r
131                         ///+ gaussian\r
132                         //draw Gaussian envelopes\r
133                         envelope.clear(new Color(bg_lum)); //clear offscreen image\r
134                         double _x, _y;\r
135                         for(int i=0; i<rect_size; i++){\r
136                         _x=i-0.5*rect_size;\r
137                         for(int j=0; j<rect_size; j++){\r
138                         _y=j-0.5*rect_size;\r
139                         envelope.alpha(i,j,1.0-Math.exp(-((_x*_x+_y*_y)/ (2.0*pow(rect_size/6.0, 2.0) ))));\r
140                         }\r
141                         }\r
142 \r
143                         envelope_small.clear(new Color(bg_lum)); //clear offscreen image\r
144                         for(int i=0; i<rect_size*0.5; i++){\r
145                         _x=i-0.25*rect_size;\r
146                         for(int j=0; j<rect_size*0.5; j++){\r
147                         _y=j-0.25*rect_size;\r
148                         envelope_small.alpha(i,j,1.0-Math.exp(-((_x*_x+_y*_y)/ (2.0*pow(rect_size/12.0, 2.0) ))));\r
149                         }\r
150                         }\r
151                         envelope.cache(); //send offscreen image from main memory to GPU\r
152                         envelope_small.cache(); //send offscreen image from main memory to GPU\r
153                         ///- gaussian\r
154 \r
155                         ///+ user interface\r
156                         // Draw user interface\r
157                         Widgets::SelectBox stimulus_type;\r
158                         stimulus_type.area.set(120, 20);\r
159                         stimulus_type.append(L"TypeI");\r
160                         stimulus_type.append(L"TypeII");\r
161                         stimulus_type.centering().shift(-120.0,250.0);\r
162 \r
163                         Psychlops::Widgets::SelectBox stimulus_type2;\r
164                         stimulus_type2.area.set(120, 20);\r
165                         stimulus_type2.append(L"Continuous");\r
166                         stimulus_type2.append(L"Periodic");\r
167                         stimulus_type2.centering().shift(120.0,250.0);\r
168 \r
169                         Psychlops::Widgets::Slider duration_slider;\r
170                         duration_slider.area.set(100,20);\r
171                         duration_slider.centering().shift(120,280.0);\r
172                         Interval rng = new Interval();\r
173                         duration_slider.link(duration, 50<=rng<=950, 50.0, 50.0);\r
174                         ///- user interface\r
175                         ///- Preperation\r
176 \r
177                         ///+ Main loop\r
178                         int frame = 0;\r
179                         int period = refresh_int;\r
180                         int movienum;\r
181                         while(!Keyboard.esc.pushed()) {\r
182                         Display.clear(new Color(bg_lum));\r
183                         movienum = stimulus_type.getSelected(); //if "Type-I" is selected, 0, else frame refresh per sec\r
184 \r
185                         in;\r
186                         else period = refresh_int;\r
187 \r
188                         if(frame>0){\r
189                         movie[movienum, frame].centering().draw();\r
190                         envelope.centering().draw();\r
191                         component_movie[movienum*2, frame].centering().shift(-rect_size*0.5, -rect_size).draw();\r
192                         envelope_small.centering().shift(-rect_size*0.5, -rect_size).draw();\r
193                         component_movie[movienum*2+1, frame].centering().shift(rect_size*0.5, -rect_size).draw();\r
194                         envelope_small.centering().shift(rect_size*0.5, -rect_size).draw();\r
195                         }\r
196 \r
197                         ///+ draw user interface\r
198                         let1.draw(0.75);\r
199                         let2.draw(0.75);\r
200                         let3.draw(0.75);\r
201                         stimulus_type.draw();\r
202                         stimulus_type2.draw();\r
203                         if(stimulus_type2.getSelected())duration_slider.draw();\r
204                         ///- draw user interface\r
205                         Display.flip();\r
206                         if(frame++ >= period) frame -= refresh_int;\r
207                         }\r
208                         ///- Main loop\r
209 \r
210                         }\r
211                         ///- Stimulus drawing function\r
212 \r
213                 ///+ Main function for demo circumstances\r
214                 public void psychlops_main() {\r
215                         ///+ Demo circumstances\r
216                         //// Spells for run demonstration circumstances\r
217                         Procedure p = new Procedure();\r
218                         //p.setDesign(Procedure::DEMO); //Designate that this is a demo.\r
219                         p.setProcedure(drawplaid);  //The argument name is a name of drawing function.\r
220                         p.run();\r
221                         ///- Demo circumstances\r
222                 }\r
223         }\r
224 }\r
225 \r
226 \r
227 \r
228 \r
229 /*\r
230 using Psychlops;\r
231 //Position Bias Program\r
232 namespace PsychlopsSilverlightApp\r
233 {\r
234 \r
235     public class PsychlopsMain\r
236     {\r
237         Canvas cnvs;\r
238         Image img, img2, img3;\r
239         int isize = 80;        \r
240         int frames;\r
241         Psychlops.Widgets.Slider tfreq;\r
242         Psychlops.Widgets.Slider contrast;\r
243         Psychlops.Widgets.Slider lambda;\r
244 \r
245         public void psychlops_main()\r
246         {\r
247             cnvs = new Canvas(300, 600);\r
248             Interval rng = new Interval();\r
249             tfreq = new Psychlops.Widgets.Slider("Temporal Frequency(Hz)", -5 <= rng <= 5, 3.0);\r
250             contrast = new Psychlops.Widgets.Slider("Contrast", 0.0 <= rng <= 1.0, 0.25);\r
251             lambda = new Psychlops.Widgets.Slider("Wave Length", 10.0 <= rng <= 120.0, 30);\r
252 \r
253             img = new Image(isize * 2, isize * 2);\r
254             img2 = new Image(isize * 2, isize * 2);\r
255             img3 = new Image(isize * 2, isize * 2);\r
256 \r
257 \r
258             while (true)\r
259             {\r
260                 cnvs.clear(new Color(0.5));\r
261 \r
262                 Figures.drawGabor(ref img, isize / 6, 1/lambda, contrast, 0.5 * Math.PI, (double)frames * 2.0 * Math.PI * tfreq / 60);\r
263                                 Figures.drawGabor(ref img2, isize / 6, 1 / lambda, contrast, 0.5 * Math.PI, (double)frames * 2.0 * Math.PI * -tfreq / 60);\r
264                                 Figures.drawGabor(ref img3, isize / 6, 1 / lambda, contrast, 0.5 * Math.PI, (double)frames * 2.0 * Math.PI * tfreq / 60);\r
265 \r
266                 img.centering().shift(0, -isize * 1.5).draw();\r
267                 img2.centering().draw();\r
268                 img3.centering().shift(0, isize * 1.5).draw();\r
269                 \r
270                 if (!Mouse.left.pressed()) frames++;\r
271 \r
272                 cnvs.flip();\r
273             }\r
274         }\r
275     }\r
276 }\r
277 \r
278 */