kopia lustrzana https://github.com/villares/sketch-a-day
196 wiersze
5.5 KiB
Python
196 wiersze
5.5 KiB
Python
"""
|
|
Alexandre B A Villares - https://abav.lugaralgum.com/sketch-a-day
|
|
|
|
- Unfolding solid....
|
|
"""
|
|
|
|
add_library('GifAnimation')
|
|
from gif_exporter import gif_export
|
|
from unfold_face import *
|
|
|
|
CUT_STROKE = color(255, 0, 0)
|
|
FOLD_STROKE = color(0, 0, 255)
|
|
|
|
p_height, base_radius, top_radius = 100, 50, 50
|
|
sides = 5
|
|
|
|
def setup():
|
|
size(600, 600, P3D)
|
|
hint(ENABLE_DEPTH_TEST)
|
|
hint(ENABLE_DEPTH_SORT)
|
|
|
|
def draw():
|
|
background(240)
|
|
pushMatrix()
|
|
translate(width / 2, height / 4 + 50)
|
|
rotateX(radians(45))
|
|
rotateZ(radians(frameCount / 3.))
|
|
fill(255, 200)
|
|
stroke(0)
|
|
strokeWeight(2)
|
|
# draw 3D piramid and get points
|
|
points, face = prism_3D(sides, p_height, base_radius, top_radius)
|
|
popMatrix()
|
|
# draw unfolded 2D
|
|
translate(width / 2, height * 3 / 4 - 50)
|
|
prism_2D(points, face)
|
|
# triangulated_face(*face)
|
|
|
|
def prism_3D(np, h, base_r, top_r):
|
|
# calculando os points
|
|
base_points = []
|
|
for i in range(np):
|
|
ang = radians(i * 360. / np)
|
|
x = sin(ang) * base_r
|
|
y = cos(ang) * base_r
|
|
base_points.append((x, y))
|
|
# edges da base
|
|
o_base_points = base_points[1:] + [base_points[0]]
|
|
base_edges = zip(base_points, o_base_points)
|
|
top_points = []
|
|
for i in range(np):
|
|
ang = radians(i * 360. / np)
|
|
x = sin(ang) * top_r
|
|
y = cos(ang) * top_r
|
|
top_points.append((x, y))
|
|
# edges da base
|
|
o_top_points = top_points[1:] + [top_points[0]]
|
|
top_edges = zip(top_points, o_top_points)
|
|
# edges
|
|
for base_edge, top_edge in zip(base_edges, top_edges):
|
|
(p1x, p1y), (p2x, p2y) = base_edge
|
|
(p1tx, p1ty), (p2tx, p2ty) = top_edge
|
|
beginShape()
|
|
vertex(p1x, p1y, 0)
|
|
vertex(p1tx, p1ty, h)
|
|
vertex(p2tx, p2ty, h)
|
|
vertex(p2x, p2y, 0)
|
|
endShape(CLOSE)
|
|
#line(p1x, p1y, 0, p2tx, p2ty, h)
|
|
# one face
|
|
(p1x, p1y), (p2x, p2y) = base_edges[0]
|
|
(p1tx, p1ty), (p2tx, p2ty) = top_edges[0]
|
|
face = [(p2x, p2y, 0),
|
|
(p1x, p1y, 0),
|
|
(p1tx, p1ty, h),
|
|
(p2tx, p2ty, h),
|
|
]
|
|
# always draws base
|
|
beginShape()
|
|
for bpt in base_points:
|
|
vertex(bpt[0], bpt[1], 0)
|
|
endShape(CLOSE)
|
|
beginShape()
|
|
for tpt in top_points:
|
|
vertex(tpt[0], tpt[1], h)
|
|
endShape(CLOSE)
|
|
# return points for 2D!
|
|
return (base_points, top_points), face
|
|
|
|
def prism_2D(top_bot, face):
|
|
with pushMatrix():
|
|
translate(150, -300)
|
|
poly_draw(top_bot[1])
|
|
with pushMatrix():
|
|
translate(-150, -300)
|
|
poly_draw(top_bot[0])
|
|
x0, y0, z0 = face[1]
|
|
x2, y2, z2 = face[2]
|
|
d = dist(x0, y0, z0, x2, y2, z2)
|
|
side = ((150, d - 150), (150, -150))
|
|
for i in range(sides):
|
|
side = unfold_tri_face(side, face[::-1])
|
|
stroke(CUT_STROKE)
|
|
glue_tab((150, -150), (150, d - 150), 10)
|
|
|
|
# for points in all_points:
|
|
# ang = radians(360. / len(points))
|
|
# with pushMatrix():
|
|
# translate(-width / 4, 0)
|
|
# rotate(ang / 2)
|
|
# noFill()
|
|
# base fold lines
|
|
# stroke(FOLD_STROKE)
|
|
# beginShape()
|
|
# for pt in points:
|
|
# vertex(*pt)
|
|
# endShape(CLOSE)
|
|
# lateral edges
|
|
# o_points = points[1:] + [points[0]]
|
|
# edges = zip(points, o_points)
|
|
# for i, edge in enumerate(edges): # edges[1:] to skip one
|
|
# p1, p2 = edge
|
|
# stroke(CUT_STROKE)
|
|
# abas de cola
|
|
# glue_tab(p2, p1, 10, )
|
|
# FOLD_STROKE
|
|
# stroke(FOLD_STROKE)
|
|
# line(p2[0], p2[1], p1[0], p1[1])
|
|
# translate(width / 2, 0)
|
|
|
|
def glue_tab(p1, p2, tab_w, cut_ang=QUARTER_PI / 3):
|
|
"""
|
|
draws a trapezoidal or triangular glue tab along edge defined by p1 and p2,
|
|
with width tab_w and cut angle a
|
|
"""
|
|
al = atan2(p1[0] - p2[0], p1[1] - p2[1])
|
|
a1 = al + cut_ang + PI
|
|
a2 = al - cut_ang
|
|
# calculate cut_len to get the base_rght 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()
|
|
|
|
def keyPressed():
|
|
global base_radius, top_radius, p_height, sides
|
|
if keyCode == UP:
|
|
p_height += 5
|
|
if keyCode == DOWN:
|
|
p_height -= 5
|
|
if keyCode == LEFT:
|
|
base_radius += 5
|
|
if keyCode == RIGHT:
|
|
base_radius -= 5
|
|
if key == "w":
|
|
sides += 1
|
|
if key == "s" and sides > 3:
|
|
sides -= 1
|
|
if key == "a" and top_radius > 0:
|
|
top_radius -= 5
|
|
if key == "d":
|
|
top_radius += 5
|
|
if key == "g":
|
|
# saveFrame(SKETCH_NAME + ".gif")
|
|
gif_export(GifMaker, filename=SKETCH_NAME)
|
|
|
|
def settings():
|
|
from os import path
|
|
global SKETCH_NAME
|
|
SKETCH_NAME = path.basename(sketchPath())
|
|
OUTPUT = ".gif"
|
|
println(
|
|
"""
|
|

|
|
|
|
[{0}](https://github.com/villares/sketch-a-day/tree/master/{2}/{0}) [[Py.Processing](https://villares.github.io/como-instalar-o-processing-modo-python/index-EN)]
|
|
""".format(SKETCH_NAME, OUTPUT, year())
|
|
)
|