3 * sushivision copyright (C) 2006-2007 Monty <monty@xiph.org>
5 * sushivision is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * sushivision is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with sushivision; see the file COPYING. If not, write to the
17 * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include "sushivision.h"
29 int mult
[MAX_TEETH
+1][MAX_TEETH
+1];
36 static void inner(double *d
, double *ret
){
40 int factor_p
= rint(d
[4]);
41 double t
= d
[3]*M_PI
*2. * (factor_p
*mult
[(int)R
][(int)r
] + (1.-factor_p
)*r
);
43 ret
[0] = (R
-r
) * cos(t
) + p
* cos((R
-r
)*t
/r
);
44 ret
[1] = (R
-r
) * sin(t
) - p
* sin((R
-r
)*t
/r
);
47 static void outer(double *d
, double *ret
){
51 int factor_p
= rint(d
[4]);
52 double t
= d
[3]*M_PI
*2. * (factor_p
*mult
[(int)R
][(int)r
] + (1.-factor_p
)*r
);
54 ret
[0] = (R
+r
) * cos(t
) - p
* cos((R
+r
)*t
/r
);
55 ret
[1] = (R
+r
) * sin(t
) + p
* sin((R
+r
)*t
/r
);
58 int factored_mult(int x
, int y
){
61 if((x
/ d
* d
) == x
&& (y
/ d
* d
) == y
){
71 // the number of 'spins' we want to have a go at depends on which X
72 // dim we're iterating; if we're doing a normal spirograph, we want to
73 // factor the 'r' by 'R' and not do redundant loops. However, the
74 // loops aren't 'redundant' when iterating the other dims, so 'r'
75 // should not be factored then.
77 // we store the decision of which to do in a shadow dimension because
78 // that way access is properly managed/locked; function computation
79 // happens outside of any locks so we need to make sure a protected
80 // copy is passed, and this is an easy way.
81 int set_mult(sv_panel_t
*p
, void *user_data
){
82 sv_dim_t
*d
= sv_panel_get_axis(p
,'X');
85 // iterating on dim 3; normal spirograph mode
86 sv_dim_set_value(d4
, 1, 1.);
88 sv_dim_set_value(d4
, 1, 0.);
93 int sv_submain(int argc
, char *argv
[]){
95 for(i
=0;i
<=MAX_TEETH
;i
++)
96 for(j
=0;j
<=MAX_TEETH
;j
++)
97 mult
[i
][j
] = factored_mult(i
,j
);
99 sv_instance_t
*s
= sv_new(0,"spirograph");
101 d0
= sv_dim_new(s
,0,"ring teeth",0);
102 sv_dim_make_scale(d0
,2,(double []){11,MAX_TEETH
},NULL
,0);
103 sv_dim_set_discrete(d0
,1,1);
105 d1
= sv_dim_new(s
,1,"wheel teeth",0);
106 sv_dim_make_scale(d1
,2,(double []){7,MAX_TEETH
},NULL
,0);
107 sv_dim_set_discrete(d1
,1,1);
109 d2
= sv_dim_new(s
,2,"wheel pen",0);
110 sv_dim_make_scale(d2
,2,(double []){0,MAX_TEETH
},NULL
,0);
112 d3
= sv_dim_new(s
,3,"trace",0);
113 sv_dim_make_scale(d3
,2,(double []){0,1},(char *[]){"0%","100%"},0);
115 d4
= sv_dim_new(s
,4,"hidden mult",0);
117 sv_func_t
*f0
= sv_func_new(s
, 0, 2, inner
, 0);
118 sv_func_t
*f1
= sv_func_new(s
, 1, 2, outer
, 0);
120 sv_obj_t
*o0
= sv_obj_new(s
,0,"inner",
121 (sv_func_t
*[]){f0
,f0
},
125 sv_obj_t
*o1
= sv_obj_new(s
,1,"outer",
126 (sv_func_t
*[]){f1
,f1
},
130 sv_scale_t
*axis
= sv_scale_new(NULL
,3,(double []){-MAX_TEETH
*3,0,MAX_TEETH
*3},NULL
,0);
132 sv_panel_t
*p
= sv_panel_new_xy(s
,0,"spirograph (TM)",
134 (sv_obj_t
*[]){o0
,o1
,NULL
},
135 (sv_dim_t
*[]){d3
,d0
,d1
,d2
,NULL
},
138 sv_dim_set_value(d0
,1,100);
139 sv_dim_set_value(d1
,1,70);
140 sv_dim_set_value(d2
,1,50);
142 sv_panel_callback_recompute(p
,set_mult
,NULL
);