kopia lustrzana https://github.com/villares/sketch-a-day
190610
rodzic
0403759647
commit
f3d8ddb362
Plik binarny nie jest wyświetlany.
|
Po Szerokość: | Wysokość: | Rozmiar: 12 KiB |
Plik binarny nie jest wyświetlany.
|
Po Szerokość: | Wysokość: | Rozmiar: 12 KiB |
Plik binarny nie jest wyświetlany.
|
Po Szerokość: | Wysokość: | Rozmiar: 12 KiB |
|
|
@ -1,3 +1,4 @@
|
|||
from copy import deepcopy
|
||||
from arcs import *
|
||||
|
||||
class Poly():
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ A minimal poly editor
|
|||
- Add points
|
||||
"""
|
||||
import pickle
|
||||
from copy import deepcopy
|
||||
from poly import Poly
|
||||
# add_library('GifAnimation')
|
||||
# from gif_exporter import gif_export
|
||||
|
|
|
|||
|
|
@ -0,0 +1,153 @@
|
|||
def b_poly_filleted(p_list, r_list=None, open_poly=False):
|
||||
"""
|
||||
draws a 'filleted' polygon with variable radius
|
||||
dependent on roundedCorner()
|
||||
"""
|
||||
if not r_list:
|
||||
r_list = [0] * len(p_list)
|
||||
assert len(p_list) == len(r_list), \
|
||||
"Number of points and radii not the same"
|
||||
strokeJoin(ROUND)
|
||||
beginShape()
|
||||
for p0, p1, p2, r in zip(p_list,
|
||||
[p_list[-1]] + p_list[:-1],
|
||||
[p_list[-2]] + [p_list[-1]] + p_list[:-2],
|
||||
[r_list[-1]] + r_list[:-1]
|
||||
):
|
||||
m1 = (p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2
|
||||
m2 = (p2[0] + p1[0]) / 2, (p2[1] + p1[1]) / 2
|
||||
b_roundedCorner(p1, m1, m2, r)
|
||||
endShape(CLOSE)
|
||||
|
||||
def b_roundedCorner(pc, p2, p1, r):
|
||||
"""
|
||||
Based on Stackoverflow C# rounded corner post
|
||||
https://stackoverflow.com/questions/24771828/algorithm-for-creating-rounded-corners-in-a-polygon
|
||||
"""
|
||||
def GetProportionPoint(pt, segment, L, dx, dy):
|
||||
factor = float(segment) / L if L != 0 else segment
|
||||
return PVector((pt[0] - dx * factor), (pt[1] - dy * factor))
|
||||
|
||||
# Vector 1
|
||||
dx1 = pc[0] - p1[0]
|
||||
dy1 = pc[1] - p1[1]
|
||||
# Vector 2
|
||||
dx2 = pc[0] - p2[0]
|
||||
dy2 = pc[1] - p2[1]
|
||||
# Angle between vector 1 and vector 2 divided by 2
|
||||
angle = (atan2(dy1, dx1) - atan2(dy2, dx2)) / 2
|
||||
# The length of segment between angular point and the
|
||||
# points of intersection with the circle of a given radius
|
||||
tng = abs(tan(angle))
|
||||
segment = r / tng if tng != 0 else r
|
||||
# Check the segment
|
||||
length1 = sqrt(dx1 * dx1 + dy1 * dy1)
|
||||
length2 = sqrt(dx2 * dx2 + dy2 * dy2)
|
||||
min_len = min(length1, length2)
|
||||
if segment > min_len:
|
||||
segment = min_len
|
||||
max_r = min_len * abs(tan(angle))
|
||||
else:
|
||||
max_r = r
|
||||
# Points of intersection are calculated by the proportion between
|
||||
# length of vector and the length of the segment.
|
||||
p1Cross = GetProportionPoint(pc, segment, length1, dx1, dy1)
|
||||
p2Cross = GetProportionPoint(pc, segment, length2, dx2, dy2)
|
||||
# Calculation of the coordinates of the circle
|
||||
# center by the addition of angular vectors.
|
||||
dx = pc[0] * 2 - p1Cross[0] - p2Cross[0]
|
||||
dy = pc[1] * 2 - p1Cross[1] - p2Cross[1]
|
||||
L = sqrt(dx * dx + dy * dy)
|
||||
d = sqrt(segment * segment + max_r * max_r)
|
||||
circlePoint = GetProportionPoint(pc, d, L, dx, dy)
|
||||
# StartAngle and EndAngle of arc
|
||||
startAngle = atan2(p1Cross[1] - circlePoint[1],
|
||||
p1Cross[0] - circlePoint[0])
|
||||
endAngle = atan2(p2Cross[1] - circlePoint[1],
|
||||
p2Cross[0] - circlePoint[0])
|
||||
# Sweep angle
|
||||
sweepAngle = endAngle - startAngle
|
||||
# Some additional checks
|
||||
A, B = False, False
|
||||
if sweepAngle < 0:
|
||||
A = True
|
||||
startAngle, endAngle = endAngle, startAngle
|
||||
sweepAngle = -sweepAngle
|
||||
# ellipse(pc[0], pc[1], 15, 15) # debug
|
||||
if sweepAngle > PI:
|
||||
B = True
|
||||
startAngle, endAngle = endAngle, startAngle
|
||||
sweepAngle = TWO_PI - sweepAngle
|
||||
# ellipse(pc[0], pc[1], 25, 25) # debug
|
||||
if (A and not B) or (B and not A):
|
||||
startAngle, endAngle = endAngle, startAngle
|
||||
sweepAngle = -sweepAngle
|
||||
# ellipse(pc[0], pc[1], 5, 5) # debug
|
||||
b_arc(circlePoint[0], circlePoint[1], 2 * max_r, 2 * max_r,
|
||||
startAngle, startAngle + sweepAngle, arc_type=2)
|
||||
|
||||
|
||||
def b_arc(cx, cy, w, h, startAngle, endAngle, arc_type=0):
|
||||
"""
|
||||
A bezier approximation of an arc
|
||||
using the same signature as the original Processing arc()
|
||||
arc_type: 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 = endAngle - startAngle
|
||||
# Compute raw Bezier coordinates.
|
||||
if arc_type != 1 or 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 = startAngle + 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 arc_type == 0: # 'normal' arc (not 'middle' nor 'naked')
|
||||
beginShape()
|
||||
if arc_type != 1: # if not 'middle'
|
||||
vertex(px3, py3)
|
||||
if 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, startAngle, endAngle - theta / 2.0, arc_type=1)
|
||||
b_arc(cx, cy, w, h, startAngle + theta / 2.0, endAngle, arc_type=1)
|
||||
if arc_type == 0: # end of a 'normal' arc
|
||||
endShape()
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
(lp0
|
||||
(ipoly
|
||||
Poly
|
||||
p1
|
||||
(dp2
|
||||
S'closed'
|
||||
p3
|
||||
I01
|
||||
sS'lw'
|
||||
p4
|
||||
I1
|
||||
sS'id'
|
||||
p5
|
||||
I0
|
||||
sS'pts'
|
||||
p6
|
||||
(lp7
|
||||
(I0
|
||||
I0
|
||||
I-1
|
||||
tp8
|
||||
a(I6
|
||||
I0
|
||||
I1
|
||||
tp9
|
||||
a(I6
|
||||
I6
|
||||
I1
|
||||
tp10
|
||||
a(I0
|
||||
I6
|
||||
I0
|
||||
tp11
|
||||
asS'holes'
|
||||
p12
|
||||
(lp13
|
||||
(lp14
|
||||
asba(ipoly
|
||||
Poly
|
||||
p15
|
||||
(dp16
|
||||
S'closed'
|
||||
p17
|
||||
I01
|
||||
sS'lw'
|
||||
p18
|
||||
I1
|
||||
sS'id'
|
||||
p19
|
||||
I1
|
||||
sS'pts'
|
||||
p20
|
||||
(lp21
|
||||
(I-1
|
||||
I-1
|
||||
I0
|
||||
tp22
|
||||
a(I-6
|
||||
I-1
|
||||
I0
|
||||
tp23
|
||||
a(I-6
|
||||
I-6
|
||||
I0
|
||||
tp24
|
||||
a(I-1
|
||||
I-6
|
||||
I0
|
||||
tp25
|
||||
asS'holes'
|
||||
p26
|
||||
(lp27
|
||||
(lp28
|
||||
(I-2
|
||||
I-3
|
||||
I0
|
||||
tp29
|
||||
a(I-3
|
||||
I-3
|
||||
I1
|
||||
tp30
|
||||
a(I-2
|
||||
I-2
|
||||
I0
|
||||
tp31
|
||||
aasba.
|
||||
|
|
@ -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,232 @@
|
|||
from copy import deepcopy
|
||||
from arcs import *
|
||||
|
||||
class Poly():
|
||||
|
||||
selected = -1
|
||||
text_on = False
|
||||
selected_drag = -1
|
||||
drag_hole = -1
|
||||
drag_pt = -1
|
||||
id = 0
|
||||
|
||||
def __init__(self, pts, holes=None, closed=True, lw=1):
|
||||
self.pts = pts
|
||||
self.holes = holes if holes else [[]]
|
||||
self.closed = closed
|
||||
self.lw = lw
|
||||
|
||||
@classmethod
|
||||
def setup_grid(cls, cell_size, order, x_offset, y_offset):
|
||||
cls.cell_size = cell_size
|
||||
cls.order = order
|
||||
cls.x_offset, cls.y_offset = x_offset, y_offset
|
||||
cls.polys = []
|
||||
cls.text_on = False
|
||||
|
||||
def plot(self):
|
||||
for i, p in enumerate(self.polys):
|
||||
self.id = i if self == p else self.id
|
||||
pushStyle()
|
||||
strokeJoin(ROUND)
|
||||
strokeWeight(self.lw)
|
||||
if self.selected_drag == self.id:
|
||||
stroke(200, 0, 0)
|
||||
else:
|
||||
stroke(0)
|
||||
if len(self.pts) >= 2:
|
||||
if self.closed:
|
||||
fill(100)
|
||||
else:
|
||||
noFill()
|
||||
beginShape()
|
||||
Poly.draw_pts(self.pts)
|
||||
for hole in self.holes:
|
||||
beginContour()
|
||||
Poly.draw_pts(hole)
|
||||
endContour()
|
||||
if self.closed:
|
||||
endShape(CLOSE)
|
||||
else:
|
||||
endShape()
|
||||
if self.text_on:
|
||||
self.annotate_pts(self.id, self.pts, color(200, 0, 0), 5)
|
||||
self.annotate_pts(self.id, self.holes[0], color(0, 0, 200), 5)
|
||||
popStyle()
|
||||
|
||||
@classmethod
|
||||
def draw_pts(cls, pts):
|
||||
for i, pt in enumerate(pts):
|
||||
x, y, corner = pt
|
||||
sx, sy = cls.grid_to_screen(x, y)
|
||||
if corner == 0:
|
||||
vertex(sx, sy)
|
||||
elif corner > 0:
|
||||
pp = cls.grid_to_screen(pts[i - 1])
|
||||
np = cls.grid_to_screen(pts[(i + 1) % len(pts)])
|
||||
r = corner * cls.cell_size
|
||||
b_roundedCorner((sx, sy), np, pp, r) # pt[2])
|
||||
else:
|
||||
if keyPressed:
|
||||
vertex(sx, sy)
|
||||
|
||||
|
||||
def remove_pt(self):
|
||||
snap = self.mouse_snap()
|
||||
if snap:
|
||||
for pt in self.pts:
|
||||
if pt[:2] == snap:
|
||||
self.pts.remove(pt)
|
||||
return True
|
||||
for h in self.holes:
|
||||
for pt in h:
|
||||
if pt[:2] == snap:
|
||||
h.remove(pt)
|
||||
return True
|
||||
|
||||
def set_drag(self): # , io, jo):
|
||||
snap = Poly.mouse_snap()
|
||||
if snap:
|
||||
for ipt, pt in enumerate(self.pts):
|
||||
if pt[:2] == snap: # (io, jo):
|
||||
Poly.drag_pt = ipt
|
||||
return True
|
||||
for ih, h in enumerate(self.holes):
|
||||
for ipt, pt in enumerate(h):
|
||||
if pt[:2] == snap: # (io, jo):
|
||||
Poly.drag_hole = ih
|
||||
Poly.drag_pt = ipt
|
||||
return True
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def annotate_pts(cls, id, pts, c, scale_m=1):
|
||||
strokeWeight(5)
|
||||
textSize(12)
|
||||
fill(c)
|
||||
stroke(c)
|
||||
for pt in pts:
|
||||
i, j = pt[0], pt[1]
|
||||
sx, sy = cls.grid_to_screen(i, j)
|
||||
point(sx, sy)
|
||||
text(str(id) + ":" + str((i * scale_m, j * scale_m)), sx, sy)
|
||||
|
||||
@classmethod
|
||||
def draw_grid(cls):
|
||||
stroke(128)
|
||||
noFill()
|
||||
for x in range(cls.order):
|
||||
for y in range(cls.order):
|
||||
rect(x * cls.cell_size, y * cls.cell_size,
|
||||
cls.cell_size, cls.cell_size)
|
||||
|
||||
@staticmethod
|
||||
def clockwise_sort(xy_pairs):
|
||||
# https://stackoverflow.com/questions/51074984/sorting-according-to-clockwise-point-coordinates
|
||||
data_len = len(xy_pairs)
|
||||
if data_len > 2:
|
||||
x, y = zip(*xy_pairs)
|
||||
else:
|
||||
return xy_pairs
|
||||
centroid_x, centroid_y = sum(x) / data_len, sum(y) / data_len
|
||||
xy_sorted = sorted(xy_pairs,
|
||||
key=lambda p: atan2((p[1] - centroid_y), (p[0] - centroid_x)))
|
||||
xy_sorted_xy = [
|
||||
coord for pair in list(zip(*xy_sorted)) for coord in pair]
|
||||
half_len = int(len(xy_sorted_xy) / 2)
|
||||
return list(zip(xy_sorted_xy[:half_len], xy_sorted_xy[half_len:]))
|
||||
|
||||
@classmethod
|
||||
def mouse_snap(cls):
|
||||
for i in range(cls.order):
|
||||
x = i * cls.cell_size
|
||||
for j in range(cls.order):
|
||||
y = j * cls.cell_size
|
||||
# grid origin correction
|
||||
io, jo = i - cls.x_offset, j - cls.y_offset
|
||||
if dist(mouseX, mouseY, x, y) < cls.cell_size / 2:
|
||||
return (io, jo)
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def mouse_pressed(cls):
|
||||
if keyPressed and keyCode == CONTROL:
|
||||
for p in cls.polys:
|
||||
if p.remove_pt(): # io, jo):
|
||||
return
|
||||
else:
|
||||
for ip, p in enumerate(cls.polys):
|
||||
if p.set_drag(): # io, jo):
|
||||
cls.selected_drag = ip
|
||||
return
|
||||
cls.selected_drag = -1 # click outside known vertices deselects
|
||||
|
||||
@classmethod
|
||||
def mouse_dragged(cls):
|
||||
if cls.selected_drag >= 0 and not keyPressed:
|
||||
# a Poly point has been selected to be dragged
|
||||
# and no modifier key is pressed...
|
||||
if cls.drag_hole == -1: # if no hole was selected
|
||||
poly = cls.polys[cls.selected_drag]
|
||||
i, j = cls.screen_to_grid(mouseX, mouseY)
|
||||
poly.pts[cls.drag_pt] = (i, j, poly.pts[cls.drag_pt][2])
|
||||
else:
|
||||
poly = cls.polys[cls.selected_drag]
|
||||
hole = poly.holes[cls.drag_hole]
|
||||
i, j = cls.screen_to_grid(mouseX, mouseY)
|
||||
hole[cls.drag_pt] = (i, j, hole[cls.drag_pt][2])
|
||||
|
||||
elif cls.selected_drag >= 0 and key == "m":
|
||||
poly = cls.polys[cls.selected_drag]
|
||||
dragged_pt = poly.pts[cls.drag_pt]
|
||||
mx, my = cls.screen_to_grid(mouseX, mouseY)
|
||||
dx, dy = mx - dragged_pt[0], my - dragged_pt[1]
|
||||
pts = poly.pts
|
||||
for i, pt in enumerate(pts):
|
||||
pts[i] = (pt[0] + dx, pt[1] + dy, pt[2] )
|
||||
for hole in poly.holes:
|
||||
for i, pt in enumerate(hole):
|
||||
hole[i] = (pt[0] + dx, pt[1] + dy, pt[2])
|
||||
|
||||
@classmethod
|
||||
def grid_to_screen(cls, *args):
|
||||
if len(args) == 1:
|
||||
x, y = args[0][0], args[0][1]
|
||||
else:
|
||||
x, y = args
|
||||
return ((x + cls.x_offset) * cls.cell_size,
|
||||
(y + cls.y_offset) * cls.cell_size)
|
||||
|
||||
@classmethod
|
||||
def screen_to_grid(cls, x, y):
|
||||
return (int(x / cls.cell_size) - cls.x_offset,
|
||||
int(y / cls.cell_size) - cls.y_offset)
|
||||
|
||||
@classmethod
|
||||
def mouse_released(cls):
|
||||
if cls.selected_drag >= 0 and keyPressed and keyCode == SHIFT:
|
||||
# a Poly point has been selected to be dragged
|
||||
# and SHIFT key is pressed...
|
||||
if cls.drag_hole == -1: # if no hole wase selected
|
||||
poly = cls.polys[cls.selected_drag]
|
||||
i, j = cls.screen_to_grid(mouseX, mouseY )
|
||||
poly.pts.insert(cls.drag_pt, (i, j, 0))
|
||||
else:
|
||||
poly = cls.polys[cls.selected_drag]
|
||||
hole = poly.holes[Poly.drag_hole]
|
||||
i, j = cls.screen_to_grid(mouseX, mouseY )
|
||||
hole.insert(cls.drag_pt, (i, j, 0))
|
||||
# Poly.selected_drag = -1 # No poly selected
|
||||
Poly.drag_hole = -1 # No hole selected
|
||||
Poly.drag_pt = -1 # No point selected
|
||||
|
||||
@classmethod
|
||||
def duplicate_selected(cls, off=1):
|
||||
if Poly.selected_drag >= 0:
|
||||
new_poly = deepcopy(cls.polys[cls.selected_drag])
|
||||
for i, pt in enumerate(new_poly.pts):
|
||||
new_poly.pts[i] = (pt[0] + off, pt[1] + off, pt[2])
|
||||
for h in new_poly.holes:
|
||||
for i, pt in enumerate(h):
|
||||
h[i] = (pt[0] + off, pt[1] + off, pt[2])
|
||||
cls.polys.append(new_poly)
|
||||
Plik binarny nie jest wyświetlany.
|
Po Szerokość: | Wysokość: | Rozmiar: 13 KiB |
|
|
@ -0,0 +1,86 @@
|
|||
# Alexandre B A Villares - https://abav.lugaralgum.com/sketch-a-day
|
||||
"""
|
||||
A minimal poly editor
|
||||
- Add points
|
||||
"""
|
||||
import pickle
|
||||
from poly import Poly
|
||||
# add_library('GifAnimation')
|
||||
# from gif_exporter import gif_export
|
||||
|
||||
|
||||
def setup():
|
||||
size(500, 500, P2D)
|
||||
|
||||
f = createFont("Fira Mono", 16)
|
||||
textFont(f)
|
||||
|
||||
CELL_SIZE = 15
|
||||
order = width // CELL_SIZE
|
||||
x_offset = y_offset = int(order // 2)
|
||||
Poly.setup_grid(CELL_SIZE, order, x_offset, y_offset)
|
||||
p1 = Poly([(0, 0, -1), (6, 0, 1), (6, 6, 1), (0, 6, 0)])
|
||||
Poly.polys.append(p1)
|
||||
p2 = Poly([(-1, -1, 0), (-6, -1, 0), (-6, -6, 0), (-1, -6, 0)],
|
||||
holes=[[(-2, -3, 0), (-3, -3, 1), (-2, -2, 0)]])
|
||||
Poly.polys.append(p2)
|
||||
|
||||
def draw():
|
||||
background(230)
|
||||
# grade
|
||||
Poly.draw_grid()
|
||||
# polígonos
|
||||
for p in Poly.polys:
|
||||
p.plot()
|
||||
|
||||
def mousePressed():
|
||||
Poly.mouse_pressed()
|
||||
|
||||
def mouseDragged():
|
||||
Poly.mouse_dragged()
|
||||
|
||||
def mouseReleased():
|
||||
Poly.mouse_released()
|
||||
|
||||
def keyPressed():
|
||||
if key == "=":
|
||||
Poly.selected_drag += 1
|
||||
if Poly.selected_drag >= len(Poly.polys):
|
||||
Poly.selected_drag = -1
|
||||
if key == "d":
|
||||
Poly.duplicate_selected()
|
||||
|
||||
if key == " " and Poly.selected_drag >= 0:
|
||||
p = Poly.polys[Poly.selected_drag]
|
||||
p.pts[:] = Poly.clockwise_sort(p.pts)
|
||||
for h in p.holes:
|
||||
h[:] = Poly.clockwise_sort(h)[::-1]
|
||||
# if key == "g":
|
||||
# gif_export(GifMaker, filename=SKETCH_NAME)
|
||||
if key == "p":
|
||||
saveFrame(SKETCH_NAME + ".png")
|
||||
if key == "t":
|
||||
Poly.text_on = not Poly.text_on
|
||||
|
||||
if key == "s":
|
||||
with open("data/project.data", "wb") as file_out:
|
||||
pickle.dump(Poly.polys, file_out)
|
||||
println("project saved")
|
||||
|
||||
if key == "r":
|
||||
with open("data/project.data", "rb") as file_in:
|
||||
Poly.polys = pickle.load(file_in)
|
||||
println("project loaded")
|
||||
|
||||
def settings():
|
||||
from os import path
|
||||
global SKETCH_NAME
|
||||
SKETCH_NAME = path.basename(sketchPath())
|
||||
OUTPUT = ".png"
|
||||
println(
|
||||
"""
|
||||

|
||||
|
||||
[{0}](https://github.com/villares/sketch-a-day/tree/master/2019/{0}) [[Py.Processing](https://villares.github.io/como-instalar-o-processing-modo-python/index-EN)]
|
||||
""".format(SKETCH_NAME, OUTPUT)
|
||||
)
|
||||
Ładowanie…
Reference in New Issue