//gear sizes parametric search

//mechanical requirements:
macc=45/180*%pi;//acceptance angle at least +-45 deg
mss=1.5875; //magnet cube side 1/16" = 1.5875 mm
//fixed gear inner diameter between 30 mm and 60 mm
//spinning gear diameter between 20 mm and 30 mm
//fixed and spinning gear teeth is even (multiple of 2)
snum_min=ceil(((20-2*mss)*%pi/mss)/2)*2; //minimum number of magnets on spinning gear
sod_min=((mss/2)/sin(%pi/snum_min)+mss)*2; //minimum spinning gear OD
snum_max=floor(((30-2*mss)*%pi/mss)/2)*2; //maximum number of magnets on spinning gear
sod_max=((mss/2)/sin(%pi/snum_max)+mss)*2; //minimum spinning gear OD
snum_nr=snum_min:2:snum_max; //available spinning gear tooth numbers

gout=[];

for(sn=snum_nr)
    //rs=sn*mss/(2*%pi)+mss; //approximate radius
    ro=(mss/2)/tan(%pi/sn);
    rh=(mss/2)/sin(%pi/sn);
    rs=rh*(ro+mss)/ro; //outer radius enclosing spinning gear
    rf=rs/tan(macc); //approximate minimum radius of fixed gear to match acceptance angle
    fod_min=rf*2;
    if(fod_min<30)
        fod_min=30;
    end
    fnum_min=ceil(((fod_min-mss)*%pi/mss)/2)*2; //minimum number of magnets on fixed gear
    fnum_max=floor(((60-mss)*%pi/mss)/2)*2; //maximum number of magnets on fixed gear
    fnum_nr=fnum_min:2:fnum_max;
    nmm=[1,2,3,4];//number of mirrors to test
    for(fn=fnum_nr)
        gx(1)=double(lcm([fn*nmm(1), sn]))/(fn*nmm(1));
        gx(2)=double(lcm([fn*nmm(2), sn]))/(fn*nmm(2));
        gx(3)=double(lcm([fn*nmm(3), sn]))/(fn*nmm(3));
        gx(4)=double(lcm([fn*nmm(4), sn]))/(fn*nmm(4));
        sd_revs=(sn/fn)./nmm; //number of primary revolutions before secondary mirror is horizontal and rising (any side)
        ps_revs=gx'./sd_revs; //number of acceptance windows
        ds=(2*%pi*(rs+0.5))/sn;//spacing of ds teeth at 0.5 mm away from gear
        fc=ds*fn;//expected central circumference of fixed gear
        fd=fc/%pi;
        fq=(fd/2)*cos(%pi/fn);
        fs=(fd/2)*sin(%pi/fn)*2;
        fs=fs*(fq-mss/2)/fq; //actual side length of fixed gear
        fod=fd*(fq+mss/2)/fq; //circle that will fit the fixed gear OD
        fid=(fq-mss/2)*2; //circle inside the fixed gear ID
        acc=90-atan(rs,fod/2)/%pi*180; //[deg] actual acceptance angle
        gout($+1,:)=[fn,sn,gx',rs*2,fs,fod,fid,acc,ps_revs];
    end
end

//more filters
//gfout=gout;
//gfout=gout(modulo(gout(:,13),4)==0 & gout(:,5)<7,:);
//gfout(gfout(:,3)<>gfout(:,5),:)=[];
//gfout(gfout(:,3)<>gfout(:,4),:)=[];
//gfout(gfout(:,4)>6,:)=[];
//gfout(gfout(:,4)<2,:)=[];
//gfout(gfout(:,7)<mss,:)=[];
//gfout(modulo(gfout(:,13),2)~=0,:)=[];

//final conclusion: 64 fixed, 40 spinning, 3 mirrors, 94 lasers = multiplication factor of 6 with 24 acceptance windows or projected pixel pitch of ~4 cm and update rate of 12 Hz single or 24 Hz double; resolution 564x108 pixels
//or possibly even better: 64 fixed, 36 spinning, 3 mirrors, 94 lasers = multiplication factor of 4 with 16 acceptance windows or projected pixel pitch of ~5 cm and update rate of 20 Hz single or 40 Hz double; resolution 376x97 pixels and 3-fold degeneracy. Even though the resolution here is worse compared to above, the pixels are more evenly matched to a 4x1 ratio desired for a spherical projection, and the update rate is exceeding 20 Hz so there will be less flickering and more power delivered so a brighter appearance.
//smaller acceptance windows of 22.5 and 30 degrees allow 4 mirrors to be used for 100% timing efficiency but no appreciably better combinations were found

//for a complete profile (no gaps or overlaps), the number of acceptance windows should be divisible by the same number as required to fill 360 degrees (so with +-45 deg acceptance it should be divisible by 4, and with +-30 deg acceptance it should be divisible by 6), and the multiplication factor is the result of this division
//the number of lasers must then be chosen to match the phasing of the acceptance windows and not overlap
//Rule for CNO: gcd(2*L,W)=C where L=num_lasers, W=acc_wind, C=360deg/(acceptance)
