sketch-a-day/2019/sketch_190408a/sketch_190408a.pyde

229 wiersze
5.9 KiB
Python

# Alexandre B A Villares - https://abav.lugaralgum.com/sketch-a-day
SKETCH_NAME, OUTPUT = "sketch_190408a", ".gif"
"""
With glue tabs!
"""
# add_library('GifAnimation')
# from gif_exporter import gif_export
# add_library('peasycam')
from third_point import third_point
CUT_COLOR = color(200, 0, 0) # Color to mark outline cut
ENG_COLOR = color(0, 0, 200) # Color to mark folding/engraving
TAB_W = 10 # tab width
TAB_A = radians(30) # tab angle
box_d, box_w, box_h = 100, 100, 100 # initial values
ah = bh = ch = dh = box_h
def setup():
size(850, 500, P3D)
#global cam
# cam = PeasyCam(this, 300)
hint(ENABLE_DEPTH_SORT)
smooth(16)
strokeWeight(2)
def draw():
background(200)
# cam.beginHUD()
with pushMatrix():
translate(100, 350)
draw_unfolded()
# cam.endHUD()
with pushMatrix():
translate(width / 2, height / 2) # comment out if with PeasyCam
rotateX(QUARTER_PI)
rotateZ(PI)
translate(-300, -50, -100)
draw_3d()
def draw_unfolded():
bh_2d = (0, -bh)
b0_2d = (0, 0)
ch_2d = (box_w, -ch)
c0_2d = (box_w, 0)
dh_2d = (box_w + box_d, -dh)
d0_2d = (box_w + box_d, 0)
ah_2d = (box_w * 2 + box_d, -ah)
a0_2d = (box_w * 2 + box_d, 0)
noFill()
stroke(ENG_COLOR) # Marked for folding
# verticals
line_draw(b0_2d, bh_2d)
line_draw(c0_2d, ch_2d)
line_draw(d0_2d, dh_2d)
line_draw(a0_2d, ah_2d)
# lower triangle
bd = dist(0, 0, bh, box_w, box_d, dh)
cd = dist(box_w, 0, ch, box_w, box_d, dh)
d2_2d = third_point(bh_2d, ch_2d, bd, cd)[0] # gets the first solution
line_draw(bh_2d, ch_2d)
line_draw(bh_2d, d2_2d)
line_draw(ch_2d, d2_2d)
ab = dist(0, ah, box_w, bh)
ad = dist(0, ah, box_d, dh)
a2_2d = third_point(d2_2d, bh_2d, ab, ad)[1] # gets the 1st solution too!
line_draw(bh_2d, a2_2d)
line_draw(d2_2d, a2_2d)
# floor face
rect(0, 0, box_w, box_d)
stroke(CUT_COLOR) # Marked for cutting
# top tabs
glue_tab(d2_2d, ch_2d, TAB_W, TAB_A)
glue_tab(bh_2d, a2_2d, TAB_W, TAB_A)
glue_tab(a2_2d, d2_2d, TAB_W, TAB_A)
# middle tab
glue_tab(b0_2d, bh_2d, TAB_W, TAB_A)
# floor tabs
glue_tab((0, box_d), b0_2d, TAB_W, TAB_A)
glue_tab((box_w, box_d), (0, box_d), TAB_W, TAB_A)
glue_tab((box_w, 0), (box_w, box_d), TAB_W, TAB_A)
# main outline cut
poly_draw((ch_2d, dh_2d, ah_2d,
(box_w * 2 + box_d * 2, -bh),
(box_w * 2 + box_d * 2, 0),
c0_2d), closed=False)
def draw_3d():
stroke(0)
fill(255, 200)
# floor face
poly_draw(((0, 0, 0),
(box_w, 0, 0),
(box_w, box_d, 0),
(0, box_d, 0)))
# face 0
poly_draw(((0, 0, bh),
(box_w, 0, ch),
(box_w, 0, 0),
(0, 0, 0)))
# face 1
poly_draw(((box_w, box_d, dh),
(box_w, 0, ch),
(box_w, 0, 0),
(box_w, box_d, 0)))
# face 2
poly_draw(((box_w, box_d, dh),
(0, box_d, ah),
(0, box_d, 0),
(box_w, box_d, 0)))
# face 3
poly_draw(((0, 0, bh),
(0, box_d, ah),
(0, box_d, 0),
(0, 0, 0)))
# first triangle
poly_draw(((0, 0, bh),
(box_w, box_d, dh),
(0, box_d, ah)))
# second triangle
poly_draw(((0, 0, bh),
(box_w, box_d, dh),
(box_w, 0, ch)))
# diagonal
stroke(ENG_COLOR)
line(0, 0, bh, box_w, box_d, dh)
def poly_draw(points, closed=True):
beginShape()
for p in points:
vertex(*p)
if closed:
endShape(CLOSE)
else:
endShape()
def line_draw(p1, p2):
line(p1[0], p1[1], p2[0], p2[1])
def glue_tab(p1, p2, tab_w, cut_ang=QUARTER_PI):
"""
draws a trapezoidal or triangular glue tab
along edge defined by p1 and p2,
with width tab_w and cut angle a
"""
a1 = atan2(p1[0] - p2[0], p1[1] - p2[1]) + cut_ang + PI
a2 = atan2(p1[0] - p2[0], p1[1] - p2[1]) - cut_ang
# calculate cut_len to get the right tab width
cut_len = tab_w / sin(cut_ang)
f1 = PVector(p1[0] + cut_len * sin(a1),
p1[1] + cut_len * cos(a1))
f2 = PVector(p2[0] + cut_len * sin(a2),
p2[1] + cut_len * cos(a2))
edge_len = dist(p1[0], p1[1], p2[0], p2[1])
if edge_len > 2 * cut_len * cos(cut_ang): # 'normal' trapezoidal tab
line_draw(p1, f1)
line_draw(f1, f2)
line_draw(f2, p2)
else: # short triangular tab
fm = ((f1[0] + f2[0]) / 2, (f1[1] + f2[1]) / 2)
line_draw(p1, fm)
line_draw(fm, p2)
def keyPressed():
global ah, bh, ch, dh, box_w, box_d, box_h
# save frame on GIF
# gif_export(GifMaker, filename=SKETCH_NAME)
if key == "q":
ah += 5
if key == "a" and ah > 5:
ah -= 5
if key == "w":
bh += 5
if key == "s" and bh > 5:
bh -= 5
if key == "e":
ch += 5
if key == "d" and ch > 5:
ch -= 5
if key == "r":
dh += 5
if key == "f" and dh > 5:
dh -= 5
if key in ("+", "="):
box_h += 5
ah += 5
bh += 5
ch += 5
dh += 5
if (key == "-" and box_h > 5 and ah > 5 and bh > 5 and ch > 5 and dh > 5):
box_h -= 5
ah -= 5
bh -= 5
ch -= 5
dh -= 5
if keyCode == UP and box_d + box_w < 220:
box_d += 5
if keyCode == DOWN and box_d > 5:
box_d -= 5
if keyCode == RIGHT and box_w + box_d < 220:
box_w += 5
if keyCode == LEFT and box_w > 5:
box_w -= 5
if key == " ":
slowly_reset_values()
def slowly_reset_values():
global box_w, box_d, box_h, ah, bh, ch, dh
box_w += (100 - box_w) / 2
box_d += (100 - box_d) / 2
box_h += (100 - box_h) / 2
ah += (box_h - ah) / 2
bh += (box_h - bh) / 2
ch += (box_h - ch) / 2
dh += (box_h - dh) / 2