kopia lustrzana https://github.com/villares/sketch-a-day
main
rodzic
f10eae156e
commit
7e03f521d7
Plik binarny nie jest wyświetlany.
Po Szerokość: | Wysokość: | Rozmiar: 16 KiB |
|
@ -1,7 +1,6 @@
|
|||
# Alexandre B A Villares - https://abav.lugaralgum.com/sketch-a-day
|
||||
SKETCH_NAME, OUTPUT = "sketch_190409b", ".gif"
|
||||
SKETCH_NAME, OUTPUT = "sketch_190409b", ".png"
|
||||
"""
|
||||
Subdivided top! (not quite there yet...)
|
||||
"""
|
||||
add_library('GifAnimation')
|
||||
from gif_exporter import gif_export
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
DEBUG = True
|
||||
|
||||
def debug_text(name, points, enum=False):
|
||||
if DEBUG:
|
||||
for i, p in enumerate(points):
|
||||
with push():
|
||||
|
||||
fill(255, 0, 0)
|
||||
if enum:
|
||||
translate(0, -5, 10)
|
||||
text(name + "-" + str(i), *p)
|
||||
else:
|
||||
translate(10, 10, 10)
|
||||
text(name[i], *p)
|
|
@ -0,0 +1,63 @@
|
|||
from debug import *
|
||||
|
||||
def draw_3d(box_w, box_d, ab_i, cd_i):
|
||||
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)))
|
||||
|
||||
num_i = len(cd_i)
|
||||
cd_pts = tuple([(box_w, box_d - box_d * i / (num_i - 1), cd_i[::-1][i])
|
||||
for i in range(num_i)])
|
||||
ab_pts = tuple([(0, box_d * i / (num_i - 1), ab_i[::-1][i])
|
||||
for i in range(num_i)])
|
||||
# face 0
|
||||
poly_draw(((0, 0, ab_i[-1]),
|
||||
(box_w, 0, cd_i[0]),
|
||||
(box_w, 0, 0),
|
||||
(0, 0, 0)))
|
||||
# face 1
|
||||
poly_draw(cd_pts + (
|
||||
(box_w, 0, 0),
|
||||
(box_w, box_d, 0)))
|
||||
# face 2
|
||||
poly_draw(((box_w, box_d, cd_i[-1]),
|
||||
(0, box_d, ab_i[0]),
|
||||
(0, box_d, 0),
|
||||
(box_w, box_d, 0)))
|
||||
# face 3
|
||||
poly_draw(ab_pts + (
|
||||
(0, box_d, 0),
|
||||
(0, 0, 0)))
|
||||
# top faces
|
||||
|
||||
for i in range(1, len(ab_pts)):
|
||||
p = i - 1
|
||||
x = screenX(*cd_pts[::-1][p])
|
||||
y = screenY(*cd_pts[::-1][p])
|
||||
|
||||
triangulated_face(
|
||||
cd_pts[::-1][p], ab_pts[p], ab_pts[i], cd_pts[::-1][i])
|
||||
|
||||
debug_text("cd", cd_pts[::-1], enum=True)
|
||||
debug_text("ab", ab_pts[::-1], enum=True)
|
||||
debug_text("DAad", ((box_w, box_d, cd_i[-1]),
|
||||
(0, box_d, ab_i[0]),
|
||||
(0, box_d, 0),
|
||||
(box_w, box_d, 0)))
|
||||
|
||||
def poly_draw(points, closed=True):
|
||||
beginShape()
|
||||
for p in points:
|
||||
vertex(*p)
|
||||
if closed:
|
||||
endShape(CLOSE)
|
||||
else:
|
||||
endShape()
|
||||
|
||||
def triangulated_face(a, b, c, d):
|
||||
poly_draw((b, d, a))
|
||||
poly_draw((b, d, c))
|
|
@ -0,0 +1,40 @@
|
|||
"""
|
||||
Alexandre B A Villares http://abav.lugaralgum.com - GPL v3
|
||||
|
||||
A helper for the Processing gifAnimation library https://github.com/extrapixel/gif-animation/tree/3.0
|
||||
Download from https://github.com/villares/processing-play/blob/master/export_GIF/unzip_and_move_to_libraries_GifAnimation.zip
|
||||
This helper was inspired by an example by Art Simon https://github.com/APCSPrinciples/AnimatedGIF/
|
||||
|
||||
# add at the start of your sketch:
|
||||
add_library('gifAnimation')
|
||||
from gif_exporter import gif_export
|
||||
# add at the end of draw():
|
||||
gif_export(GifMaker)
|
||||
"""
|
||||
|
||||
def gif_export(GifMaker, # gets a reference to the library
|
||||
filename="exported", # .gif will be added
|
||||
repeat=0, # 0 makes it an "endless" animation
|
||||
quality=255, # quality range 0 - 255
|
||||
delay=200, # this is quick
|
||||
frames=0, # 0 will stop on keyPressed or frameCount >= 100000
|
||||
finish=False): # force stop
|
||||
global gifExporter
|
||||
try:
|
||||
gifExporter
|
||||
except NameError:
|
||||
gifExporter = GifMaker(this, filename + ".gif")
|
||||
gifExporter.setRepeat(repeat)
|
||||
gifExporter.setQuality(quality)
|
||||
gifExporter.setDelay(delay)
|
||||
|
||||
gifExporter.addFrame()
|
||||
|
||||
if frames == 0:
|
||||
if keyPressed and key == "e":
|
||||
finish = True
|
||||
|
||||
if finish:
|
||||
gifExporter.finish()
|
||||
print("gif saved")
|
||||
exit()
|
|
@ -0,0 +1,118 @@
|
|||
# Alexandre B A Villares - https://abav.lugaralgum.com/sketch-a-day
|
||||
SKETCH_NAME, OUTPUT = "sketch_190410a", ".gif"
|
||||
"""
|
||||
"""
|
||||
add_library('GifAnimation')
|
||||
from gif_exporter import gif_export
|
||||
add_library('peasycam')
|
||||
from unfolded_2D import *
|
||||
from draw_3D import *
|
||||
|
||||
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 box dimensions
|
||||
ah = bh = ch = dh = box_h # initial height of points a, b, c and d
|
||||
# height of points between d and c
|
||||
cd_i = [box_h, box_h + 15, box_h + 10, box_h]
|
||||
# height of points between a and b
|
||||
ab_i = [box_h, box_h - 15, box_h - 10, box_h]
|
||||
|
||||
assert len(cd_i) == len(ab_i) # has to mantain equal number of pts
|
||||
|
||||
def setup():
|
||||
size(850, 500, P3D)
|
||||
# global cam
|
||||
# cam = PeasyCam(this, 300)
|
||||
hint(ENABLE_DEPTH_SORT)
|
||||
smooth(16)
|
||||
strokeWeight(2)
|
||||
|
||||
def draw():
|
||||
background(200)
|
||||
# Draw 3D
|
||||
with pushMatrix():
|
||||
translate(width / 2, height / 2) # Comment out if using with PeasyCam
|
||||
rotateX(QUARTER_PI)
|
||||
rotateZ(0)
|
||||
translate(200, -50, -100)
|
||||
face_data = draw_3d(box_w, box_d, ab_i, cd_i)
|
||||
|
||||
# Draw 2D unfolded
|
||||
# cam.beginHUD() # for use with PeasyCam
|
||||
with pushMatrix():
|
||||
translate(100, 350)
|
||||
draw_unfolded(box_w, box_d, ab_i, cd_i, face_data)
|
||||
# cam.endHUD()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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()
|
||||
if key == "p":
|
||||
saveFrame("####.png")
|
||||
|
||||
# update top face point lists
|
||||
cd_i[0] = ch
|
||||
cd_i[-1] = dh
|
||||
ab_i[0] = ah
|
||||
ab_i[-1] = bh
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
"""
|
||||
Code adapted from code by Monkut https://stackoverflow.com/users/24718/monkut
|
||||
found at https://stackoverflow.com/questions/4001948/drawing-a-triangle-in-a-coordinate-plane-given-its-three-sides
|
||||
"""
|
||||
|
||||
class NoTrianglePossible(BaseException):
|
||||
pass
|
||||
|
||||
def third_point(a, b, ac_len, bc_len):
|
||||
"""
|
||||
Returns two point c options given:
|
||||
point a, point b, ac length, bc length
|
||||
"""
|
||||
# To allow use of tuples, creates or recreates PVectors
|
||||
a, b = PVector(*a), PVector(*b)
|
||||
|
||||
# check if a triangle is possible
|
||||
ab_len = a.dist(b)
|
||||
if ab_len > (ac_len + bc_len) or ab_len < abs(ac_len - bc_len):
|
||||
raise NoTrianglePossible("The sides do not form a triangle")
|
||||
|
||||
# get the length to the vertex of the right triangle formed,
|
||||
# by the intersection formed by circles a and b
|
||||
ad_len = (ab_len ** 2 + ac_len ** 2 - bc_len ** 2) / (2.0 * ab_len)
|
||||
|
||||
# get the height of the line at a right angle from a_len
|
||||
h = sqrt(abs(ac_len ** 2 - ad_len ** 2))
|
||||
|
||||
# Calculate the mid PVector (point d), needed to calculate point c(1|2)
|
||||
d_x = a.x + ad_len * (b.x - a.x) / ab_len
|
||||
d_y = a.y + ad_len * (b.y - a.y) / ab_len
|
||||
d = PVector(d_x, d_y)
|
||||
|
||||
# get point_c locations
|
||||
c_x1 = d.x + h * (b.y - a.y) / ab_len
|
||||
c_x2 = d.x - h * (b.y - a.y) / ab_len
|
||||
c_y1 = d.y - h * (b.x - a.x) / ab_len
|
||||
c_y2 = d.y + h * (b.x - a.x) / ab_len
|
||||
|
||||
return PVector(c_x1, c_y1), PVector(c_x2, c_y2)
|
|
@ -0,0 +1,94 @@
|
|||
from draw_3D import poly_draw
|
||||
from third_point import third_point
|
||||
from debug import *
|
||||
|
||||
def draw_unfolded(box_w, box_d, ab_i, cd_i, face_data):
|
||||
bh_2d = (0, -ab_i[-1])
|
||||
b0_2d = (0, 0)
|
||||
ch_2d = (box_w, -cd_i[0])
|
||||
c0_2d = (box_w, 0)
|
||||
dh_2d = (box_w + box_d, -cd_i[-1])
|
||||
d0_2d = (box_w + box_d, 0)
|
||||
ah_2d = (box_w * 2 + box_d, -ab_i[0])
|
||||
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
|
||||
b_c1 = dist(0, 0, ab_i[-1], box_w, box_d / len(cd_i)-1, cd_i[1])
|
||||
c_c1 = dist(box_w, 0, cd_i[0], box_w, box_d / len(cd_i)-1, cd_i[1])
|
||||
d2_2d = third_point(bh_2d, ch_2d, b_c1, c_c1)[0] # gets the first solution
|
||||
line_draw(bh_2d, ch_2d)
|
||||
line_draw(bh_2d, d2_2d)
|
||||
line_draw(ch_2d, d2_2d)
|
||||
debug_text("BCDA", (bh_2d, ch_2d, dh_2d, ah_2d))
|
||||
# upper triangle
|
||||
|
||||
ab = dist(0, ab_i[::-1][1], box_w, ab_i[-1])
|
||||
ad = dist(0, ab_i[::-1][1], box_d / len(cd_i)-1, ab_i[::-1][1])
|
||||
a2_2d = third_point(d2_2d, bh_2d, ab, ad)[1] # gets the second solution
|
||||
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
|
||||
num_i = len(cd_i)
|
||||
cd_pts = [(box_w + box_d * i / (num_i - 1), -cd_i[i])
|
||||
for i in range(num_i)]
|
||||
ab_pts = [(box_w * 2 + box_d + box_d * i / (num_i - 1), -ab_i[i])
|
||||
for i in range(num_i)]
|
||||
main_outline = tuple(cd_pts + ab_pts) + ((box_w * 2 + box_d * 2, 0), c0_2d)
|
||||
poly_draw(main_outline, closed=False)
|
||||
|
||||
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 = (p1[0] + cut_len * sin(a1),
|
||||
p1[1] + cut_len * cos(a1))
|
||||
f2 = (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
|
||||
beginShape()
|
||||
vertex(*p1) # vertex(p1[0], p1[1])
|
||||
vertex(*f1)
|
||||
vertex(*f2)
|
||||
vertex(*p2)
|
||||
endShape()
|
||||
else: # short triangular tab
|
||||
fm = ((f1[0] + f2[0]) / 2, (f1[1] + f2[1]) / 2)
|
||||
beginShape()
|
||||
vertex(*p1)
|
||||
vertex(*fm) # middle way of f1 and f2
|
||||
vertex(*p2)
|
||||
endShape()
|
Ładowanie…
Reference in New Issue