Skip to content
Snippets Groups Projects
2018.12.7-hex-speaker.py 4.65 KiB
Newer Older
Sam Calisch's avatar
Sam Calisch committed
#!/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]


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 main():
	rs.AddLayer('magnets',(255,0,0))
	rs.AddLayer('holes',(0,255,0))
	rs.AddLayer('coils',(0,0,255))

	mag_d = 3 #mm, diameter of magnets
	hole_d = 8 #mm, diameter of air hole
	s = 6 #mm, hex side length (2xmag_d?)
	#lead_in = 25 #mm, lead in length
	#phase_extension = 1 #mm, extension of each phase for overpass and turnaround
	#wire_pitch = .22 #mm, pitch, .22 = 34 awg measured diameter (.2) + .02mm slop (determined empirically)
	wire_pitch = 2*.088 #mm, pitch, .088 = measured diameter (.080) + .008 mm slop (10% applied)
	N = 11 #number of turns
	Nx = 3 #number of cells in x direction,
	Ny = 6 #number of cells in y direction

	s32 = s*sqrt(3)/2.

	magnets = []; holes = []; coils = [];
	for i in range(Nx):
		x0 = i*3*s + s
		for j in range(Ny):
			y0 = j*2*s32
			magnets += [
				circle(V2(x0-s/2,y0+s32),mag_d,'magnets'),
				circle(V2(x0,y0),mag_d,'magnets'),
				circle(V2(x0+s,y0),mag_d,'magnets'),
				circle(V2(x0+3*s/2,y0+s32),mag_d,'magnets')
				]
			holes += [circle(V2(x0+s/2,y0+s32),hole_d,'holes')]
			if i<Nx-1:
				holes += [circle(V2(x0+2*s,y0),hole_d,'holes')]
			if j%2==0:
				for k in range(N):
					kk = -(N-1)/2+k
					coils += [
						arc(V2(x0-s/2,y0+s32),s+kk*wire_pitch,180,300,'coils') if i>0 else arc(V2(x0,y0),s-kk*wire_pitch,240,120,'coils'),
						arc(V2(x0,y0),s-kk*wire_pitch,120,0,'coils'),
						arc(V2(x0+s,y0),s+kk*wire_pitch,180,420,'coils'),
						arc(V2(x0+3*s/2,y0+s32),s-kk*wire_pitch,240,0 if i<Nx-1 else 120,'coils'),
					]
			else:
				for k in range(N):
					kk = -(N-1)/2+k
					coils += [
						arc(V2(x0-s/2,y0+s32),s+kk*wire_pitch,180 if i>0 else 60,-60,'coils'),
						arc(V2(x0,y0),s-kk*wire_pitch,120,360,'coils'),
						arc(V2(x0+s,y0),s+kk*wire_pitch,180,60,'coils'),
						arc(V2(x0+3*s/2,y0+s32),s-kk*wire_pitch,240,360,'coils') if i<Nx-1 else arc(V2(x0+s,y0),s+kk*wire_pitch,60,-60,'coils'),
					]				


if __name__ == '__main__':
	main()