# 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