kopia lustrzana https://github.com/villares/sketch-a-day
159 wiersze
5.0 KiB
Python
159 wiersze
5.0 KiB
Python
CUT_STROKE = color(255, 0, 0)
|
|
|
|
def test():
|
|
#size(600, 400, P3D)
|
|
p3D = [(50, 100, 0), (200, 100, 0), (200, 200, 0), (100, 300, -100)]
|
|
debug_text("ABCD", p3D)
|
|
beginShape()
|
|
for p in p3D:
|
|
vertex(*p)
|
|
endShape(CLOSE)
|
|
x0, y0, z0 = p3D[1]
|
|
x2, y2, z2 = p3D[3]
|
|
line(x0, y0, z0, x2, y2, z2)
|
|
println(dist(x0, y0, z0, x2, y2, z2))
|
|
|
|
p2D = [(250, 100), (250, 200)]
|
|
bx, by = p2D[0]
|
|
debug_text("BC", p2D)
|
|
for i in range(1):
|
|
p2D = unfold_tri_face(p2D, p3D)
|
|
println(p2D)
|
|
debug_text("AD", p2D)
|
|
dx, dy, _ = p2D[1]
|
|
println(dist(bx, by, dx, dy))
|
|
|
|
|
|
def unfold_tri_face(pts_2D, pts_3D):
|
|
"""
|
|
gets a collection of 2 (B, C) starting 2D points (PVectors or tuples)
|
|
Gets a collection of 4 (A, B, C, D) 3D points (PVectors or tuples)
|
|
Draws the unfolded face and returns (A, D) 2D positions.
|
|
"""
|
|
b2D, c2D = pts_2D
|
|
a3D, b3D, c3D, d3D = pts_3D
|
|
bd_len = dist(b3D[0], b3D[1], b3D[2], d3D[0], d3D[1], d3D[2])
|
|
cd_len = dist(c3D[0], c3D[1], c3D[2], d3D[0], d3D[1], d3D[2])
|
|
# lower triangle
|
|
d2D = third_point(b2D, c2D, bd_len, cd_len)[0] # gets the first solution
|
|
line_draw(b2D, c2D)
|
|
#line_draw(b2D, d2D)
|
|
line_draw(d2D, c2D, tab=True)
|
|
# upper triangle (fixed from 190408a)
|
|
ab_len = dist(b3D[0], b3D[1], b3D[2], a3D[0], a3D[1], a3D[2])
|
|
ad_len = dist(a3D[0], a3D[1], a3D[2], d3D[0], d3D[1], d3D[2])
|
|
# gets the 1st solution too!
|
|
a2D = third_point(b2D, d2D, ab_len, ad_len)[0]
|
|
line_draw(b2D, a2D, tab=True)
|
|
line_draw(d2D, a2D)
|
|
return (a2D, d2D)
|
|
|
|
def third_point(a, b, ac_len, bc_len):
|
|
"""
|
|
Adapted from code by Monkut https://stackoverflow.com/users/24718/monkut
|
|
at https://stackoverflow.com/questions/4001948/drawing-a-triangle-in-a-coordinate-plane-given-its-three-sides
|
|
for use with Processing Python Mode - using PVectors
|
|
|
|
Returns two point c options given:
|
|
point a, point b, ac length, bc length
|
|
"""
|
|
class NoTrianglePossible(BaseException):
|
|
pass
|
|
|
|
# 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 point d, needed to calculate point c(1|2)
|
|
d = PVector(a.x + ad_len * (b.x - a.x) / ab_len,
|
|
a.y + ad_len * (b.y - a.y) / ab_len)
|
|
# get point c locations
|
|
c1 = PVector(d.x + h * (b.y - a.y) / ab_len,
|
|
d.y - h * (b.x - a.x) / ab_len)
|
|
c2 = PVector(d.y + h * (b.x - a.x) / ab_len,
|
|
d.x - h * (b.y - a.y) / ab_len)
|
|
return c1, c2
|
|
|
|
def line_draw(p1, p2, tab=False):
|
|
"""
|
|
sugar for drawing lines from 2 "points" (tuples or PVectors)
|
|
may also draw a glue tab suitably marked for cutting.
|
|
"""
|
|
line(p1[0], p1[1], p2[0], p2[1])
|
|
if tab:
|
|
with pushStyle():
|
|
stroke(CUT_STROKE)
|
|
glue_tab(p1, p2)
|
|
|
|
def glue_tab(p1, p2, tab_w=10, cut_ang=QUARTER_PI):
|
|
"""
|
|
draws a trapezoidal or triangular glue tab
|
|
along edge defined by p1 and p2, with provided
|
|
width (tab_w) and cut angle (cut_ang)
|
|
"""
|
|
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
|
|
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)
|
|
|
|
|
|
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)
|
|
|
|
def poly_draw(points, closed=True):
|
|
""" sugar for face drawing """
|
|
beginShape()
|
|
for p in points:
|
|
vertex(*p)
|
|
if closed:
|
|
endShape(CLOSE)
|
|
else:
|
|
endShape()
|
|
|
|
def triangulated_face(*args):
|
|
if len(args) == 4:
|
|
a, b, c, d = args
|
|
println("face")
|
|
else:
|
|
a, b, c, d = args[0]
|
|
# two triangles - could be with a diferent diagonal!
|
|
# TODO: let one choose diagonal orientation
|
|
stroke(0)
|
|
poly_draw((a, b, d))
|
|
poly_draw((b, d, c))
|