psychlops silverlight
Revision | c3b559a9144300352379e8d80dd71131b45f4d99 (tree) |
---|---|
Time | 2012-10-04 14:14:16 |
Author | HOSOKAWA Kenchi <hskwk@user...> |
Commiter | HOSOKAWA Kenchi |
da
@@ -77,6 +77,21 @@ namespace Psychlops{ | ||
77 | 77 | buffer.SetPixel(x, y, col); |
78 | 78 | } |
79 | 79 | |
80 | + public void pix_raw(int x, int y, Color col) | |
81 | + { | |
82 | + buffer.SetPixel(x, y, col); | |
83 | + } | |
84 | + | |
85 | + public void pix_direct(int x, int y, Color col) | |
86 | + { | |
87 | + buffer.SetPixel(x, y, col); | |
88 | + } | |
89 | + | |
90 | + public void pix_direct(int x, int y, double r, double g, double b, double a) | |
91 | + { | |
92 | + buffer.SetPixel(x, y, new Color(r,g,b,a)); | |
93 | + } | |
94 | + | |
80 | 95 | public void release() |
81 | 96 | { |
82 | 97 | } |
@@ -92,13 +107,7 @@ namespace Psychlops{ | ||
92 | 107 | |
93 | 108 | public void clear(Color col) |
94 | 109 | { |
95 | - for (int y = 0; y < height; y++) | |
96 | - { | |
97 | - for (int x = 0; x < width; x++) | |
98 | - { | |
99 | - pix(x, y, col); | |
100 | - } | |
101 | - } | |
110 | + each((x, y) => col); | |
102 | 111 | } |
103 | 112 | |
104 | 113 |
@@ -4,6 +4,45 @@ namespace Psychlops | ||
4 | 4 | { |
5 | 5 | namespace ColorSpaces |
6 | 6 | { |
7 | + public struct HSV | |
8 | + { | |
9 | + public double H, S, V, A; | |
10 | + | |
11 | + public Color toRGB() | |
12 | + { | |
13 | + if (S == 0.0) return new Color(V, V, V, A); | |
14 | + int hi = (int)Math.floor(H/60.0); | |
15 | + double f = (H / 60.0) - (double)hi, | |
16 | + p = V*(1.0-S), | |
17 | + q = V*(1.0-f*S), | |
18 | + t = V*(1.0-(1.0-f)*S); | |
19 | + if (hi == 0) { return new Color(V, t, p, A); } | |
20 | + else if (hi == 1) { return new Color(q, V, p, A); } | |
21 | + else if (hi == 2) { return new Color(p, V, t, A); } | |
22 | + else if (hi == 3) { return new Color(p, q, V, A); } | |
23 | + else if (hi == 4) { return new Color(t, p, V, A); } | |
24 | + else if (hi == 5) { return new Color(V, p, q, A); } | |
25 | + else return Color.transparent; | |
26 | + } | |
27 | + | |
28 | + public void fromRGB(Color o) { | |
29 | + double MAX = Math.max(Math.max(o.r, o.g), o.b); | |
30 | + double MIN = Math.min(Math.min(o.r, o.g), o.b); | |
31 | + double h; | |
32 | + if(MAX==MIN) { h=0.0; } | |
33 | + else if(o.r>o.g && o.r>o.b) { h=60.0*(o.g-o.b)/(MAX-MIN)+360.0; } | |
34 | + else if(o.g>o.b) { h=60.0*(o.b-o.r)/(MAX-MIN)+120.0; } | |
35 | + else { h=60.0*(o.r-o.g)/(MAX-MIN)+240.0; } | |
36 | + h = Math.mod(h, 360.0); | |
37 | + double v = MAX, s; | |
38 | + if(MAX==MIN) { s=0.0; } else { s=(MAX-MIN)/MAX; } | |
39 | + H = h; | |
40 | + S = s; | |
41 | + V = v; | |
42 | + A = o.a; | |
43 | + } | |
44 | + } | |
45 | + | |
7 | 46 | /* |
8 | 47 | * CIE 1931 |
9 | 48 | * R: 700 nm |
@@ -149,11 +149,12 @@ namespace Psychlops | ||
149 | 149 | |
150 | 150 | static Slider() |
151 | 151 | { |
152 | - bgcolor.set(.5,.5, .5, .3); | |
152 | + bgcolor.set(.5, .5, .5, .3); | |
153 | 153 | } |
154 | 154 | |
155 | 155 | public Slider(string l, Interval r, double initialvalue) |
156 | 156 | { |
157 | + changed = true; | |
157 | 158 | retval = initialvalue; |
158 | 159 | range = r; |
159 | 160 | label = l; |
@@ -167,6 +168,7 @@ namespace Psychlops | ||
167 | 168 | } |
168 | 169 | public Slider(string l, Interval r, double step1, double step2) |
169 | 170 | { |
171 | + changed = true; | |
170 | 172 | retval = r.begin.value; |
171 | 173 | range = r; |
172 | 174 | label = l; |
@@ -341,6 +343,7 @@ namespace Psychlops | ||
341 | 343 | slide.SmallChange = ss.small_step; |
342 | 344 | } |
343 | 345 | slide.ValueChanged += slider_ValueChanged; |
346 | + slide.ValueChanged += (sender, e) => { ss.changed = true; }; | |
344 | 347 | System.Windows.Controls.Canvas.SetTop(slide, label.ActualHeight - 3); |
345 | 348 | var b = new System.Windows.Data.Binding { |
346 | 349 | Path = new PropertyPath("Value"), |
@@ -1,4 +1,113 @@ | ||
1 | -// Motion with glass patterns. | |
1 | +/* | |
2 | +// Lilac Chaser. | |
3 | +// Zaidi Q, Ennis R, Cao D, Lee B (2012) | |
4 | +// Neural locus of color after-image. | |
5 | +// Current Biology, 22, 220-224 | |
6 | +///+ Prefix | |
7 | +//// Include Psychlops Package | |
8 | +using Psychlops; | |
9 | + | |
10 | +namespace PsychlopsSilverlightApp | |
11 | +{ | |
12 | + | |
13 | + public class PsychlopsMain | |
14 | + { | |
15 | +///- Prefix | |
16 | + | |
17 | + | |
18 | + ///+ Stimulus drawing function | |
19 | + //// A function for stimulus drawing (main body) | |
20 | + public void psychlops_main() { | |
21 | + | |
22 | + ///+ Preperation | |
23 | + //// Declare and initialize local variables | |
24 | + Canvas cnvs = new Canvas(Canvas.window); //Prepare drawing window | |
25 | + double dotsize = 100; | |
26 | + double dot_lum = 1; | |
27 | + double bg_lum = 0.5; | |
28 | + double duration = 8.0; | |
29 | + int stroke = 0; | |
30 | + bool draw_base_position = false; | |
31 | + | |
32 | + var fixate = new Rectangle(); | |
33 | + Image dot = new Image(); | |
34 | + Color col = new Color(); | |
35 | + double xp, yp, radius, a; | |
36 | + | |
37 | + Psychlops.Widgets.Slider hue, value; | |
38 | + ///- Preperation | |
39 | + | |
40 | + ///+ set Independent | |
41 | + //// set variables and value ranges for interaction | |
42 | + Interval rng = new Interval(); | |
43 | + hue = new Psychlops.Widgets.Slider("Hue", 0.0 <= rng < 360.0, 1, 12); | |
44 | + hue.setValue(300.0); | |
45 | + value = new Psychlops.Widgets.Slider("Lightness", 0 <= rng <= 1.0, 0.1, 0.05); | |
46 | + value.setValue(0.7); | |
47 | + ///- set Independent | |
48 | + | |
49 | + dot.set(dotsize, dotsize); | |
50 | + double width = dotsize, height = dotsize, sigma = (width / 6.0); | |
51 | + | |
52 | + fixate.set(11,11); | |
53 | + | |
54 | + int frame = 0; | |
55 | + | |
56 | + while (!Keyboard.esc.pushed()) | |
57 | + { | |
58 | + ///+ reflesh dot | |
59 | + if (hue.changed) | |
60 | + { | |
61 | + Psychlops.ColorSpaces.HSV hsv = new Psychlops.ColorSpaces.HSV(); | |
62 | + hsv.H = Math.mod( hue.getValue(), 360); | |
63 | + hsv.S = 1.0; | |
64 | + hsv.V = value.getValue(); | |
65 | + dot.each((x, y) => | |
66 | + { | |
67 | + yp = y - height / 2.0; | |
68 | + xp = x - width / 2.0; | |
69 | + radius = Math.sqrt(xp * xp + yp * yp); | |
70 | + hsv.A = Math.exp(-(radius * radius) / (2.0 * sigma * sigma)); | |
71 | + return hsv.toRGB(); | |
72 | + }); | |
73 | + } | |
74 | + ///+ reflesh dot | |
75 | + | |
76 | + | |
77 | + ///+ stroke count | |
78 | + if(frame%((int)duration)==0) { | |
79 | + stroke++; stroke %= 8; | |
80 | + } | |
81 | + ///- stroke count | |
82 | + | |
83 | + cnvs.clear(new Color(bg_lum)); //Clear window | |
84 | + | |
85 | + | |
86 | + ///+ Draw dots | |
87 | + //// Draw dots at a desinated position. | |
88 | + for(int i=0; i<8; i++) { | |
89 | + if(i!=stroke) { | |
90 | + dot.centering().shift(dotsize*1.3*Math.cos(i/8.0*2*Math.PI), dotsize*1.3*Math.sin(i/8.0*2*Math.PI)).draw(); | |
91 | + } | |
92 | + } | |
93 | + ///- Draw dots | |
94 | + | |
95 | + fixate.centering().draw(); | |
96 | + | |
97 | + cnvs.flip(); // Flip frame buffers | |
98 | + frame++; | |
99 | + } | |
100 | + | |
101 | + } | |
102 | + ///- Stimulus drawing function | |
103 | + | |
104 | + } | |
105 | + | |
106 | +} | |
107 | +*/ | |
108 | + | |
109 | + | |
110 | +// Motion with glass patterns. | |
2 | 111 | // Ross, J., Badcock, D. R., and Hayes, A. (2000) |
3 | 112 | // Coherent global motion in the absence of coherent velocity signals. |
4 | 113 | // Current Biology, 10, 679-682. |
@@ -29,11 +138,12 @@ namespace PsychlopsSilverlightApp | ||
29 | 138 | //// Declare and initialize local variables |
30 | 139 | Canvas cnvs = new Canvas(400,400); //Prepare drawing window |
31 | 140 | double dotsize = 2; |
32 | - double dot_lum = 0.5; | |
141 | + double dot_lum = 1.0; | |
33 | 142 | double bg_lum = 0.2; |
34 | 143 | double fieldsize = 300; |
35 | 144 | double[] orientation = new double[DOTNUM]; |
36 | 145 | Rectangle dots = new Rectangle(dotsize, dotsize); |
146 | + Ellipse dot = new Ellipse(dotsize*3, dotsize*3); | |
37 | 147 | ///+ prepare dots position |
38 | 148 | //// prepare dots position and paired orientation |
39 | 149 | Matrix positionmat = Matrix.gen(DOTNUM,2); |
@@ -54,7 +164,7 @@ namespace PsychlopsSilverlightApp | ||
54 | 164 | _x=i-0.5*fieldsize-50; |
55 | 165 | for(int j=0; j<fieldsize+100; j++){ |
56 | 166 | _y=j-0.5*fieldsize-50; |
57 | - envelope.alpha(i,j,1.0-Math.exp(-((_x*_x+_y*_y)/ (2.0*Math.pow(fieldsize/6.0, 2.0) )))); | |
167 | + envelope.alpha(i,j,1.0-Math.exp(-((_x*_x+_y*_y)/ (2.0*Math.pow(fieldsize/4.0, 2.0) )))); | |
58 | 168 | } |
59 | 169 | } |
60 | 170 | envelope.cache(); |
@@ -62,70 +172,105 @@ namespace PsychlopsSilverlightApp | ||
62 | 172 | ///+ set Independent |
63 | 173 | //// set variables and value ranges for interaction |
64 | 174 | Interval rng = new Interval(); |
65 | - stimulus_type = new Psychlops.Widgets.Slider("Stimulus Type", 0.0 <= rng <= 2.0, 1, 1); | |
175 | + stimulus_type = new Psychlops.Widgets.Slider("Stimulus Type", 0.0 <= rng <= 5.0, 1, 1); | |
66 | 176 | stimulus_type.setValue(0); |
67 | - distance = new Psychlops.Widgets.Slider("distance between pairs", 1 <= rng <= 100, 1, 1); | |
68 | - distance.setValue(3.0); | |
69 | - duration = new Psychlops.Widgets.Slider("Refresh", 0.0 <= rng <= 10.0, 1, 1); | |
70 | - duration.setValue(10); | |
177 | + distance = new Psychlops.Widgets.Slider("distance between pairs", 1 <= rng <= 10, 1, 1); | |
178 | + distance.setValue(4.0); | |
179 | + duration = new Psychlops.Widgets.Slider("Refresh", 0.0 <= rng <= 30.0, 1, 1); | |
180 | + duration.setValue(5); | |
71 | 181 | ///- set Independent |
72 | 182 | |
73 | 183 | int frame = 0; |
74 | - while(!Keyboard.esc.pushed()) { | |
75 | - ///+ position change | |
76 | - //// Re-randomize position with a desingated interval | |
77 | - if(frame > duration) | |
184 | + int stroke = 0; | |
185 | + bool draw_base_position = false; | |
186 | + Color col = new Color(); | |
187 | + | |
188 | + | |
189 | + ///+ initialize position | |
190 | + //// Re-randomize position with a desingated interval | |
191 | + //Math.random(positionmat, -0.5 * fieldsize, 0.5 * fieldsize); | |
192 | + positionmat.each((v) => Math.random(-0.5 * fieldsize, 0.5 * fieldsize)); | |
193 | + for (int i = 0; i < DOTNUM; i++) { orientation[i] = Math.atan2(positionmat[i + 1, 2], positionmat[i + 1, 1]); } | |
194 | + frame = 0; | |
195 | + ///- initialize position | |
196 | + | |
197 | + while (!Keyboard.esc.pushed()) | |
198 | + { | |
199 | + ///+ stroke count | |
200 | + if (frame % duration == 0) | |
78 | 201 | { |
79 | - //Math.random(positionmat, -0.5 * fieldsize, 0.5 * fieldsize); | |
80 | - positionmat.each((v) => Math.random(-0.5 * fieldsize, 0.5 * fieldsize)); | |
81 | - for (int i = 0; i < DOTNUM; i++) { orientation[i] = Math.atan2(positionmat[i + 1, 2], positionmat[i + 1, 1]); } | |
82 | - frame = 0; | |
202 | + stroke++; stroke %= 4; | |
203 | + if (stroke < 2) col.set(dot_lum); | |
204 | + else col.set(1 - dot_lum); | |
205 | + draw_base_position = (stroke % 2 == 0); | |
83 | 206 | } |
84 | - ///- position change | |
207 | + ///- stroke count | |
208 | + | |
85 | 209 | Display.clear(new Color(bg_lum)); //Clear window |
86 | 210 | |
87 | - //// Draw DOTNUM pairs of dots | |
88 | - for(int i=0; i<DOTNUM; i++){ | |
89 | - ///+ draw first dots | |
90 | - | |
91 | - ///+ switch stimulus type | |
92 | - //// draw the second dots to generate selected stimulu type. | |
93 | - switch((int)stimulus_type){ | |
94 | - ///+ case rotation | |
95 | - //// Rotation | |
96 | - case 0: | |
97 | - dots.centering().shift(positionmat[i+1,1],positionmat[i+1,2]); // move to center position | |
98 | - dots.shift(-0.5*distance*Math.cos(orientation[i]+0.5*Math.PI),-0.5*distance*Math.sin(orientation[i]+0.5*Math.PI));// move to the first position | |
99 | - dots.draw(new Color(dot_lum)); // draw first dot | |
100 | - dots.shift(distance*Math.cos(orientation[i]+0.5*Math.PI),distance*Math.sin(orientation[i]+0.5*Math.PI));// move to the second position | |
101 | - //cnvs.msg("Rotation", cnvs.getCenter().x, cnvs.getHeight() - 20); | |
102 | - break; | |
103 | - ///- case rotation | |
104 | - ///+ case diversion | |
105 | - ////Diversion | |
106 | - case 1: | |
107 | - dots.centering().shift(positionmat[i+1,1],positionmat[i+1,2]);// move to center position | |
108 | - dots.shift(-0.5*distance*Math.cos(orientation[i]+0.5*Math.PI),-0.5*distance*Math.sin(orientation[i]+0.5*Math.PI));// move to the first position | |
109 | - dots.draw(new Color(dot_lum));// draw first dot | |
110 | - dots.shift(distance*Math.cos(orientation[i]),distance*Math.sin(orientation[i]));// move to the second position | |
111 | - break; | |
112 | - ///- case diversion | |
113 | - ///+ case spiral | |
114 | - //// Spiral | |
115 | - case 2: | |
116 | - dots.centering().shift(positionmat[i+1,1],positionmat[i+1,2]);// move to center position | |
117 | - dots.shift(-0.5*distance*Math.cos(orientation[i]+0.5*Math.PI),-0.5*distance*Math.sin(orientation[i]+0.5*Math.PI));// move to the first position | |
118 | - dots.draw(new Color(dot_lum));// draw first dot | |
119 | - dots.shift(distance*Math.cos(orientation[i]+0.25*Math.PI),distance*Math.sin(orientation[i]+0.25*Math.PI));// move to the second position | |
120 | - break; | |
121 | - ///- case spiral | |
211 | + if ((int)stimulus_type <= 1) | |
212 | + { | |
213 | + for (int i = -10; i < 11; i++) | |
214 | + { | |
215 | + if (stroke % 2 == 0) | |
216 | + dot.centering().shift((stimulus_type * 2 - 1) * -distance / 2.0, i * 20); | |
217 | + else | |
218 | + dot.centering().shift((stimulus_type * 2 - 1) * distance / 2.0, i * 20); | |
219 | + dot.draw(col); | |
122 | 220 | } |
123 | - ///- switch stimulus type | |
124 | 221 | |
125 | - dots.draw(new Color(dot_lum)); // Draw dots at a desinated position. | |
222 | + } else { | |
223 | + //// Draw DOTNUM pairs of dots | |
224 | + for (int i = 0; i < DOTNUM; i++) | |
225 | + { | |
226 | + ///+ draw first dots | |
227 | + | |
228 | + ///+ switch stimulus type | |
229 | + //// draw the second dots to generate selected stimulu type. | |
230 | + switch ((int)stimulus_type) | |
231 | + { | |
232 | + ///+ case rotation | |
233 | + //// Rotation | |
234 | + case 2: | |
235 | + dots.centering().shift(positionmat[i + 1, 1], positionmat[i + 1, 2]); // move to center position | |
236 | + dots.shift(-0.5 * distance * Math.cos(orientation[i] + 0.5 * Math.PI), -0.5 * distance * Math.sin(orientation[i] + 0.5 * Math.PI));// move to the first position | |
237 | + if (draw_base_position) dots.draw(col); // draw first dot | |
238 | + dots.shift(distance * Math.cos(orientation[i] + 0.5 * Math.PI), distance * Math.sin(orientation[i] + 0.5 * Math.PI));// move to the second position | |
239 | + //cnvs.msg("Rotation", cnvs.getCenter().x, cnvs.getHeight() - 20); | |
240 | + break; | |
241 | + ///- case rotation | |
242 | + ///+ case diversion | |
243 | + ////Diversion | |
244 | + case 3: | |
245 | + dots.centering().shift(positionmat[i + 1, 1], positionmat[i + 1, 2]);// move to center position | |
246 | + dots.shift(-0.5 * distance * Math.cos(orientation[i] + 0.5 * Math.PI), -0.5 * distance * Math.sin(orientation[i] + 0.5 * Math.PI));// move to the first position | |
247 | + if (draw_base_position) dots.draw(col); // draw first dot | |
248 | + dots.shift(distance * Math.cos(orientation[i]), distance * Math.sin(orientation[i]));// move to the second position | |
249 | + break; | |
250 | + ///- case diversion | |
251 | + ///+ case spiral | |
252 | + //// Spiral | |
253 | + case 4: | |
254 | + dots.centering().shift(positionmat[i + 1, 1], positionmat[i + 1, 2]);// move to center position | |
255 | + dots.shift(-0.5 * distance * Math.cos(orientation[i] + 0.5 * Math.PI), -0.5 * distance * Math.sin(orientation[i] + 0.5 * Math.PI));// move to the first position | |
256 | + if (draw_base_position) dots.draw(col); // draw first dot | |
257 | + dots.shift(distance * Math.cos(orientation[i] + 0.25 * Math.PI), distance * Math.sin(orientation[i] + 0.25 * Math.PI));// move to the second position | |
258 | + break; | |
259 | + ///- case spiral | |
260 | + } | |
261 | + ///- switch stimulus type | |
262 | + | |
263 | + ///- draw first dots | |
264 | + | |
265 | + | |
266 | + ///+ draw second dots | |
267 | + if (!draw_base_position) dots.draw(col); // Draw dots at a desinated position. | |
268 | + ///- draw second dots | |
269 | + | |
270 | + } | |
271 | + ///- Draw dots | |
126 | 272 | } |
127 | - ///- Draw dots | |
128 | - envelope.centering().draw(); //Draw offscreen Gaussian onto screen | |
273 | + envelope.centering().draw(); | |
129 | 274 | Display.flip(); // Flip frame buffers |
130 | 275 | frame++; |
131 | 276 | } |
@@ -133,11 +278,11 @@ namespace PsychlopsSilverlightApp | ||
133 | 278 | } |
134 | 279 | } |
135 | 280 | |
136 | - | |
281 | +*/ | |
137 | 282 | |
138 | 283 | |
139 | 284 | /* |
140 | - * //Psychlops Code Template | |
285 | +//Psychlops Code Template | |
141 | 286 | // Please visit following web site to get sample codes. |
142 | 287 | // http://psychlops.sourceforge.jp/ja/?StartCode |
143 | 288 | // CodeDresser at following address is also available to view the code. |
@@ -162,7 +307,7 @@ namespace PsychlopsSilverlightApp | ||
162 | 307 | ///+ 1 Declaration ///////////////////////////////////////////////////////////// |
163 | 308 | //// 1 Declaration |
164 | 309 | // declare default window and variables for its parameters |
165 | - Canvas cnvs = new Canvas(900,600, Canvas.window, Display.primary); | |
310 | + Canvas cnvs = new Canvas(600,600, Canvas.window, Display.primary); | |
166 | 311 | double CANVAS_FRAMENUM; |
167 | 312 | int CANVAS_REFRESHRATE; |
168 | 313 | Color DEFAULT_BG_COLOR = new Color(); |
@@ -255,9 +400,9 @@ namespace PsychlopsSilverlightApp | ||
255 | 400 | } |
256 | 401 | |
257 | 402 | } |
258 | - | |
259 | 403 | */ |
260 | 404 | |
405 | + | |
261 | 406 | /* |
262 | 407 | public void psychlops_main() { |
263 | 408 |