@@ -894,28 +894,30 @@ def checkValues(self) -> None:
894894 if abs (self .space + self .finger ) < 0.1 :
895895 raise ValueError ("FingerJointSettings: space + finger must not be close to zero" )
896896
897- def edgeObjects (self , boxes , chars : str = "fFh " , add : bool = True ):
897+ def edgeObjects (self , boxes , chars : str = "fFhƒ " , add : bool = True ):
898898 edges = [FingerJointEdge (boxes , self ),
899899 FingerJointEdgeCounterPart (boxes , self ),
900900 FingerHoleEdge (boxes , self ),
901+ TriFingerJointEdge (boxes , self ),
901902 ]
902903 return self ._edgeObjects (edges , boxes , chars , add )
903904
904905
905906class FingerJointBase (ABC ):
906907 """Abstract base class for finger joint."""
908+ finger_factor = 1
907909
908910 def calcFingers (self , length : float , bedBolts ) -> tuple [int , float ]:
909911 space , finger = self .settings .space , self .settings .finger # type: ignore
910- fingers = int ((length - (self .settings .surroundingspaces - 1 ) * space ) // (space + finger )) # type: ignore
912+ fingers = int ((length - (self .settings .surroundingspaces - 1 ) * space ) // (space + self . finger_factor * finger )) # type: ignore
911913 # shrink surrounding space up to half a thickness each side
912914 if fingers == 0 and length > finger + 1.0 * self .settings .thickness : # type: ignore
913915 fingers = 1
914916 if not finger :
915917 fingers = 0
916918 if bedBolts :
917919 fingers = bedBolts .numFingers (fingers )
918- leftover = length - fingers * (space + finger ) + space
920+ leftover = length - fingers * (space + self . finger_factor * finger ) + space
919921
920922 if fingers <= 0 :
921923 fingers = 0
@@ -983,6 +985,20 @@ def draw_finger(self, f, h, style, positive: bool = True, firsthalf: bool = True
983985 else :
984986 self .polyline (0 , 90 , h , - 90 , f , - 90 , h , 90 )
985987
988+ def addTriFingerSpace (self , i , fingers , pattern ) -> bool :
989+ # no double finger - no space
990+ if self .finger_factor == 1 :
991+ return False
992+ # ensure symmetric pattern
993+ j = min (i , fingers - i - 1 )
994+ # check if space is needed
995+ if (j % 2 ) == 0 and pattern == 'A' :
996+ return True
997+ if (j % 2 ) == 1 and pattern == 'B' :
998+ return True
999+ # otherwise no space
1000+ return False
1001+
9861002 def __call__ (self , length , bedBolts = None , bedBoltSettings = None , ** kw ):
9871003
9881004 positive = self .positive
@@ -1025,8 +1041,12 @@ def __call__(self, length, bedBolts=None, bedBoltSettings=None, **kw):
10251041 self .bedBoltHole (s , bedBoltSettings )
10261042 else :
10271043 self .edge (s )
1044+ if self .addTriFingerSpace (i , fingers , 'B' ):
1045+ self .edge (f )
10281046 self .draw_finger (f , h , style ,
10291047 positive , i < fingers // 2 )
1048+ if self .addTriFingerSpace (i , fingers , 'A' ):
1049+ self .edge (f )
10301050
10311051 self .edge (leftover / 2.0 , tabs = 1 )
10321052
@@ -1088,14 +1108,14 @@ def __call__(self, x, y, length, angle=90, bedBolts=None, bedBoltSettings=None):
10881108 self .ctx .rectangle (b , - self .settings .width / 2 + b ,
10891109 length - 2 * b , self .settings .width - 2 * b )
10901110 for i in range (fingers ):
1091- pos = leftover / 2.0 + i * (s + f )
1111+ pos = leftover / 2.0 + i * (s + self . finger_factor * f )
10921112
10931113 if bedBolts and bedBolts .drawBolt (i ):
10941114 d = (bedBoltSettings or self .boxes .bedBoltSettings )[0 ]
10951115 self .boxes .hole (pos - 0.5 * s , 0 , d * 0.5 )
10961116
1097- self .boxes .rectangularHole (pos + 0.5 * f , 0 ,
1098- f + p , self .settings .width + p )
1117+ self .boxes .rectangularHole (pos + 0.5 * self . finger_factor * f , 0 ,
1118+ self . finger_factor * f + p , self .settings .width + p )
10991119
11001120
11011121class FingerHoleEdge (BaseEdge ):
@@ -1156,6 +1176,29 @@ def startWidth(self) -> float:
11561176 return self .outset
11571177
11581178
1179+ # The TriFingerJoint can be used to join two edges from oposing sides into a
1180+ # single wall. The holes in the wall have doubled length and the fingers have
1181+ # two spaces (one space sized and on finger sizes). For each hole the order of
1182+ # the fingers changes, to ensure a tight fit, if only one side is used. joint
1183+ # will like like the following:
1184+ # w = wall, l/r = fingers from left/right side
1185+ # lr w rl w lr w ... w rl w lr
1186+ # Note: the order of the pairs "lr" and "rl" is kepts symmetric. This causes a
1187+ # rectangularWall() with two opposing TriFingerJointEdges to cover the left and
1188+ # right sied, as the edges of an rectangularWall() are printed clockwise.
1189+ class TriFingerJointEdge (FingerJointEdge ):
1190+ """Tri finger joint edge"""
1191+ char = 'ƒ'
1192+ description = "Tri Finger Joint"
1193+ finger_factor = 2
1194+
1195+
1196+ class TriFingerHoles (FingerHoles ):
1197+ """Hole matching a tri finger joint edge"""
1198+ description = "Edge (parallel Tri Finger Joint Holes)"
1199+ finger_factor = 2
1200+
1201+
11591202#############################################################################
11601203#### Stackable Joints
11611204#############################################################################
0 commit comments