New .polygonWall() part
Similar to .polyline() but with (f) edges on the outside .polygonWalls draws the surrounding walls
This commit is contained in:
parent
4f4d947253
commit
7aec26e893
|
@ -29,6 +29,7 @@ import re
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
from xml.sax.saxutils import quoteattr
|
from xml.sax.saxutils import quoteattr
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
|
import copy
|
||||||
|
|
||||||
from boxes import edges
|
from boxes import edges
|
||||||
from boxes import formats
|
from boxes import formats
|
||||||
|
@ -1805,6 +1806,158 @@ class Boxes:
|
||||||
|
|
||||||
self.move(overallwidth, overallheight, move)
|
self.move(overallwidth, overallheight, move)
|
||||||
|
|
||||||
|
|
||||||
|
### polygonWall and friends
|
||||||
|
|
||||||
|
def _polygonWallExtend(self, borders, edge, close=False):
|
||||||
|
posx, posy = 0, 0
|
||||||
|
ext = [ 0.0 ] * 4
|
||||||
|
angle = 0
|
||||||
|
|
||||||
|
def checkpoint(ext, x, y):
|
||||||
|
ext[0] = min(ext[0], x)
|
||||||
|
ext[1] = min(ext[1], y)
|
||||||
|
ext[2] = max(ext[2], x)
|
||||||
|
ext[3] = max(ext[3], y)
|
||||||
|
|
||||||
|
for i in range(len(borders)):
|
||||||
|
if i % 2:
|
||||||
|
try:
|
||||||
|
a, r = borders[i]
|
||||||
|
except TypeError:
|
||||||
|
angle = (angle + borders[i]) % 360
|
||||||
|
continue
|
||||||
|
centerx = posx + r * math.cos(math.radians(angle+90))
|
||||||
|
centery = posy + r * math.sin(math.radians(angle+90))
|
||||||
|
|
||||||
|
for direction in (0, 90, 180, 270):
|
||||||
|
if ((a > 0 and
|
||||||
|
angle <= direction and angle + a >= direction) or
|
||||||
|
(a < 0 and
|
||||||
|
angle >= direction and angle + a <= direction)):
|
||||||
|
checkpoint(ext, centerx + r * math.cos(math.radians(direction)), centery + r * math.sin(math.radians(direction)))
|
||||||
|
angle = (angle + a) % 360
|
||||||
|
posx = centerx + r * math.cos(math.radians(angle-90))
|
||||||
|
posy = centery + r * math.sin(math.radians(angle-90))
|
||||||
|
else:
|
||||||
|
posx += borders[i] * math.cos(math.radians(angle))
|
||||||
|
posy += borders[i] * math.sin(math.radians(angle))
|
||||||
|
checkpoint(ext, posx, posy)
|
||||||
|
|
||||||
|
ext[0] -= edge.margin()
|
||||||
|
ext[1] -= edge.margin()
|
||||||
|
ext[2] += edge.margin()
|
||||||
|
ext[3] += edge.margin()
|
||||||
|
|
||||||
|
return ext
|
||||||
|
|
||||||
|
def polygonWall(self, borders, edge="f", callback=None, move=None):
|
||||||
|
|
||||||
|
e = self.edges.get(edge, edge)
|
||||||
|
t = self.thickness # XXX edge.margin()
|
||||||
|
|
||||||
|
minx, miny, maxx, maxy = self._polygonWallExtend(borders, e)
|
||||||
|
|
||||||
|
tw, th = maxx - minx, maxy - miny
|
||||||
|
if self.move(tw, th, move, True):
|
||||||
|
return
|
||||||
|
|
||||||
|
self.moveTo(-minx, -miny)
|
||||||
|
|
||||||
|
length_correction = 0.
|
||||||
|
for i in range(0, len(borders), 2):
|
||||||
|
self.cc(callback, i)
|
||||||
|
self.edge(length_correction)
|
||||||
|
l = borders[i] - length_correction
|
||||||
|
next_angle = borders[i+1]
|
||||||
|
|
||||||
|
if isinstance(next_angle, (int, float)) and next_angle < 0:
|
||||||
|
length_correction = t * math.tan(math.radians((-next_angle / 2)))
|
||||||
|
else:
|
||||||
|
length_correction = 0.0
|
||||||
|
l -= length_correction
|
||||||
|
e(l)
|
||||||
|
self.edge(length_correction)
|
||||||
|
self.corner(next_angle, tabs=1)
|
||||||
|
|
||||||
|
self.move(tw, th, move)
|
||||||
|
|
||||||
|
@restore
|
||||||
|
def polygonWalls(self, borders, h, bottom="F", top="F", symetrical=True):
|
||||||
|
bottom = self.edges.get(bottom, bottom)
|
||||||
|
top = self.edges.get(top, top)
|
||||||
|
t = self.thickness # XXX edge.margin()
|
||||||
|
|
||||||
|
leftsettings = copy.deepcopy(self.edges["f"].settings)
|
||||||
|
lf, lF, lh = leftsettings.edgeObjects(self, add=False)
|
||||||
|
rightsettings = copy.deepcopy(self.edges["f"].settings)
|
||||||
|
rf, rF, rh = rightsettings.edgeObjects(self, add=False)
|
||||||
|
|
||||||
|
length_correction = 0.
|
||||||
|
angle = borders[-1]
|
||||||
|
i = 0
|
||||||
|
part_cnt = 0
|
||||||
|
|
||||||
|
self.moveTo(0, bottom.margin())
|
||||||
|
while i < len(borders):
|
||||||
|
if symetrical:
|
||||||
|
if part_cnt % 2:
|
||||||
|
left, right = lf, rf
|
||||||
|
else:
|
||||||
|
left, right = lF, rF
|
||||||
|
else:
|
||||||
|
left, right = lf, rF
|
||||||
|
|
||||||
|
top_lengths = []
|
||||||
|
top_edges = []
|
||||||
|
|
||||||
|
self.moveTo(left.spacing() + self.spacing, 0)
|
||||||
|
l = borders[i] - length_correction
|
||||||
|
leftsettings.setValues(self.thickness, angle=angle)
|
||||||
|
angle = borders[i+1]
|
||||||
|
|
||||||
|
while isinstance(angle, (tuple, list)):
|
||||||
|
bottom(l)
|
||||||
|
angle, radius = angle
|
||||||
|
lr = math.radians(angle) * radius
|
||||||
|
self.edges["X"](lr, h + 2*t) # XXX
|
||||||
|
top_lengths.append(l)
|
||||||
|
top_lengths.append(lr)
|
||||||
|
top_edges.append(top)
|
||||||
|
top_edges.append("E")
|
||||||
|
|
||||||
|
i += 2
|
||||||
|
l = borders[i]
|
||||||
|
angle = borders[i+1]
|
||||||
|
|
||||||
|
rightsettings.setValues(self.thickness, angle=angle)
|
||||||
|
if angle < 0:
|
||||||
|
length_correction = t * math.tan(math.radians((-angle / 2)))
|
||||||
|
else:
|
||||||
|
length_correction = 0.0
|
||||||
|
l -= length_correction
|
||||||
|
|
||||||
|
bottom(l)
|
||||||
|
|
||||||
|
top_lengths.append(l)
|
||||||
|
top_edges.append(top)
|
||||||
|
with self.saved_context():
|
||||||
|
self.edgeCorner(bottom, right, 90)
|
||||||
|
right(h)
|
||||||
|
self.edgeCorner(right, top, 90)
|
||||||
|
|
||||||
|
top_edges.reverse()
|
||||||
|
top_lengths.reverse()
|
||||||
|
edges.CompoundEdge(self, top_edges, top_lengths)(sum(top_lengths))
|
||||||
|
self.edgeCorner(top, left, 90)
|
||||||
|
left(h)
|
||||||
|
self.edgeCorner(left, bottom, 90)
|
||||||
|
|
||||||
|
self.moveTo(right.spacing() + self.spacing)
|
||||||
|
part_cnt += 1
|
||||||
|
i += 2
|
||||||
|
|
||||||
|
|
||||||
##################################################
|
##################################################
|
||||||
### Place Parts
|
### Place Parts
|
||||||
##################################################
|
##################################################
|
||||||
|
|
|
@ -584,6 +584,10 @@ class FingerJointBase:
|
||||||
if angle >=90:
|
if angle >=90:
|
||||||
return self.settings.thickness, 0
|
return self.settings.thickness, 0
|
||||||
|
|
||||||
|
if angle < 0:
|
||||||
|
return math.sin(math.radians(-angle)) * self.settings.thickness, 0
|
||||||
|
|
||||||
|
# 0 to 90
|
||||||
a = 90 - (180-angle) / 2.0
|
a = 90 - (180-angle) / 2.0
|
||||||
fingerlength = self.settings.thickness * math.tan(math.radians(a))
|
fingerlength = self.settings.thickness * math.tan(math.radians(a))
|
||||||
b = 90-2*a
|
b = 90-2*a
|
||||||
|
|
Loading…
Reference in New Issue