#%% from build123d import * from ocp_vscode import * from math import sin, cos, pi import copy set_defaults(reset_camera=Camera.KEEP, render_joints=True, helper_scale=8) # %% y = 120 height = 6 pad = 2 s = 0.8 s1 = 0.7 #%% with BuildPart() as ring: with BuildSketch(Plane.XY) as sk: with BuildLine() as outline: c1 = Bezier((-pad,y,0),(-pad,y+3,0),(height+pad,y+3,0),(height+pad, y, 0)) c2 = Bezier((-pad,y,0),(-pad,y-2,0),(height+pad,y-2,0),(height+pad, y, 0)) #c1 = Spline([(-pad,y,0),(height+pad,y,0)], tangents=[(0,1),( 0,-1)], tangent_scalars=[s,s]) #c2 = Spline([(-pad,y,0),(height+pad,y,0)], tangents=[(0,-1),(0,1)], tangent_scalars=[s1,s1]) make_face() revolve(axis=Axis.X) show(ring,outline) # %% outer_ring_surface = Face.revolve(c1, 360, Axis.X) # cut ring in half and use the outer edge that got created by the cut #outer_ring_path = (copy.copy(ring.part)-(Pos(X=10+height/2)*Box(20,50,50))).edges().sort_by(Axis.X)[-1] outer_ring_path = ring.part.edges().sort_by(Axis.X)[0] show(ring,outer_ring_surface,outer_ring_path) # %% def sinus_signal(periods, width, height,n): dw = (width) / (n-1) dphi = periods * 2 * pi / (n-1) t = 0.5 # thickness pts = [( t+0.1+dw*i, t+0.1+(height/2)*(1+sin(dphi*i))) for i in range(n)] with BuildSketch() as sk: with BuildLine() as signal: Polyline(pts) offset(amount=t) make_face() return sk sig = sinus_signal(1,outer_ring_path.length/3, 5, 60) show(sig) #%% wrapped_sig = outer_ring_surface.wrap_faces(sig.faces(), outer_ring_path) show(ring, wrapped_sig) # %% width = 3 ri = 10 rm = ri+2 ro = ri+4 p = Pos(ri,0,0) def string_to_binary_string(s:str): return ''.join(["{0:08b}".format(ord(c)) for c in s]) def build_signal2D(binstring, width): hheight = height - 1 print(f"{width=} {hheight=}") n = len(binstring) dw = width/n h = 0.5 if binstring[0] == "0" else hheight pts = [(h,+ 0.5)] for i, b in enumerate(binstring): pos_flank = (b == "0" and binstring[(i+1)%n] == "1") neg_flank = (b == "1" and binstring[(i+1)%n] == "0") #print(f"{pos_flank*1}{neg_flank*1}") if pos_flank or neg_flank: x = dw*(1+i) if i < len(binstring)-1 else dw*(1+i) -0.5 pts.append((h,x)) #print(f"- {i} {b}") if pos_flank: h = hheight #print(f"^ {i} {b}") pts.append((h,x)) if neg_flank: #print(f"v {i} {b}") h = 0.5 pts.append((h,x)) #print(f"{pts = }") with BuildSketch() as sk: with BuildLine() as signal: Polyline(pts) offset(amount=0.4) make_face() #rrr = Rectangle(width, height,mode=Mode.PRIVATE) return sk # %% sig = build_signal2D("100010",outer_ring_path.length-0.0) show(sig.face()) # %% wrapped_sig = outer_ring_surface.wrap_faces(sig.faces(), outer_ring_path) show(ring, wrapped_sig) #show(sig) # %% def build_signal_A(binstring, ri): n = len(binstring) ro = ri+1 dphi =2*pi/(n+0) dp = dphi/10 dh = min(dp*ro, 18*pi/180) a = 1 tngu = lambda phi, d: (a*cos(phi), a*sin(phi), d) tngd = lambda phi, d: (-a*cos(phi), -a*sin(phi), d) with BuildPart() as signal: with BuildLine(Plane.XY) as path_builder: segments = [] h = 0 if binstring[0] == "0" else height same_bits_streak = 0 for i, b in enumerate(binstring): pos_flank = (b == "0" and binstring[(i+1)%n] == "1") neg_flank = (b == "1" and binstring[(i+1)%n] == "0") same_bits_streak += 1 if neg_flank or pos_flank or (i == n-1): phi0 = dphi*(i-same_bits_streak+1) phi1 = dphi*(i-same_bits_streak+1+0.5*same_bits_streak) phi2 = dphi*(i+1) phi0_pad = phi0 + dp phi2_pad = phi2 - dp #if segments: # segments.append(Spline(segments[-1]@1,p1, tangents=[segments[-1]%1, tngu(phi2, -1)])) segments.append(ThreePointArc( (ri * cos(phi0_pad), ri * sin(phi0_pad),h), (ri * cos(phi1), ri * sin(phi1),h), (ri * cos(phi2_pad), ri * sin(phi2_pad),h), )) same_bits_streak = 0 p1 = (ri * cos(phi2), ri * sin(phi2),height-dh) p2 = (ri * cos(phi2), ri * sin(phi2),dh) #l = segments[i] if neg_flank: h = 0 segments.append(Spline(segments[-1]@1,p1, tangents=[segments[-1]%1, tngu(phi2, -1)])) segments.append(Spline(p1,p2, tangents=[tngu(phi2, -1), tngd(phi2, -1)])) if pos_flank: h = height segments.append(Spline(p2,p1, tangents=[tngu(phi2, 1), tngd(phi2, 1)])) # l1 = segments[0] with BuildSketch(Plane( segments[0] @ 0, z_dir=segments[0] % 0)) as x_section: Circle(0.5) #return path_builder sweep(transition=Transition.ROUND) return signal def build_signal_B(binstring, ri): n = len(binstring) ro = ri+1 dphi =2*pi/(n+0) # how much angle per bit dp = 0.81/ri/pi#dphi/10 # how much of that used for curvature dh = min(dp*ro, 10*pi/180) a = 1 tngu = lambda phi, d: (a*cos(phi), a*sin(phi), d) tngd = lambda phi, d: (-a*cos(phi), -a*sin(phi), d) def build_segments(pre_segments=[]): segments = [] h = 0 if binstring[0] == "0" else height same_bits_streak = 0 i_hoz = 0 ns = len(pre_segments) for i, b in enumerate(binstring): pos_flank = b == "0" and binstring[(i+1)%n] == "1" neg_flank = b == "1" and binstring[(i+1)%n] == "0" same_bits_streak += 1 if neg_flank or pos_flank or (i == n-1): phi0 = dphi*(i-same_bits_streak+1) phi1 = dphi*(i-same_bits_streak+1+0.5*same_bits_streak) phi2 = dphi*(i+1) phi0_pad = phi0 + dp phi2_pad = phi2 - dp #if segments: # segments.append(Spline(segments[-1]@1,p1, tangents=[segments[-1]%1, tngu(phi2, -1)])) segments.append(ThreePointArc( (ri * cos(phi0_pad), ri * sin(phi0_pad),h), (ri * cos(phi1), ri * sin(phi1),h), (ri * cos(phi2_pad), ri * sin(phi2_pad),h), )) i_hoz += 1 same_bits_streak = 0 p1 = (ri * cos(phi2), ri * sin(phi2),height-dh) p2 = (ri * cos(phi2), ri * sin(phi2),dh) #l = segments[i] if neg_flank: h = 0 if pre_segments: segments.append(Spline(pre_segments[i_hoz-1]@1,p1, tangents=[pre_segments[i_hoz-1]%1, tngu(phi2, -1)])) segments.append(Spline(p1,p2, tangents=[tngu(phi2, -1), tngd(phi2, -1)])) segments.append(Spline(p2, pre_segments[i_hoz%ns]@0, tangents=[tngd(phi2, -1), pre_segments[i_hoz%ns]%0])) if pos_flank: h = height if pre_segments: segments.append(Spline(pre_segments[i_hoz-1]@1,p2, tangents=[pre_segments[i_hoz-1]%1, tngu(phi2, 1)])) segments.append(Spline(p2,p1, tangents=[tngu(phi2, 1), tngd(phi2, 1)])) segments.append(Spline(p1, pre_segments[i_hoz%ns]@0, tangents=[tngd(phi2, 1), pre_segments[i_hoz%ns]%0])) return segments pre_segments = build_segments()#??? with BuildPart() as signal: with BuildLine(Plane.XY) as path_builder: #path_builder.mode=Mode.PRIVATE segments = build_segments(pre_segments) #segments = build_segments() # l1 = segments[0] with BuildSketch(Plane(segments[0] @ 0, z_dir=segments[0] % 0)) as x_section: Circle(0.4) #Rectangle(0.8,0.8) #return path_builder sweep() #sweep(transition=Transition.ROUND) signal.label="decor" #return pre_segments return path_builder #return signal # %% #binstr = '0101100'# #binstr = '110101000'# binstr = string_to_binary_string("munsel") #binstr = string_to_binary_string("nonpostrans") signal = build_signal_B(binstr, ri+width+0.3) #show(signal,ring, transparent=True) show(signal, transparent=True) #%% product = Compound(label="ring", children=[ring.part, signal.part]) show(product)