@@ -69,7 +69,8 @@ def de_ambiguous(
6969 box : Cbox , terminals : list [Terminal ], bom_data : list [BOMData ], ** options
7070 ):
7171 if len (bom_data ) > 1 :
72- raise BOMError (f"Ambiguous BOM data for { box .type } { box .id } : { bom_data !r} " )
72+ raise BOMError (
73+ f"Ambiguous BOM data for { box .type } { box .id } : { bom_data !r} " )
7374 if not bom_data :
7475 bom_data = [BOMData (box .type , box .id , "" )]
7576 return func (box , terminals , bom_data [0 ], ** options )
@@ -111,7 +112,8 @@ def resistor(box: Cbox, terminals: list[Terminal], bom_data: BOMData, **options)
111112 quad_angle = angle + pi / 2
112113 points = [t1 ]
113114 for i in range (1 , 4 * int (length )):
114- points .append (t1 - rect (i / 4 , angle ) + pow (- 1 , i ) * rect (1 , quad_angle ) / 4 )
115+ points .append (t1 - rect (i / 4 , angle ) + pow (- 1 , i )
116+ * rect (1 , quad_angle ) / 4 )
115117 points .append (t2 )
116118 return (
117119 polylinegon (points , ** options )
@@ -323,7 +325,8 @@ def integrated_circuit(
323325 x = sc_text_pt .real ,
324326 y = sc_text_pt .imag ,
325327 text__anchor = (
326- "start" if (terminal .side in (Side .TOP , Side .BOTTOM )) else "middle"
328+ "start" if (terminal .side in (
329+ Side .TOP , Side .BOTTOM )) else "middle"
327330 ),
328331 font__size = options ["scale" ],
329332 fill = options ["stroke" ],
@@ -415,7 +418,8 @@ def transistor(box: Cbox, terminals: list[Terminal], bom_data: BOMData, **option
415418 (sp , mid - rect (0.8 , theta )), # Lead out
416419 ]
417420 if "fet" in silicon_type :
418- arr = mid + rect (0.8 , theta ), mid + rect (0.8 , theta ) + rect (0.7 , thetaquarter )
421+ arr = mid + rect (0.8 , theta ), mid + \
422+ rect (0.8 , theta ) + rect (0.7 , thetaquarter )
419423 if "nfet" == silicon_type :
420424 arr = arr [1 ], arr [0 ]
421425 out_lines .extend (
@@ -436,7 +440,8 @@ def transistor(box: Cbox, terminals: list[Terminal], bom_data: BOMData, **option
436440 ]
437441 )
438442 else :
439- arr = mid + rect (0.8 , theta ), mid + rect (0.4 , theta ) + rect (1 , thetaquarter )
443+ arr = mid + rect (0.8 , theta ), mid + \
444+ rect (0.4 , theta ) + rect (1 , thetaquarter )
440445 if "npn" == silicon_type :
441446 arr = arr [1 ], arr [0 ]
442447 out_lines .extend (
@@ -468,7 +473,8 @@ def ground(box: Cbox, terminals: list[Terminal], bom_data: BOMData, **options):
468473 points = [(0 , 1j ), (- 0.5 + 1j , 0.5 + 1j )]
469474 match icon_type :
470475 case "earth" :
471- points += [(- 0.33 + 1.25j , 0.33 + 1.25j ), (- 0.16 + 1.5j , 0.16 + 1.5j )]
476+ points += [(- 0.33 + 1.25j , 0.33 + 1.25j ),
477+ (- 0.16 + 1.5j , 0.16 + 1.5j )]
472478 case "chassis" :
473479 points += [
474480 (- 0.5 + 1j , - 0.25 + 1.5j ),
@@ -485,6 +491,61 @@ def ground(box: Cbox, terminals: list[Terminal], bom_data: BOMData, **options):
485491 return bunch_o_lines (points , ** options )
486492
487493
494+ @component ("S" , "SW" , "PB" )
495+ @n_terminal (2 )
496+ @no_ambiguous
497+ def switch (box : Cbox , terminals : list [Terminal ], bom_data : BOMData , ** options ):
498+ """Draw a mechanical switch symbol.
499+ bom:{nc/no}[m][:label]"""
500+ icon_type = bom_data .data or "no"
501+ if ":" in icon_type :
502+ icon_type , * b = icon_type .split (":" )
503+ bom_data = BOMData (bom_data .type , bom_data .id , ":" .join (b ))
504+ else :
505+ bom_data = BOMData (bom_data .type , bom_data .id , "" )
506+ t1 , t2 = terminals [0 ].pt , terminals [1 ].pt
507+ mid = (t1 + t2 ) / 2
508+ angle = phase (t1 - t2 )
509+ quad_angle = angle + pi / 2
510+ scale = options ["scale" ]
511+ out = (XML .circle (
512+ cx = (rect (- scale , angle ) + mid * scale ).real ,
513+ cy = (rect (- scale , angle ) + mid * scale ).imag ,
514+ r = scale / 4 ,
515+ stroke = "transparent" ,
516+ fill = options ["stroke" ],
517+ class_ = "filled" ,
518+ ) + XML .circle (
519+ cx = (rect (scale , angle ) + mid * scale ).real ,
520+ cy = (rect (scale , angle ) + mid * scale ).imag ,
521+ r = scale / 4 ,
522+ stroke = "transparent" ,
523+ fill = options ["stroke" ],
524+ class_ = "filled" ,
525+ ) + bunch_o_lines ([(t1 , mid + rect (1 , angle )), (t2 , mid + rect (- 1 , angle ))], ** options ))
526+ sc = 1
527+ match icon_type :
528+ case "nc" :
529+ points = [(- 1j , - .3 + 1j )]
530+ case "no" :
531+ points = [(- 1j , - .8 + 1j )]
532+ sc = 1.9
533+ case "ncm" :
534+ points = [(.3 - 1j , .3 + 1j )]
535+ out += polylinegon (deep_transform ([- .5 + .6j , - .5 - .6j , .3 - .6j , .3 + .6j ], mid , angle ), True , ** options )
536+ sc = 1.3
537+ case "nom" :
538+ points = [(- .5 - 1j , - .5 + 1j )]
539+ out += polylinegon (deep_transform ([- 1 + .6j , - 1 - .6j , - .5 - .6j , - .5 + .6j ], mid , angle ), True , ** options )
540+ sc = 2.5
541+ case _:
542+ raise BOMError (f"Unknown switch symbol type: { icon_type } " )
543+ points = deep_transform (points , mid , angle )
544+ return bunch_o_lines (points , ** options ) + out + id_text (
545+ box , bom_data , terminals , None , make_text_point (
546+ t1 , t2 , ** (options | {"offset_scaler" : sc })), ** options )
547+
548+
488549# code for drawing stuff
489550# https://github.com/pfalstad/circuitjs1/tree/master/src/com/lushprojects/circuitjs1/client
490551# https://github.com/KenKundert/svg_schematic/blob/0abb5dc/svg_schematic.py
0 commit comments