villares 2019-06-06 21:39:17 -03:00
rodzic 594f7ba807
commit 8a991af401
14 zmienionych plików z 87118 dodań i 0 usunięć

Wyświetl plik

@ -0,0 +1,199 @@
# Alexandre B A Villares - https://abav.lugaralgum.com/sketch-a-day
# Circ-circ tangents on a poly using Bezier approximation of arcs
pts = []
rds = [30, 70, 50]
dragged_pt = -1
def setup():
size(500, 500)
pts.append((250, 150))
pts.append((250 + 100 * cos(PI / 6.0),
250 + 100 * sin(PI / 6.0)))
pts.append((250 - 100 * cos(PI / 6.0),
250 + 100 * sin(PI / 6.0)))
def draw():
background(200)
fill(255, 100)
b_poly_arc_augmented(pts, rds)
fill(0, 0, 100)
for pt in pts:
ellipse(pt[0], pt[1], 10, 10)
def mouseWheel(E):
global r, d
for i, pt in enumerate(pts):
if dist(mouseX, mouseY, pt[0], pt[1]) < 10:
rds[i] += 5 * E.getAmount()
def mousePressed():
global dragged_pt
for i, pt in enumerate(pts):
if dist(mouseX, mouseY, pt[0], pt[1]) < 10:
dragged_pt = i
break
def mouseDragged():
if dragged_pt >= 0:
pts[dragged_pt] = mouseX, mouseY
def mouseReleased():
global dragged_pt
dragged_pt = -1
def b_poly_arc_augmented(op_list, or_list):
assert len(op_list) == len(or_list), \
"Number of points and radii not the same"
# remove overlapping adjacent points
p_list, r_list, r2_list = [], [], or_list[:]
for i1, p1 in enumerate(op_list):
i2 = (i1 + 1) % len(op_list)
p2, r2, r1 = op_list[i2], r2_list[i2], r2_list[i1]
if dist(p1[0], p1[1], p2[0], p2[1]) > 1: # or p1 != p2:
p_list.append(p1)
r_list.append(r1)
else:
r2_list[i2] = min(r1, r2)
# reduce radius that won't fit
for i1, p1 in enumerate(p_list):
i2 = (i1 + 1) % len(p_list)
p2, r2, r1 = p_list[i2], r_list[i2], r_list[i1]
r_list[i1], r_list[i2] = reduce_radius(p1, p2, r1, r2)
# calculate the tangents
a_list = []
for i1, p1 in enumerate(p_list):
i2 = (i1 + 1) % len(p_list)
p2, r2, r1 = p_list[i2], r_list[i2], r_list[i1]
a = circ_circ_tangent(p1, p2, r1, r2)
a_list.append(a)
# draw
beginShape()
for i1, _ in enumerate(a_list):
i2 = (i1 + 1) % len(a_list)
p1, p2, r1, r2 = p_list[i1], p_list[i2], r_list[i1], r_list[i2]
a1, p11, p12 = a_list[i1]
a2, p21, p22 = a_list[i2]
if a1 and a2:
start = a1 if a1 < a2 else a1 - TWO_PI
if r2 < 0:
a2 = a2 - TWO_PI
b_arc(p2[0], p2[1], r2 * 2, r2 * 2, start, a2, mode=2)
else:
# when the the segment is smaller than the diference between
# radius, circ_circ_tangent won't renturn the angle
# ellipse(p2[0], p2[1], r2 * 2, r2 * 2) # debug
if a1:
vertex(p12[0], p12[1])
if a2:
vertex(p21[0], p21[1])
endShape(CLOSE)
def reduce_radius(p1, p2, r1, r2):
d = dist(p1[0], p1[1], p2[0], p2[1])
ri = abs(r1 - r2)
if d - ri < 0:
if r1 > r2:
r1 = map(d, ri + 1, 0, r1, r2)
else:
r2 = map(d, ri + 1, 0, r2, r1)
return(r1, r2)
def circ_circ_tangent(p1, p2, r1, r2):
d = dist(p1[0], p1[1], p2[0], p2[1])
ri = r1 - r2
line_angle = atan2(p1[0] - p2[0], p2[1] - p1[1])
if d - abs(ri) > 0:
theta = asin(ri / float(d))
x1 = -cos(line_angle + theta) * r1
y1 = -sin(line_angle + theta) * r1
x2 = -cos(line_angle + theta) * r2
y2 = -sin(line_angle + theta) * r2
return (line_angle + theta,
(p1[0] - x1, p1[1] - y1),
(p2[0] - x2, p2[1] - y2))
else:
return (None,
(p1[0], p1[1]),
(p2[0], p2[1]))
def b_arc(cx, cy, w, h, start_angle, end_angle, mode=0):
"""
A bezier approximation of an arc
using the same signature as the original Processing arc()
mode: 0 "normal" arc, using beginShape() and endShape()
1 "middle" used in recursive call of smaller arcs
2 "naked" like normal, but without beginShape() and endShape()
for use inside a larger PShape
"""
theta = end_angle - start_angle
# Compute raw Bezier coordinates.
if mode != 1 or abs(theta) < HALF_PI:
x0 = cos(theta / 2.0)
y0 = sin(theta / 2.0)
x3 = x0
y3 = 0 - y0
x1 = (4.0 - x0) / 3.0
if y0 != 0:
y1 = ((1.0 - x0) * (3.0 - x0)) / (3.0 * y0) # y0 != 0...
else:
y1 = 0
x2 = x1
y2 = 0 - y1
# Compute rotationally-offset Bezier coordinates, using:
# x' = cos(angle) * x - sin(angle) * y
# y' = sin(angle) * x + cos(angle) * y
bezAng = start_angle + theta / 2.0
cBezAng = cos(bezAng)
sBezAng = sin(bezAng)
rx0 = cBezAng * x0 - sBezAng * y0
ry0 = sBezAng * x0 + cBezAng * y0
rx1 = cBezAng * x1 - sBezAng * y1
ry1 = sBezAng * x1 + cBezAng * y1
rx2 = cBezAng * x2 - sBezAng * y2
ry2 = sBezAng * x2 + cBezAng * y2
rx3 = cBezAng * x3 - sBezAng * y3
ry3 = sBezAng * x3 + cBezAng * y3
# Compute scaled and translated Bezier coordinates.
rx, ry = w / 2.0, h / 2.0
px0 = cx + rx * rx0
py0 = cy + ry * ry0
px1 = cx + rx * rx1
py1 = cy + ry * ry1
px2 = cx + rx * rx2
py2 = cy + ry * ry2
px3 = cx + rx * rx3
py3 = cy + ry * ry3
# Debug points... comment this out!
# stroke(0)
# ellipse(px3, py3, 15, 15)
# ellipse(px0, py0, 5, 5)
# Drawing
if mode == 0: # 'normal' arc (not 'middle' nor 'naked')
beginShape()
if mode != 1: # if not 'middle'
vertex(px3, py3)
if abs(theta) < HALF_PI:
bezierVertex(px2, py2, px1, py1, px0, py0)
else:
# to avoid distortion, break into 2 smaller arcs
b_arc(cx, cy, w, h, start_angle, end_angle - theta / 2.0, mode=1)
b_arc(cx, cy, w, h, start_angle + theta / 2.0, end_angle, mode=1)
if mode == 0: # end of a 'normal' arc
endShape()
def settings():
from os import path
global SKETCH_NAME
SKETCH_NAME = path.basename(sketchPath())
OUTPUT = ".png"
println(
"""
![{0}]({2}/{0}/{0}{1})
[{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())
)

Wyświetl plik

@ -0,0 +1,21 @@
<!DOCTYPE html>
<!-- pyp5js index.html boilerplate -->
<html lang="">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>sketch_190606b - pyp5js</title>
<style> body, html, canvas {padding: 0; margin: 0; overflow: hidden;} </style>
<script src="static/p5.js"></script>
<script src="target/sketch_190606b.js" type="module"></script>
</head>
<body>
<div id="sketch-holder">
<!-- You sketch will go here! -->
</div>
</body>
</html>

Wyświetl plik

@ -0,0 +1,190 @@
from pytop5js import *
pts = []
rds = [30, 70, 50]
dragged_pt = -1
def setup():
createCanvas(500, 500)
pts.append((250, 150))
pts.append((250 + 100 * cos(PI / 6.0),
250 + 100 * sin(PI / 6.0)))
pts.append((250 - 100 * cos(PI / 6.0),
250 + 100 * sin(PI / 6.0)))
def draw():
background(200)
fill(255, 100)
b_poly_arc_augmented(pts, rds)
fill(0, 0, 100)
for pt in pts:
ellipse(pt[0], pt[1], 10, 10)
def mouseWheel(event):
global r, d
for i, pt in enumerate(pts):
if dist(mouseX, mouseY, pt[0], pt[1]) < 10:
rds[i] += 5 * event.delta
return False
def mousePressed():
global dragged_pt
for i, pt in enumerate(pts):
if dist(mouseX, mouseY, pt[0], pt[1]) < 10:
dragged_pt = i
break
def mouseDragged():
if dragged_pt >= 0:
pts[dragged_pt] = mouseX, mouseY
def mouseReleased():
global dragged_pt
dragged_pt = -1
def b_poly_arc_augmented(op_list, or_list):
assert len(op_list) == len(or_list), \
"Number of points and radii not the same"
# remove overlapping adjacent points
p_list, r_list, r2_list = [], [], or_list[:]
for i1, p1 in enumerate(op_list):
i2 = (i1 + 1) % len(op_list)
p2, r2, r1 = op_list[i2], r2_list[i2], r2_list[i1]
if dist(p1[0], p1[1], p2[0], p2[1]) > 1: # or p1 != p2:
p_list.append(p1)
r_list.append(r1)
else:
r2_list[i2] = min(r1, r2)
# reduce radius that won't fit
for i1, p1 in enumerate(p_list):
i2 = (i1 + 1) % len(p_list)
p2, r2, r1 = p_list[i2], r_list[i2], r_list[i1]
r_list[i1], r_list[i2] = reduce_radius(p1, p2, r1, r2)
# calculate the tangents
a_list = []
for i1, p1 in enumerate(p_list):
i2 = (i1 + 1) % len(p_list)
p2, r2, r1 = p_list[i2], r_list[i2], r_list[i1]
a = circ_circ_tangent(p1, p2, r1, r2)
a_list.append(a)
# draw
beginShape()
for i1, _ in enumerate(a_list):
i2 = (i1 + 1) % len(a_list)
p1, p2, r1, r2 = p_list[i1], p_list[i2], r_list[i1], r_list[i2]
a1, p11, p12 = a_list[i1]
a2, p21, p22 = a_list[i2]
if a1 and a2:
start = a1 if a1 < a2 else a1 - TWO_PI
if r2 < 0:
a2 = a2 - TWO_PI
b_arc(p2[0], p2[1], r2 * 2, r2 * 2, start, a2, mode=2)
else:
# when the the segment is smaller than the diference between
# radius, circ_circ_tangent won't renturn the angle
# ellipse(p2[0], p2[1], r2 * 2, r2 * 2) # debug
if a1:
vertex(p12[0], p12[1])
if a2:
vertex(p21[0], p21[1])
endShape(CLOSE)
def reduce_radius(p1, p2, r1, r2):
d = dist(p1[0], p1[1], p2[0], p2[1])
ri = abs(r1 - r2)
if d - ri < 0:
if r1 > r2:
r1 = map(d, ri + 1, 0, r1, r2)
else:
r2 = map(d, ri + 1, 0, r2, r1)
return(r1, r2)
def circ_circ_tangent(p1, p2, r1, r2):
d = dist(p1[0], p1[1], p2[0], p2[1])
ri = r1 - r2
line_angle = atan2(p1[0] - p2[0], p2[1] - p1[1])
if d - abs(ri) > 0:
theta = asin(ri / float(d))
x1 = -cos(line_angle + theta) * r1
y1 = -sin(line_angle + theta) * r1
x2 = -cos(line_angle + theta) * r2
y2 = -sin(line_angle + theta) * r2
return (line_angle + theta,
(p1[0] - x1, p1[1] - y1),
(p2[0] - x2, p2[1] - y2))
else:
return (None,
(p1[0], p1[1]),
(p2[0], p2[1]))
def b_arc(cx, cy, w, h, start_angle, end_angle, mode=0):
"""
A bezier approximation of an arc
using the same signature as the original Processing arc()
mode: 0 "normal" arc, using beginShape() and endShape()
1 "middle" used in recursive call of smaller arcs
2 "naked" like normal, but without beginShape() and endShape()
for use inside a larger PShape
"""
theta = end_angle - start_angle
# Compute raw Bezier coordinates.
if mode != 1 or abs(theta) < HALF_PI:
x0 = cos(theta / 2.0)
y0 = sin(theta / 2.0)
x3 = x0
y3 = 0 - y0
x1 = (4.0 - x0) / 3.0
if y0 != 0:
y1 = ((1.0 - x0) * (3.0 - x0)) / (3.0 * y0) # y0 != 0...
else:
y1 = 0
x2 = x1
y2 = 0 - y1
# Compute rotationally-offset Bezier coordinates, using:
# x' = cos(angle) * x - sin(angle) * y
# y' = sin(angle) * x + cos(angle) * y
bezAng = start_angle + theta / 2.0
cBezAng = cos(bezAng)
sBezAng = sin(bezAng)
rx0 = cBezAng * x0 - sBezAng * y0
ry0 = sBezAng * x0 + cBezAng * y0
rx1 = cBezAng * x1 - sBezAng * y1
ry1 = sBezAng * x1 + cBezAng * y1
rx2 = cBezAng * x2 - sBezAng * y2
ry2 = sBezAng * x2 + cBezAng * y2
rx3 = cBezAng * x3 - sBezAng * y3
ry3 = sBezAng * x3 + cBezAng * y3
# Compute scaled and translated Bezier coordinates.
rx, ry = w / 2.0, h / 2.0
px0 = cx + rx * rx0
py0 = cy + ry * ry0
px1 = cx + rx * rx1
py1 = cy + ry * ry1
px2 = cx + rx * rx2
py2 = cy + ry * ry2
px3 = cx + rx * rx3
py3 = cy + ry * ry3
# Debug points... comment this out!
# stroke(0)
# ellipse(px3, py3, 15, 15)
# ellipse(px0, py0, 5, 5)
# Drawing
## if mode == 0: # 'normal' arc (not 'middle' nor 'naked')
## beginShape()
if mode != 1: # if not 'middle'
vertex(px3, py3)
if abs(theta) < HALF_PI:
bezierVertex(px2, py2, px1, py1, px0, py0)
else:
# to avoid distortion, break into 2 smaller arcs
b_arc(cx, cy, w, h, start_angle, end_angle - theta / 2.0, mode=1)
b_arc(cx, cy, w, h, start_angle + theta / 2.0, end_angle, mode=1)
## if mode == 0: # end of a 'normal' arc
## endShape()
# ==== This is required by pyp5js to work
# Register your events functions here
event_functions = {"mouseWheel": mouseWheel, "mousePressed": mousePressed, "mouseDragged": mouseDragged, "mouseReleased": mouseReleased, }
start_p5(setup, draw, event_functions)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Wyświetl plik

@ -0,0 +1,285 @@
# Transcrypt runtime module
#__pragma__ ('js', 'export var __envir__ = {{}};\n{}', __include__ ('org/transcrypt/__envir__.js'))
#__pragma__ ('js', '{}', __include__ ('org/transcrypt/__core__.js'))
#__pragma__ ('js', '{}', __include__ ('org/transcrypt/__builtin__.js'))
#__pragma__ ('skip')
copy = Math = __typeof__ = __repr__ = document = console = window = 0
#__pragma__ ('noskip')
#__pragma__ ('notconv') # !!! tconv gives a problem with __terminal__, needs investigation
#__pragma__ ('nokwargs')
#__pragma__ ('noalias', 'sort')
class BaseException:
pass
class Exception (BaseException):
#__pragma__ ('kwargs')
def __init__ (self, *args, **kwargs):
self.__args__ = args
try:
self.stack = kwargs.error.stack # Integrate with JavaScript Error object
except:
self.stack = 'No stack trace available'
#__pragma__ ('nokwargs')
def __repr__ (self):
if len (self.__args__) > 1:
return '{}{}'.format (self.__class__.__name__, repr (tuple (self.__args__)))
elif len (self.__args__):
return '{}({})'.format (self.__class__.__name__, repr (self.__args__ [0]))
else:
return '{}()'.format (self.__class__.__name__)
def __str__ (self):
if len (self.__args__) > 1:
return str (tuple (self.__args__))
elif len (self.__args__):
return str (self.__args__ [0])
else:
return ''
class IterableError (Exception):
def __init__ (self, error):
Exception.__init__ (self, 'Can\'t iterate over non-iterable', error = error)
class StopIteration (Exception):
def __init__ (self, error):
Exception.__init__ (self, 'Iterator exhausted', error = error)
class ValueError (Exception):
def __init__ (self, message, error):
Exception.__init__ (self, message, error = error)
class KeyError (Exception):
def __init__ (self, message, error):
Exception.__init__ (self, message, error = error)
class AssertionError (Exception):
def __init__ (self, message, error):
if message:
Exception.__init__ (self, message, error = error)
else:
Exception.__init__ (self, error = error)
class NotImplementedError (Exception):
def __init__(self, message, error):
Exception.__init__(self, message, error = error)
class IndexError (Exception):
def __init__(self, message, error):
Exception.__init__(self, message, error = error)
class AttributeError (Exception):
def __init__(self, message, error):
Exception.__init__(self, message, error = error)
class TypeError (Exception):
def __init__(self, message, error):
Exception.__init__(self, message, error = error)
# Warnings Exceptions
# N.B. This is a limited subset of the warnings defined in
# the cpython implementation to keep things small for now.
class Warning (Exception):
''' Warning Base Class
'''
pass
class UserWarning (Warning):
pass
class DeprecationWarning (Warning):
pass
class RuntimeWarning (Warning):
pass
#__pragma__ ('kwargs')
def __sort__ (iterable, key = None, reverse = False): # Used by py_sort, can deal with kwargs
if key:
iterable.sort (lambda a, b: 1 if key (a) > key (b) else -1) # JavaScript sort, case '==' is irrelevant for sorting
else:
iterable.sort () # JavaScript sort
if reverse:
iterable.reverse ()
def sorted (iterable, key = None, reverse = False):
if type (iterable) == dict:
result = copy (iterable.keys ())
else:
result = copy (iterable)
__sort__ (result, key, reverse)
return result
#__pragma__ ('nokwargs')
def map (func, iterable):
return [func (item) for item in iterable]
def filter (func, iterable):
if func == None:
func = bool
return [item for item in iterable if func (item)]
def divmod (n, d):
return n // d, n % d
#__pragma__ ('ifdef', '__complex__')
class complex:
def __init__ (self, real, imag = None):
if imag == None:
if type (real) == complex:
self.real = real.real
self.imag = real.imag
else:
self.real = real
self.imag = 0
else:
self.real = real
self.imag = imag
def __neg__ (self):
return complex (-self.real, -self.imag)
def __exp__ (self):
modulus = Math.exp (self.real)
return complex (modulus * Math.cos (self.imag), modulus * Math.sin (self.imag))
def __log__ (self):
return complex (Math.log (Math.sqrt (self.real * self.real + self.imag * self.imag)), Math.atan2 (self.imag, self.real))
def __pow__ (self, other): # a ** b = exp (b log a)
return (self.__log__ () .__mul__ (other)) .__exp__ ()
def __rpow__ (self, real): # real ** comp -> comp.__rpow__ (real)
return self.__mul__ (Math.log (real)) .__exp__ ()
def __mul__ (self, other):
if __typeof__ (other) is 'number':
return complex (self.real * other, self.imag * other)
else:
return complex (self.real * other.real - self.imag * other.imag, self.real * other.imag + self.imag * other.real)
def __rmul__ (self, real): # real + comp -> comp.__rmul__ (real)
return complex (self.real * real, self.imag * real)
def __div__ (self, other):
if __typeof__ (other) is 'number':
return complex (self.real / other, self.imag / other)
else:
denom = other.real * other.real + other.imag * other.imag
return complex (
(self.real * other.real + self.imag * other.imag) / denom,
(self.imag * other.real - self.real * other.imag) / denom
)
def __rdiv__ (self, real): # real / comp -> comp.__rdiv__ (real)
denom = self.real * self.real
return complex (
(real * self.real) / denom,
(real * self.imag) / denom
)
def __add__ (self, other):
if __typeof__ (other) is 'number':
return complex (self.real + other, self.imag)
else: # Assume other is complex
return complex (self.real + other.real, self.imag + other.imag)
def __radd__ (self, real): # real + comp -> comp.__radd__ (real)
return complex (self.real + real, self.imag)
def __sub__ (self, other):
if __typeof__ (other) is 'number':
return complex (self.real - other, self.imag)
else:
return complex (self.real - other.real, self.imag - other.imag)
def __rsub__ (self, real): # real - comp -> comp.__rsub__ (real)
return complex (real - self.real, -self.imag)
def __repr__ (self):
return '({}{}{}j)'.format (self.real, '+' if self.imag >= 0 else '', self.imag)
def __str__ (self):
return __repr__ (self) [1 : -1]
def __eq__ (self, other):
if __typeof__ (other) is 'number':
return self.real == other
else:
return self.real == other.real and self.imag == other.imag
def __ne__ (self, other):
if __typeof__ (other) is 'number':
return self.real != other
else:
return self.real != other.real or self.imag != other.imag
def conjugate (self):
return complex (self.real, -self.imag)
def __conj__ (aNumber):
if isinstance (aNumber, complex):
return complex (aNumber.real, -aNumber.imag)
else:
return complex (aNumber, 0)
#__pragma__ ('endif')
class __Terminal__:
'''
Printing to either the console or to html happens async, but is blocked by calling window.prompt.
So while all input and print statements are encountered in normal order, the print's exit immediately without yet having actually printed
This means the next input takes control, blocking actual printing and so on indefinitely
The effect is that everything's only printed after all inputs are done
To prevent that, what's needed is to only execute the next window.prompt after actual printing has been done
Since we've no way to find out when that is, a timeout is used.
'''
def __init__ (self):
self.buffer = ''
try:
self.element = document.getElementById ('__terminal__')
except:
self.element = None
if self.element:
self.element.style.overflowX = 'auto'
self.element.style.boxSizing = 'border-box'
self.element.style.padding = '5px'
self.element.innerHTML = '_'
#__pragma__ ('kwargs')
def print (self, *args, sep = ' ', end = '\n'):
self.buffer = '{}{}{}'.format (self.buffer, sep.join ([str (arg) for arg in args]), end) [-4096 : ]
if self.element:
self.element.innerHTML = self.buffer.replace ('\n', '<br>') .replace (' ', '&nbsp')
self.element.scrollTop = self.element.scrollHeight
else:
console.log (sep.join ([str (arg) for arg in args]))
def input (self, question):
self.print ('{}'.format (question), end = '')
answer = window.prompt ('\n'.join (self.buffer.split ('\n') [-8:]))
self.print (answer)
return answer
#__pragma__ ('nokwargs')
__terminal__ = __Terminal__ ()
print = __terminal__.print
input = __terminal__.input

File diff suppressed because one or more lines are too long

Wyświetl plik

@ -0,0 +1,205 @@
// Transcrypt'ed from Python, 2019-06-06 21:37:32
import {AssertionError, AttributeError, BaseException, DeprecationWarning, Exception, IndexError, IterableError, KeyError, NotImplementedError, RuntimeWarning, StopIteration, UserWarning, ValueError, Warning, __JsIterator__, __PyIterator__, __Terminal__, __add__, __and__, __call__, __class__, __envir__, __eq__, __floordiv__, __ge__, __get__, __getcm__, __getitem__, __getslice__, __getsm__, __gt__, __i__, __iadd__, __iand__, __idiv__, __ijsmod__, __ilshift__, __imatmul__, __imod__, __imul__, __in__, __init__, __ior__, __ipow__, __irshift__, __isub__, __ixor__, __jsUsePyNext__, __jsmod__, __k__, __kwargtrans__, __le__, __lshift__, __lt__, __matmul__, __mergefields__, __mergekwargtrans__, __mod__, __mul__, __ne__, __neg__, __nest__, __or__, __pow__, __pragma__, __proxy__, __pyUseJsNext__, __rshift__, __setitem__, __setproperty__, __setslice__, __sort__, __specialattrib__, __sub__, __super__, __t__, __terminal__, __truediv__, __withblock__, __xor__, all, any, assert, bool, bytearray, bytes, callable, chr, deepcopy, delattr, dict, dir, divmod, enumerate, getattr, hasattr, input, isinstance, issubclass, len, list, object, ord, property, py_TypeError, py_iter, py_metatype, py_next, py_reversed, py_typeof, range, repr, setattr, sorted, sum, tuple, zip} from './org.transcrypt.__runtime__.js';
import {ADD, ALT, ARROW, AUTO, AXES, BACKSPACE, BASELINE, BEVEL, BEZIER, BLEND, BLUR, BOLD, BOLDITALIC, BOTTOM, BURN, CENTER, CHORD, CLAMP, CLOSE, CONTROL, CORNER, CORNERS, CROSS, CURVE, DARKEST, DEGREES, DEG_TO_RAD, DELETE, DIFFERENCE, DILATE, DODGE, DOWN_ARROW, ENTER, ERODE, ESCAPE, EXCLUSION, FILL, GRAY, GRID, HALF_PI, HAND, HARD_LIGHT, HSB, HSL, IMAGE, IMMEDIATE, INVERT, ITALIC, LANDSCAPE, LEFT, LEFT_ARROW, LIGHTEST, LINEAR, LINES, LINE_LOOP, LINE_STRIP, MIRROR, MITER, MOVE, MULTIPLY, NEAREST, NORMAL, OPAQUE, OPEN, OPTION, OVERLAY, P2D, PI, PIE, POINTS, PORTRAIT, POSTERIZE, PROJECT, QUADRATIC, QUADS, QUAD_STRIP, QUARTER_PI, RADIANS, RADIUS, RAD_TO_DEG, REPEAT, REPLACE, RETURN, RGB, RIGHT, RIGHT_ARROW, ROUND, SCREEN, SHIFT, SOFT_LIGHT, SQUARE, STROKE, SUBTRACT, TAB, TAU, TEXT, TEXTURE, THRESHOLD, TOP, TRIANGLES, TRIANGLE_FAN, TRIANGLE_STRIP, TWO_PI, UP_ARROW, WAIT, WEBGL, _CTX_MIDDLE, _DEFAULT_FILL, _DEFAULT_LEADMULT, _DEFAULT_STROKE, _DEFAULT_TEXT_FILL, _P5_INSTANCE, abs, accelerationX, accelerationY, accelerationZ, acos, alpha, ambientLight, ambientMaterial, angleMode, append, applyMatrix, arc, arrayCopy, asin, atan, atan2, background, beginContour, beginShape, bezier, bezierDetail, bezierPoint, bezierTangent, bezierVertex, blend, blendMode, blue, boolean, box, brightness, byte, camera, ceil, char, circle, color, colorMode, concat, cone, constrain, copy, cos, createCamera, createCanvas, createGraphics, createImage, createNumberDict, createShader, createStringDict, createVector, createWriter, cursor, curve, curveDetail, curvePoint, curveTangent, curveTightness, curveVertex, cylinder, day, debugMode, degrees, deviceOrientation, directionalLight, disableFriendlyErrors, displayDensity, displayHeight, displayWidth, dist, ellipse, ellipseMode, ellipsoid, endContour, endShape, exp, fill, filter, float, floor, focused, frameCount, frameRate, fullscreen, getURL, getURLParams, getURLPath, global_p5_injection, green, height, hex, hour, httpDo, httpGet, httpPost, hue, image, imageMode, int, join, key, keyCode, keyIsDown, keyIsPressed, lerp, lerpColor, lightness, lights, line, loadBytes, loadFont, loadImage, loadJSON, loadModel, loadPixels, loadShader, loadStrings, loadTable, loadXML, log, loop, mag, map, match, matchAll, max, millis, min, minute, model, month, mouseButton, mouseIsPressed, mouseX, mouseY, nf, nfc, nfp, nfs, noCanvas, noCursor, noDebugMode, noFill, noLoop, noSmooth, noStroke, noTint, noise, noiseDetail, noiseSeed, norm, normalMaterial, orbitControl, ortho, pAccelerationX, pAccelerationY, pAccelerationZ, pRotationX, pRotationY, pRotationZ, perspective, pixelDensity, pixels, plane, pmouseX, pmouseY, point, pointLight, pow, pre_draw, preload, print, push, pwinMouseX, pwinMouseY, py_clear, py_get, py_pop, py_sort, py_split, quad, quadraticVertex, radians, random, randomGaussian, randomSeed, rect, rectMode, red, redraw, remove, resetMatrix, resetShader, resizeCanvas, reverse, rotate, rotateX, rotateY, rotateZ, rotationX, rotationY, rotationZ, round, saturation, save, saveCanvas, saveFrames, saveJSON, saveStrings, saveTable, scale, second, set, setAttributes, setCamera, setMoveThreshold, setShakeThreshold, shader, shearX, shearY, shininess, shorten, shuffle, sin, smooth, specularMaterial, sphere, splice, splitTokens, sq, sqrt, square, start_p5, str, stroke, strokeCap, strokeJoin, strokeWeight, subset, tan, text, textAlign, textAscent, textDescent, textFont, textLeading, textSize, textStyle, textWidth, texture, textureMode, textureWrap, tint, torus, touches, translate, triangle, trim, turnAxis, unchar, unhex, updatePixels, vertex, width, winMouseX, winMouseY, windowHeight, windowWidth, year} from './pytop5js.js';
var __name__ = '__main__';
export var pts = list ([]);
export var rds = list ([30, 70, 50]);
export var dragged_pt = -(1);
export var setup = function () {
createCanvas (500, 500);
pts.append (tuple ([250, 150]));
pts.append (tuple ([250 + 100 * cos (PI / 6.0), 250 + 100 * sin (PI / 6.0)]));
pts.append (tuple ([250 - 100 * cos (PI / 6.0), 250 + 100 * sin (PI / 6.0)]));
};
export var draw = function () {
background (200);
fill (255, 100);
b_poly_arc_augmented (pts, rds);
fill (0, 0, 100);
for (var pt of pts) {
ellipse (pt [0], pt [1], 10, 10);
}
};
export var mouseWheel = function (event) {
for (var [i, pt] of enumerate (pts)) {
if (dist (mouseX, mouseY, pt [0], pt [1]) < 10) {
rds [i] += 5 * event.delta;
}
}
return false;
};
export var mousePressed = function () {
for (var [i, pt] of enumerate (pts)) {
if (dist (mouseX, mouseY, pt [0], pt [1]) < 10) {
dragged_pt = i;
break;
}
}
};
export var mouseDragged = function () {
if (dragged_pt >= 0) {
pts [dragged_pt] = tuple ([mouseX, mouseY]);
}
};
export var mouseReleased = function () {
dragged_pt = -(1);
};
export var b_poly_arc_augmented = function (op_list, or_list) {
var __left0__ = tuple ([list ([]), list ([]), or_list.__getslice__ (0, null, 1)]);
var p_list = __left0__ [0];
var r_list = __left0__ [1];
var r2_list = __left0__ [2];
for (var [i1, p1] of enumerate (op_list)) {
var i2 = __mod__ (i1 + 1, len (op_list));
var __left0__ = tuple ([op_list [i2], r2_list [i2], r2_list [i1]]);
var p2 = __left0__ [0];
var r2 = __left0__ [1];
var r1 = __left0__ [2];
if (dist (p1 [0], p1 [1], p2 [0], p2 [1]) > 1) {
p_list.append (p1);
r_list.append (r1);
}
else {
r2_list [i2] = min (r1, r2);
}
}
for (var [i1, p1] of enumerate (p_list)) {
var i2 = __mod__ (i1 + 1, len (p_list));
var __left0__ = tuple ([p_list [i2], r_list [i2], r_list [i1]]);
var p2 = __left0__ [0];
var r2 = __left0__ [1];
var r1 = __left0__ [2];
var __left0__ = reduce_radius (p1, p2, r1, r2);
r_list [i1] = __left0__ [0];
r_list [i2] = __left0__ [1];
}
var a_list = list ([]);
for (var [i1, p1] of enumerate (p_list)) {
var i2 = __mod__ (i1 + 1, len (p_list));
var __left0__ = tuple ([p_list [i2], r_list [i2], r_list [i1]]);
var p2 = __left0__ [0];
var r2 = __left0__ [1];
var r1 = __left0__ [2];
var a = circ_circ_tangent (p1, p2, r1, r2);
a_list.append (a);
}
beginShape ();
for (var [i1, _] of enumerate (a_list)) {
var i2 = __mod__ (i1 + 1, len (a_list));
var __left0__ = tuple ([p_list [i1], p_list [i2], r_list [i1], r_list [i2]]);
var p1 = __left0__ [0];
var p2 = __left0__ [1];
var r1 = __left0__ [2];
var r2 = __left0__ [3];
var __left0__ = a_list [i1];
var a1 = __left0__ [0];
var p11 = __left0__ [1];
var p12 = __left0__ [2];
var __left0__ = a_list [i2];
var a2 = __left0__ [0];
var p21 = __left0__ [1];
var p22 = __left0__ [2];
if (a1 && a2) {
var start = (a1 < a2 ? a1 : a1 - TWO_PI);
if (r2 < 0) {
var a2 = a2 - TWO_PI;
}
b_arc (p2 [0], p2 [1], r2 * 2, r2 * 2, start, a2, __kwargtrans__ ({mode: 2}));
}
else {
if (a1) {
vertex (p12 [0], p12 [1]);
}
if (a2) {
vertex (p21 [0], p21 [1]);
}
}
}
endShape (CLOSE);
};
export var reduce_radius = function (p1, p2, r1, r2) {
var d = dist (p1 [0], p1 [1], p2 [0], p2 [1]);
var ri = abs (r1 - r2);
if (d - ri < 0) {
if (r1 > r2) {
var r1 = map (d, ri + 1, 0, r1, r2);
}
else {
var r2 = map (d, ri + 1, 0, r2, r1);
}
}
return tuple ([r1, r2]);
};
export var circ_circ_tangent = function (p1, p2, r1, r2) {
var d = dist (p1 [0], p1 [1], p2 [0], p2 [1]);
var ri = r1 - r2;
var line_angle = atan2 (p1 [0] - p2 [0], p2 [1] - p1 [1]);
if (d - abs (ri) > 0) {
var theta = asin (ri / float (d));
var x1 = -(cos (line_angle + theta)) * r1;
var y1 = -(sin (line_angle + theta)) * r1;
var x2 = -(cos (line_angle + theta)) * r2;
var y2 = -(sin (line_angle + theta)) * r2;
return tuple ([line_angle + theta, tuple ([p1 [0] - x1, p1 [1] - y1]), tuple ([p2 [0] - x2, p2 [1] - y2])]);
}
else {
return tuple ([null, tuple ([p1 [0], p1 [1]]), tuple ([p2 [0], p2 [1]])]);
}
};
export var b_arc = function (cx, cy, w, h, start_angle, end_angle, mode) {
if (typeof mode == 'undefined' || (mode != null && mode.hasOwnProperty ("__kwargtrans__"))) {;
var mode = 0;
};
var theta = end_angle - start_angle;
if (mode != 1 || abs (theta) < HALF_PI) {
var x0 = cos (theta / 2.0);
var y0 = sin (theta / 2.0);
var x3 = x0;
var y3 = 0 - y0;
var x1 = (4.0 - x0) / 3.0;
if (y0 != 0) {
var y1 = ((1.0 - x0) * (3.0 - x0)) / (3.0 * y0);
}
else {
var y1 = 0;
}
var x2 = x1;
var y2 = 0 - y1;
var bezAng = start_angle + theta / 2.0;
var cBezAng = cos (bezAng);
var sBezAng = sin (bezAng);
var rx0 = cBezAng * x0 - sBezAng * y0;
var ry0 = sBezAng * x0 + cBezAng * y0;
var rx1 = cBezAng * x1 - sBezAng * y1;
var ry1 = sBezAng * x1 + cBezAng * y1;
var rx2 = cBezAng * x2 - sBezAng * y2;
var ry2 = sBezAng * x2 + cBezAng * y2;
var rx3 = cBezAng * x3 - sBezAng * y3;
var ry3 = sBezAng * x3 + cBezAng * y3;
var __left0__ = tuple ([w / 2.0, h / 2.0]);
var rx = __left0__ [0];
var ry = __left0__ [1];
var px0 = cx + rx * rx0;
var py0 = cy + ry * ry0;
var px1 = cx + rx * rx1;
var py1 = cy + ry * ry1;
var px2 = cx + rx * rx2;
var py2 = cy + ry * ry2;
var px3 = cx + rx * rx3;
var py3 = cy + ry * ry3;
}
if (mode != 1) {
vertex (px3, py3);
}
if (abs (theta) < HALF_PI) {
bezierVertex (px2, py2, px1, py1, px0, py0);
}
else {
b_arc (cx, cy, w, h, start_angle, end_angle - theta / 2.0, __kwargtrans__ ({mode: 1}));
b_arc (cx, cy, w, h, start_angle + theta / 2.0, end_angle, __kwargtrans__ ({mode: 1}));
}
};
export var event_functions = dict ({'mouseWheel': mouseWheel, 'mousePressed': mousePressed, 'mouseDragged': mouseDragged, 'mouseReleased': mouseReleased});
start_p5 (setup, draw, event_functions);
//# sourceMappingURL=sketch_190606b.map

Wyświetl plik

@ -0,0 +1,8 @@
{
"version": 3,
"file": "sketch_190606b.js",
"sources": [
"sketch_190606b.py"
],
"mappings": "AAAA;AAAA;AAAA;AAAA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAGA;AAEA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAGA;AAEA;AACA;AAAA;AAAA;AAAA;AAEA;AAAA;AAEA;AAEA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AAGA;AACA;AACA;AAAA;AAAA;AAEA;AAEA;AAAA;AAEA;AAIA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AAAA;AAEA;AACA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAEA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AAAA;AACA;AAIA;AACA;AAAA;AACA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AAAA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAGA;AACA;AAAA;AAAA;AAIA;AAAA;AAAA;AAAA;AASA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAQA;AACA;AAAA;AACA;AACA;AAAA;AACA;AAEA;AACA;AAAA;AAAA;AAMA;AACA;AA7LA"
}

Plik binarny nie jest wyświetlany.

Wyświetl plik

@ -0,0 +1,190 @@
from pytop5js import *
pts = []
rds = [30, 70, 50]
dragged_pt = -1
def setup():
createCanvas(500, 500)
pts.append((250, 150))
pts.append((250 + 100 * cos(PI / 6.0),
250 + 100 * sin(PI / 6.0)))
pts.append((250 - 100 * cos(PI / 6.0),
250 + 100 * sin(PI / 6.0)))
def draw():
background(200)
fill(255, 100)
b_poly_arc_augmented(pts, rds)
fill(0, 0, 100)
for pt in pts:
ellipse(pt[0], pt[1], 10, 10)
def mouseWheel(event):
global r, d
for i, pt in enumerate(pts):
if dist(mouseX, mouseY, pt[0], pt[1]) < 10:
rds[i] += 5 * event.delta
return False
def mousePressed():
global dragged_pt
for i, pt in enumerate(pts):
if dist(mouseX, mouseY, pt[0], pt[1]) < 10:
dragged_pt = i
break
def mouseDragged():
if dragged_pt >= 0:
pts[dragged_pt] = mouseX, mouseY
def mouseReleased():
global dragged_pt
dragged_pt = -1
def b_poly_arc_augmented(op_list, or_list):
assert len(op_list) == len(or_list), \
"Number of points and radii not the same"
# remove overlapping adjacent points
p_list, r_list, r2_list = [], [], or_list[:]
for i1, p1 in enumerate(op_list):
i2 = (i1 + 1) % len(op_list)
p2, r2, r1 = op_list[i2], r2_list[i2], r2_list[i1]
if dist(p1[0], p1[1], p2[0], p2[1]) > 1: # or p1 != p2:
p_list.append(p1)
r_list.append(r1)
else:
r2_list[i2] = min(r1, r2)
# reduce radius that won't fit
for i1, p1 in enumerate(p_list):
i2 = (i1 + 1) % len(p_list)
p2, r2, r1 = p_list[i2], r_list[i2], r_list[i1]
r_list[i1], r_list[i2] = reduce_radius(p1, p2, r1, r2)
# calculate the tangents
a_list = []
for i1, p1 in enumerate(p_list):
i2 = (i1 + 1) % len(p_list)
p2, r2, r1 = p_list[i2], r_list[i2], r_list[i1]
a = circ_circ_tangent(p1, p2, r1, r2)
a_list.append(a)
# draw
beginShape()
for i1, _ in enumerate(a_list):
i2 = (i1 + 1) % len(a_list)
p1, p2, r1, r2 = p_list[i1], p_list[i2], r_list[i1], r_list[i2]
a1, p11, p12 = a_list[i1]
a2, p21, p22 = a_list[i2]
if a1 and a2:
start = a1 if a1 < a2 else a1 - TWO_PI
if r2 < 0:
a2 = a2 - TWO_PI
b_arc(p2[0], p2[1], r2 * 2, r2 * 2, start, a2, mode=2)
else:
# when the the segment is smaller than the diference between
# radius, circ_circ_tangent won't renturn the angle
# ellipse(p2[0], p2[1], r2 * 2, r2 * 2) # debug
if a1:
vertex(p12[0], p12[1])
if a2:
vertex(p21[0], p21[1])
endShape(CLOSE)
def reduce_radius(p1, p2, r1, r2):
d = dist(p1[0], p1[1], p2[0], p2[1])
ri = abs(r1 - r2)
if d - ri < 0:
if r1 > r2:
r1 = map(d, ri + 1, 0, r1, r2)
else:
r2 = map(d, ri + 1, 0, r2, r1)
return(r1, r2)
def circ_circ_tangent(p1, p2, r1, r2):
d = dist(p1[0], p1[1], p2[0], p2[1])
ri = r1 - r2
line_angle = atan2(p1[0] - p2[0], p2[1] - p1[1])
if d - abs(ri) > 0:
theta = asin(ri / float(d))
x1 = -cos(line_angle + theta) * r1
y1 = -sin(line_angle + theta) * r1
x2 = -cos(line_angle + theta) * r2
y2 = -sin(line_angle + theta) * r2
return (line_angle + theta,
(p1[0] - x1, p1[1] - y1),
(p2[0] - x2, p2[1] - y2))
else:
return (None,
(p1[0], p1[1]),
(p2[0], p2[1]))
def b_arc(cx, cy, w, h, start_angle, end_angle, mode=0):
"""
A bezier approximation of an arc
using the same signature as the original Processing arc()
mode: 0 "normal" arc, using beginShape() and endShape()
1 "middle" used in recursive call of smaller arcs
2 "naked" like normal, but without beginShape() and endShape()
for use inside a larger PShape
"""
theta = end_angle - start_angle
# Compute raw Bezier coordinates.
if mode != 1 or abs(theta) < HALF_PI:
x0 = cos(theta / 2.0)
y0 = sin(theta / 2.0)
x3 = x0
y3 = 0 - y0
x1 = (4.0 - x0) / 3.0
if y0 != 0:
y1 = ((1.0 - x0) * (3.0 - x0)) / (3.0 * y0) # y0 != 0...
else:
y1 = 0
x2 = x1
y2 = 0 - y1
# Compute rotationally-offset Bezier coordinates, using:
# x' = cos(angle) * x - sin(angle) * y
# y' = sin(angle) * x + cos(angle) * y
bezAng = start_angle + theta / 2.0
cBezAng = cos(bezAng)
sBezAng = sin(bezAng)
rx0 = cBezAng * x0 - sBezAng * y0
ry0 = sBezAng * x0 + cBezAng * y0
rx1 = cBezAng * x1 - sBezAng * y1
ry1 = sBezAng * x1 + cBezAng * y1
rx2 = cBezAng * x2 - sBezAng * y2
ry2 = sBezAng * x2 + cBezAng * y2
rx3 = cBezAng * x3 - sBezAng * y3
ry3 = sBezAng * x3 + cBezAng * y3
# Compute scaled and translated Bezier coordinates.
rx, ry = w / 2.0, h / 2.0
px0 = cx + rx * rx0
py0 = cy + ry * ry0
px1 = cx + rx * rx1
py1 = cy + ry * ry1
px2 = cx + rx * rx2
py2 = cy + ry * ry2
px3 = cx + rx * rx3
py3 = cy + ry * ry3
# Debug points... comment this out!
# stroke(0)
# ellipse(px3, py3, 15, 15)
# ellipse(px0, py0, 5, 5)
# Drawing
## if mode == 0: # 'normal' arc (not 'middle' nor 'naked')
## beginShape()
if mode != 1: # if not 'middle'
vertex(px3, py3)
if abs(theta) < HALF_PI:
bezierVertex(px2, py2, px1, py1, px0, py0)
else:
# to avoid distortion, break into 2 smaller arcs
b_arc(cx, cy, w, h, start_angle, end_angle - theta / 2.0, mode=1)
b_arc(cx, cy, w, h, start_angle + theta / 2.0, end_angle, mode=1)
## if mode == 0: # end of a 'normal' arc
## endShape()
# ==== This is required by pyp5js to work
# Register your events functions here
event_functions = {"mouseWheel": mouseWheel, "mousePressed": mousePressed, "mouseDragged": mouseDragged, "mouseReleased": mouseReleased, }
start_p5(setup, draw, event_functions)