Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 11fe019

Browse files
committed
first py5 attempt
1 parent cf111a5 commit 11fe019

File tree

2 files changed

+292
-0
lines changed

2 files changed

+292
-0
lines changed

‎unfold_pyramidal_solid_py5/geometry.py

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
from py5 import *
2+
3+
CUT_STROKE = color(255, 0, 0)
4+
5+
def unfold_tri_face(pts_2D, pts_3D):
6+
"""
7+
gets a collection of 2 (B, C) starting 2D points (Py5Vectors or tuples)
8+
gets a collection of 4 (A, B, C, D) 3D points (p_vectors or tuples)
9+
draws the unfolded face and returns (A, D) 2D positions.
10+
"""
11+
b2D, c2D = pts_2D
12+
a3D, b3D, c3D, d3D = pts_3D
13+
bd_len = dist(b3D[0], b3D[1], b3D[2], d3D[0], d3D[1], d3D[2])
14+
cd_len = dist(c3D[0], c3D[1], c3D[2], d3D[0], d3D[1], d3D[2])
15+
# lower triangle
16+
d2D = third_point(b2D, c2D, bd_len, cd_len)[
17+
0] # gets the first solution
18+
line_draw(b2D, c2D)
19+
line_draw(d2D, c2D, tab=True)
20+
# upper triangle (fixed from 190408a)
21+
ab_len = dist(b3D[0], b3D[1], b3D[2], a3D[0], a3D[1], a3D[2])
22+
ad_len = dist(a3D[0], a3D[1], a3D[2], d3D[0], d3D[1], d3D[2])
23+
# gets the 1st solution too!
24+
a2D = third_point(b2D, d2D, ab_len, ad_len)[0]
25+
line_draw(b2D, a2D, tab=True)
26+
# line_draw(d2D, a2D)
27+
return (a2D, d2D)
28+
29+
30+
def third_point(a, b, ac_len, bc_len):
31+
"""
32+
Adapted from code by monkut https://stackoverflow.com/users/24718/monkut
33+
at https://stackoverflow.com/questions/4001948/drawing-a-triangle-in-a-coordinate-plane-given-its-three-sides
34+
for use with processing python mode - using p_vectors
35+
36+
returns two point c options given:
37+
point a, point b, ac length, bc length
38+
"""
39+
class NoTrianglePossible(BaseException):
40+
pass
41+
42+
# To allow use of tuples, creates or recreates PVectors
43+
a, b = Py5Vector(*a), Py5Vector(*b)
44+
# check if a triangle is possible
45+
ab_len = a.dist(b)
46+
if ab_len > (ac_len + bc_len) or ab_len < abs(ac_len - bc_len):
47+
raise no_triangle_possible("The sides do not form a triangle")
48+
49+
# get the length to the vertex of the right triangle formed,
50+
# by the intersection formed by circles a and b
51+
ad_len = (ab_len ** 2 + ac_len ** 2 - bc_len ** 2) / (2.0 * ab_len)
52+
# get the height of the line at a right angle from a_len
53+
h = sqrt(abs(ac_len ** 2 - ad_len ** 2))
54+
55+
# Calculate the mid point d, needed to calculate point c(1|2)
56+
d = Py5Vector(a.x + ad_len * (b.x - a.x) / ab_len,
57+
a.y + ad_len * (b.y - a.y) / ab_len)
58+
# get point c locations
59+
c1 = Py5Vector(d.x + h * (b.y - a.y) / ab_len,
60+
d.y - h * (b.x - a.x) / ab_len)
61+
c2 = Py5Vector(d.y + h * (b.x - a.x) / ab_len,
62+
d.x - h * (b.y - a.y) / ab_len)
63+
return c1, c2
64+
65+
66+
def line_draw(p1, p2, tab=False):
67+
"""
68+
sugar for drawing lines from 2 "points" (tuples or p_vectors)
69+
may also draw a glue tab suitably marked for cutting.
70+
"""
71+
line(p1[0], p1[1], p2[0], p2[1])
72+
if tab:
73+
with push_style():
74+
stroke(CUT_STROKE)
75+
glue_tab(p1, p2)
76+
77+
78+
def glue_tab(p1, p2, tab_w=10, cut_ang=QUARTER_PI):
79+
"""
80+
draws a trapezoidal or triangular glue tab
81+
along edge defined by p1 and p2, with provided
82+
width (tab_w) and cut angle (cut_ang)
83+
"""
84+
a1 = atan2(p1[0] - p2[0], p1[1] - p2[1]) + cut_ang + PI
85+
a2 = atan2(p1[0] - p2[0], p1[1] - p2[1]) - cut_ang
86+
# calculate cut_len to get the right tab width
87+
cut_len = tab_w / sin(cut_ang)
88+
f1 = (p1[0] + cut_len * sin(a1),
89+
p1[1] + cut_len * cos(a1))
90+
f2 = (p2[0] + cut_len * sin(a2),
91+
p2[1] + cut_len * cos(a2))
92+
edge_len = dist(p1[0], p1[1], p2[0], p2[1])
93+
94+
if edge_len > 2 * cut_len * cos(cut_ang): # 'normal' trapezoidal tab
95+
line_draw(p1, f1)
96+
line_draw(f1, f2)
97+
line_draw(f2, p2)
98+
else: # short triangular tab
99+
fm = ((f1[0] + f2[0]) / 2, (f1[1] + f2[1]) / 2)
100+
line_draw(p1, fm)
101+
line_draw(fm, p2)
102+
103+
104+
DEBUG = True
105+
106+
107+
def debug_text(name, points, enum=False):
108+
if DEBUG:
109+
for i, p in enumerate(points):
110+
with push():
111+
112+
fill(255, 0, 0)
113+
if enum:
114+
translate(0, -5, 10)
115+
text(name + "-" + str(i), *p)
116+
else:
117+
translate(10, 10, 10)
118+
text(name[i], *p)
119+
120+
121+
def poly_draw(points, force_z=None, closed=True):
122+
""" sugar for face drawing """
123+
begin_shape()
124+
for p in points:
125+
if force_z is None:
126+
vertex(*p)
127+
else:
128+
vertex(p[0], p[1], force_z)
129+
if closed:
130+
end_shape(CLOSE)
131+
else:
132+
end_shape()
133+
134+
135+
def triangulated_face(*args):
136+
if len(args) == 4:
137+
a, b, c, d = args
138+
print("face")
139+
else:
140+
a, b, c, d = args[0]
141+
# two triangles - could be with a diferent diagonal!
142+
# TODO: let one choose diagonal orientation
143+
stroke(0)
144+
poly_draw((a, b, d))
145+
poly_draw((b, d, c))
146+
147+
148+
def test():
149+
#size(600, 400, P3D)
150+
p3D = [(50, 100, 0), (200, 100, 0), (200, 200, 0), (100, 300, -100)]
151+
debug_text("ABCD", p3D)
152+
begin_shape()
153+
for p in p3D:
154+
vertex(*p)
155+
end_shape(CLOSE)
156+
x0, y0, z0 = p3D[1]
157+
x2, y2, z2 = p3D[3]
158+
line(x0, y0, z0, x2, y2, z2)
159+
print(dist(x0, y0, z0, x2, y2, z2))
160+
161+
p2D = [(250, 100), (250, 200)]
162+
bx, by = p2D[0]
163+
debug_text("BC", p2D)
164+
for i in range(1):
165+
p2D = unfold_tri_face(p2D, p3D)
166+
print(p2D)
167+
debug_text("AD", p2D)
168+
dx, dy, _ = p2D[1]
169+
print(dist(bx, by, dx, dy))
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
"""
2+
alexandre B A villares - https://abav.lugaralgum.com/
3+
4+
unfolding prism or pyramideal solid
5+
6+
https://github.com/villares/paper-objects-with-processing-and-python
7+
for py5 imported mode
8+
"""
9+
10+
from geometry import poly_draw, line_draw, unfold_tri_face, glue_tab
11+
12+
CUT_STROKE = color(255, 0, 0)
13+
FOLD_STROKE = color(0, 0, 255)
14+
15+
p_height = 100
16+
base_radius, top_radius = 50, 50
17+
sides = 5
18+
19+
def setup():
20+
size(600, 600, P3D)
21+
hint(ENABLE_DEPTH_TEST)
22+
hint(ENABLE_DEPTH_SORT)
23+
24+
def draw():
25+
background(240)
26+
push_matrix()
27+
translate(width / 2, height / 4 + 50)
28+
rotate_x(radians(45))
29+
rotate_z(radians(frame_count / 3.))
30+
fill(255, 200)
31+
stroke(0)
32+
stroke_weight(2)
33+
# draw 3D piramid and get points
34+
base, top, face = prism_3D(sides, p_height, base_radius, top_radius)
35+
pop_matrix()
36+
# draw unfolded 2D
37+
translate(width / 2, height * 3 / 4 - 50)
38+
prism_2D(base, top, face)
39+
40+
41+
def prism_3D(np, h, base_r, top_r):
42+
# calculando os points
43+
base_points = []
44+
for i in range(np):
45+
ang = radians(i * 360. / np)
46+
x = sin(ang) * base_r
47+
y = cos(ang) * base_r
48+
base_points.append((x, y, 0))
49+
# edges da base
50+
o_base_points = base_points[1:] + [base_points[0]]
51+
base_edges = list(zip(base_points, o_base_points))
52+
top_points = []
53+
for i in range(np):
54+
ang = radians(i * 360. / np)
55+
x = sin(ang) * top_r
56+
y = cos(ang) * top_r
57+
top_points.append((x, y, h))
58+
# edges da base
59+
o_top_points = top_points[1:] + [top_points[0]]
60+
top_edges = list(zip(top_points, o_top_points))
61+
# edges
62+
for base_edge, top_edge in zip(base_edges, top_edges):
63+
(p1x, p1y, p1z), (p2x, p2y, p2z) = base_edge
64+
(p1tx, p1ty, p1tz), (p2tx, p2ty, p2tz) = top_edge
65+
begin_shape()
66+
vertex(p1x, p1y, p1z)
67+
vertex(p1tx, p1ty, p1tz)
68+
vertex(p2tx, p2ty, p2tz)
69+
vertex(p2x, p2y, p2z)
70+
end_shape(CLOSE)
71+
# one face
72+
(p1x, p1y, p1z), (p2x, p2y, p2z) = base_edges[0]
73+
(p1tx, p1ty, p1tz), (p2tx, p2ty, p2tz) = top_edges[0]
74+
face = [(p2x, p2y, p2z),
75+
(p1x, p1y, p1z),
76+
(p1tx, p1ty, p1tz),
77+
(p2tx, p2ty, p2tz),
78+
]
79+
# draw base and top
80+
poly_draw(top_points)
81+
poly_draw(base_points)
82+
83+
return base_points, top_points, face
84+
85+
86+
def prism_2D(base, top, face):
87+
with push_matrix():
88+
translate(150, -300)
89+
poly_draw(top, force_z=0)
90+
with push_matrix():
91+
translate(-150, -300)
92+
poly_draw(base, force_z=0)
93+
x0, y0, z0 = face[1]
94+
x2, y2, z2 = face[2]
95+
d = dist(x0, y0, z0, x2, y2, z2)
96+
side = ((150, d - 150), (150, -150))
97+
for i in range(sides):
98+
side = unfold_tri_face(side, face[::-1])
99+
stroke(CUT_STROKE)
100+
line_draw(side[0], side[1])
101+
glue_tab((150, -150), (150, d - 150))
102+
103+
104+
def key_pressed():
105+
global base_radius, top_radius, p_height, sides
106+
if key_code == UP:
107+
p_height += 5
108+
if key_code == DOWN:
109+
p_height -= 5
110+
if key_code == LEFT:
111+
base_radius += 5
112+
if key_code == RIGHT:
113+
base_radius -= 5
114+
if key == "w":
115+
sides += 1
116+
if key == "s" and sides > 3:
117+
sides -= 1
118+
if key == "a" and top_radius > 0:
119+
top_radius -= 5
120+
if key == "d":
121+
top_radius += 5
122+
if key == "p":
123+
save_frame(SKETCH_NAME + ".png")

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /