Skip to content
Snippets Groups Projects
Select Git revision
  • 51fc0bd97b2bd574464606ca6717b5016a7071b7
  • master default protected
2 results

index.html

Blame
  • 2018.12.26-speaker.py 6.52 KiB
    #!/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()