It appears Solaris's cc is ignoring the signedness of bitfield types.
[xiph/unicode.git] / sushivision / example_spirograph.c
blob6cc337f6cf9e4bb4963873de7ce9cb35f5497d8d
1 /*
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)
8 * any later version.
9 *
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.
22 #define _GNU_SOURCE
23 #include <stdio.h>
24 #include <math.h>
25 #include "sushivision.h"
27 #define MAX_TEETH 100
29 int mult[MAX_TEETH+1][MAX_TEETH+1];
30 sv_dim_t *d0;
31 sv_dim_t *d1;
32 sv_dim_t *d2;
33 sv_dim_t *d3;
34 sv_dim_t *d4;
36 static void inner(double *d, double *ret){
37 double R = d[0];
38 double r = d[1];
39 double p = d[2];
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){
48 double R = d[0];
49 double r = d[1];
50 double p = d[2];
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){
59 int d = 2;
60 while(d<x){
61 if((x / d * d) == x && (y / d * d) == y){
62 x/=d;
63 y/=d;
64 }else{
65 d++;
68 return 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');
84 if(d->number == 3){
85 // iterating on dim 3; normal spirograph mode
86 sv_dim_set_value(d4, 1, 1.);
87 }else{
88 sv_dim_set_value(d4, 1, 0.);
90 return 0;
93 int sv_submain(int argc, char *argv[]){
94 int i,j;
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},
122 (int []){0,1},
123 "XY", 0);
125 sv_obj_t *o1 = sv_obj_new(s,1,"outer",
126 (sv_func_t *[]){f1,f1},
127 (int []){0,1},
128 "XY", 0);
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)",
133 axis,axis,
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);
144 return 0;