diff --git a/img/speaker-microscope.jpg b/img/speaker-microscope.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0dd23ae54dac881259f7a9f4cfeb540cc41781e0 Binary files /dev/null and b/img/speaker-microscope.jpg differ diff --git a/img/speakers-green-with-plates.jpg b/img/speakers-green-with-plates.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0b826223e3a6a88af55713f91346f8a1b9a42bed Binary files /dev/null and b/img/speakers-green-with-plates.jpg differ diff --git a/img/waveforms-impedance-1.png b/img/waveforms-impedance-1.png new file mode 100644 index 0000000000000000000000000000000000000000..e969f8eb19b3ff7adf63d911d1b7487ac2b8284d Binary files /dev/null and b/img/waveforms-impedance-1.png differ diff --git a/script/2018.12.26-speaker.py b/script/2018.12.26-speaker.py new file mode 100644 index 0000000000000000000000000000000000000000..822cadbe85ff439db91f410b63a148b58e5939f2 --- /dev/null +++ b/script/2018.12.26-speaker.py @@ -0,0 +1,195 @@ +#!/usr/bin/env python +from __future__ import division,absolute_import +import rhinoscriptsyntax as rs +from math import * +import sys + +#simple class for vec2 +class V2(object): + def __init__(self,*args): + if len(args)>1: + self.x = args[0] + self.y = args[1] + else: + self.x = args[0][0] + self.y = args[0][1] + self.p3l = [self.x,self.y,0] + def __add__(self,other): + return V2(self.x+other.x,self.y+other.y) + def __sub__(self,other): + return V2(self.x-other.x,self.y-other.y) + def __mul__(self,other): + try: + return V2(self.x*other.x,self.y*other.y) + except(AttributeError): + return V2(self.x*other,self.y*other) + def __rmul__(self,other): + try: + return V2(self.x*other.x, self.y*other.y) + except(AttributeError): + return V2(self.x*other,self.y*other) + def __getitem__(self,index): + return [self.x,self.y][index] + def __repr__(self): + return "V2(%.6f,%.6f)"%(self.x,self.y) + def rotate(self,th): + return V2(self.x*cos(th)-self.y*sin(th), self.x*sin(th)+self.y*cos(th)) + def rotate90(self): + return V2(-self.y,self.x) + def rotate_p(self,b,th): + return b + (self-b).rotate(th) + def magnitude(self): + return sqrt(self.x*self.x + self.y*self.y) + def normalized(self): + return self*(1./self.magnitude()) + def dot(self,other): + return self.x*other.x + self.y*other.y + def cross(self,other): + return self.x*other.y - self.y*other.x + def angle_between(self,other): + #unsigned angle between two vectors + c = self.cross(other) + return atan2(c,self.dot(other)) + def projected_onto(self,other): + return ((self.dot(other))/(other.dot(other)))*other + def projected_orthogonal_to(self,other): + return self - self.projected_onto(other) + + def close(self,other,tol=1e-6): + return (abs(self.x-other.x)<tol) and (abs(self.y-other.y)<tol) + def p3lz(self,z): + return [self.x,self.y,z] + +# a few helper functions +def line(p1,p2,layer,bridge_w=0,cut_w=0): + d = p2-p1; dl = d.magnitude() + if dl==0: + return None + dn = d.normalized() + if bridge_w==0 or cut_w==0: + rs.CurrentLayer(layer) + return rs.AddLine(p1.p3l, p2.p3l) + else: + rs.CurrentLayer(layer) + output = []; dist = bridge_w + ds = [] + while dist < dl-2*bridge_w:#-cut_w: + ds.append((dist, dist+cut_w)) + #print bridge_w, (p1+dist*dn).p3l , (p1+(dist+bridge_w)*dn).p3l + dist += cut_w+bridge_w + #leftover = dl-bridge_w-cut_w - dist + cut_w+bridge_w + leftover = dl-bridge_w - dist + cut_w+bridge_w + for pair in ds: + output.append(rs.AddLine( (p1+(pair[0] + leftover/2)*dn).p3l , (p1+(pair[1]+ leftover/2)*dn).p3l) ) + + return output +def circle(c,d,layer): + rs.CurrentLayer(layer) + return rs.AddCircle(c.p3l, .5*d) +def arc(c,d,th1,th2,layer): + rs.CurrentLayer(layer) + p1 = c + d/2*V2(cos(pi/180.*th1),sin(pi/180.*th1)) + p2 = c + d/2*V2(cos(pi/180.*th2),sin(pi/180.*th2)) + pm = c + d/2*V2(cos(pi/180.*(th1+th2)/2),sin(pi/180.*(th1+th2)/2)) + return rs.AddArc3Pt(p1.p3l,p2.p3l,pm.p3l) +def filleted_hex(c,R,r,layer): + crvs = [] + x = r/sqrt(3) + for i in range(6): + v0 = R*V2(cos(i*2*pi/6),sin(i*2*pi/6)) + v1 = R*V2(cos((i+1)*2*pi/6),sin((i+1)*2*pi/6)) + d = (v1 - v0).normalized() + crvs.append( line( c+v0 + x*d, c+v1 - x*d, layer) ) + crvs.append( arc( c+v0-2*x*v0.normalized(),2*r,-30+i*60,30+i*60, layer) ) + return crvs + + + + + + +#main +def main(): + rs.AddLayer('magnets_a',(255,0,0)) + rs.AddLayer('magnets_b',(0,255,255)) + rs.AddLayer('holes',(0,255,0)) + rs.AddLayer('coils',(0,0,255)) + rs.AddLayer('frame',(255,0,255)) + + mag_d = 3.3 #mm, diameter of magnets, as cut by laser + hole_d = 6 #mm, diameter of air hole + s = 6 #mm, hex lattice side length (2xmag_d?) + s32 = s*sqrt(3)/2. + frame_inner = 60 #mm, radius / side length of inner hex of frame + frame_inner_fillet = 10 #mm, fillet radius + frame_outer = 80 #mm, radius / side length of outer hex of frame + frame_outer_fillet = 20 #mm, fillet radius + frame_bolt_d = 4.1 #mm, diameter of bolt holes + + wire_pitch = 2*.088 #mm, pitch, .088 = measured diameter (.080) + .008 mm slop (10% applied) + N = 19 #number of turns, must be odd + Nr = 4 #number of radial layers in the hex lattice + lead_length = 20 + + #make frame + frame = [] + frame += filleted_hex(V2(0,0), frame_inner, frame_inner_fillet, 'frame') + frame += filleted_hex(V2(0,0), frame_outer, frame_outer_fillet, 'frame') + for i in range(6): + v0 = .5*(frame_inner+frame_outer)*V2(cos(i*2*pi/6),sin(i*2*pi/6)) + v1 = .5*(frame_inner+frame_outer)*V2(cos((i+1)*2*pi/6),sin((i+1)*2*pi/6)) + frame += [ + circle(v0, frame_bolt_d, 'frame'), + circle(.5*(v0+v1), frame_bolt_d, 'frame'), + ] + + #for each of the (2*Nr-1)*(Nr) points in the grid, what are the starting and ending angles + coil_params=[ + [(90,330), (150,30), (210,360+90), (270,360+30), (210,90), (270,30), (210,360+90), (150,270)], + [(90,330), (270,360+150), (330,450), (270,150), (330,90), (270,360+150), (330,360+90), (150,270)], + [(210,330), (360+150,270), (330,450), (270,150), (330,90), (270,360+150), (330,360+90), (150,270)], + [(360+210,330), (150,360+30), (360+210,330), (270,150), (330,90), (270,360+150), (330,360+90), (150,270)], + ] + + #make magnet grid, air holes, and coils + crvs = []; + crvs += [circle(V2(0,0),mag_d,'magnets_a')] + for i in range(3): #3-fold angular symmetry + vr = V2(cos(i*2*pi/3),sin(i*2*pi/3)) + vth = V2(cos(i*2*pi/3+pi/2),sin(i*2*pi/3+pi/2)) + vk = V2(cos((i+1)*2*pi/3),sin((i+1)*2*pi/3)) + for j in range(Nr+1): + for k in range(Nr+1): + crvs += [circle(2*s32*vr*j + 2*s32*vk*k + s*vth, hole_d, 'holes')] + if j < Nr: + crvs += [circle(2*s32*vr*(j+1) + 2*s32*vk*k, mag_d, 'magnets_a')] + if k<Nr: + crvs += [ + circle(2*s32*vr*(j+.5) + 2*s32*vk*k + .5*s*vth, mag_d, 'magnets_b') + ] + + #coils + for l in range(N): + dd = (l - (N-1)/2)*wire_pitch + crvs += [ arc(2*s32*vr*(j+.5) + 2*s32*vk*k + .5*s*vth, s+dd, coil_params[k][2*j][0]+i*120, coil_params[k][2*j][1]+i*120,'coils' ) ] + if j<Nr-1 or k>0: + crvs += [ arc(2*s32*vr*(j+1) + 2*s32*vk*k, s+dd, coil_params[k][2*j+1][0]+i*120, coil_params[k][2*j+1][1]+i*120,'coils' ) ] + + #make traverses + for l in range(N): + dd = (l - (N-1)/2)*wire_pitch + crvs += [ arc(2*s32*(vr+vk)*Nr, s+dd, 270+i*120, 180+i*120,'coils' ) ] + crvs += [ arc(2*s32*vr*(Nr-1) + 2*s32*Nr*vk, s+dd, 270+i*120, 360+i*120,'coils' ) ] + if l<N-1: + crvs += [ arc(2*s32*vr*(Nr-.5) + 2*s32*Nr*vk - .25*wire_pitch*vr, s*(sqrt(3)-1)+dd+.5*wire_pitch, 180+i*120, 0+i*120,'coils' ) ] + #make leads + v0 = 2*s32*vr*(Nr-.5) + 2*s32*Nr*vk - .25*wire_pitch*vr + r0 = .5*(s*(sqrt(3)-1) - N/2.*wire_pitch)*vr + r1 = .5*(s*(sqrt(3)-1) + N/2.*wire_pitch)*vr + crvs += [ + line( v0-r0, v0-r0+lead_length*vth, 'coils' ), + line( v0+r1, v0+r1+lead_length*vth, 'coils' ), + ] + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/script/2018.12.7-hex-speaker.py b/script/2018.12.7-hex-speaker.py index 90c692e5384fdb4e6f527c07fdb063359f7de459..322b48478beda1b47f8a6c809c8b6bdc1d988566 100644 --- a/script/2018.12.7-hex-speaker.py +++ b/script/2018.12.7-hex-speaker.py @@ -94,30 +94,6 @@ def arc(c,d,th1,th2,layer): return rs.AddArc3Pt(p1.p3l,p2.p3l,pm.p3l) -def make_rectangular_spiral(x,y,h,w,R,pitch,N): - rs.CurrentLayer('coil') - r = R - hw = w/2; hh = h/2 - crvs = [ ] - for i in range(N): - #r -= pitch/2 - r2 = r*(1-1/sqrt(2)) - crvs.append( line( V2(-hw+(i+0)*pitch,hh-r), V2(-hw+(i+.5)*pitch,-hh+r), 'coil' ) ) - crvs.append( rs.AddArc3Pt( [-hw+(i+.5)*pitch,-hh+r,0], [-hw+r,-hh+(i+.5)*pitch,0], [-hw+r2+(i+.5)*pitch/sqrt(2),-hh+r2+(i+.5)*pitch/sqrt(2),0] ) ) - crvs.append( line(V2(-hw+r,-hh+(i+.5)*pitch), V2(hw-r,-hh+(i+.5)*pitch), 'coil' ) ) - crvs.append( rs.AddArc3Pt( [hw-r,-hh+(i+.5)*pitch,0], [hw-(i+.5)*pitch,-hh+r,0], [hw-r2-(i+.5)*pitch/sqrt(2),-hh+r2+(i+.5)*pitch/sqrt(2),0] ) ) - crvs.append( line( V2(hw-(i+.5)*pitch,-hh+r), V2(hw-(i+1)*pitch,hh-r), 'coil' ) ) - if i<N-1: - crvs.append( rs.AddArc3Pt( [hw-(i+1)*pitch,hh-r,0], [hw-r,hh-(i+1)*pitch,0], [hw-r2-(i+1)*pitch/sqrt(2),hh-r2-(i+1)*pitch/sqrt(2),0] ) ) - crvs.append( line(V2(hw-r,hh-(i+1)*pitch), V2(-hw+r,hh-(i+1.)*pitch), 'coil' ) ) - crvs.append( rs.AddArc3Pt( [-hw+r,hh-(i+1.)*pitch,0], [-hw+(i+1.)*pitch,hh-r,0], [-hw+r2+(i+1.)*pitch/sqrt(2),hh-r2-(i+1.)*pitch/sqrt(2),0] ) ) - #crvs.append( line( V2(hw-(N+0)*pitch,-hh+r), V2(hw-(N+.25)*pitch,hh-r), 'coil' ) ) - result = rs.JoinCurves(crvs) - rs.DeleteObjects(crvs) - rs.MoveObjects(result,[x,y,0]) - return result - - def main(): rs.AddLayer('magnets',(255,0,0)) rs.AddLayer('holes',(0,255,0))