kopia lustrzana https://github.com/villares/sketch-a-day
				
				
				
			0601
							rodzic
							
								
									98c604db94
								
							
						
					
					
						commit
						6de3088f64
					
				| 
						 | 
				
			
			@ -53,11 +53,11 @@ def draw():
 | 
			
		|||
                popMatrix()
 | 
			
		||||
                i += 1
 | 
			
		||||
    if i < len(line_combos):
 | 
			
		||||
        gif_export(GifMaker, SKETCH_NAME)
 | 
			
		||||
        # gif_export(GifMaker, SKETCH_NAME)
 | 
			
		||||
        # gif_export(GifMaker, SKETCH_NAME[:-1] + "b") # B option
 | 
			
		||||
        position += H * W
 | 
			
		||||
    else:
 | 
			
		||||
        gif_export(GifMaker, finish=True)
 | 
			
		||||
        # gif_export(GifMaker, finish=True)
 | 
			
		||||
 | 
			
		||||
def draw_combo(n):
 | 
			
		||||
    colorMode(RGB)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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=1000,            # 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,128 @@
 | 
			
		|||
def poly(p_list, closed=True):
 | 
			
		||||
    beginShape()
 | 
			
		||||
    for p in p_list:
 | 
			
		||||
        if len(p) == 2 or p[2] == 0:
 | 
			
		||||
            vertex(p[0], p[1])
 | 
			
		||||
        else:
 | 
			
		||||
            vertex(*p)
 | 
			
		||||
    if closed:
 | 
			
		||||
        endShape(CLOSE)
 | 
			
		||||
    else:
 | 
			
		||||
        endShape()
 | 
			
		||||
 | 
			
		||||
def 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)
 | 
			
		||||
 | 
			
		||||
    if not open_poly:
 | 
			
		||||
        with pushStyle():
 | 
			
		||||
            noStroke()
 | 
			
		||||
            beginShape()
 | 
			
		||||
            for p0, p1 in zip(p_list, [p_list[-1]] + p_list[:-1]):
 | 
			
		||||
                m = (PVector(p0[0], p0[1]) + PVector(p1[0], p1[1])) / 2
 | 
			
		||||
                vertex(m[0], m[1])
 | 
			
		||||
            endShape(CLOSE)
 | 
			
		||||
        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 = (PVector(p0[0], p0[1]) + PVector(p1[0], p1[1])) / 2
 | 
			
		||||
            m2 = (PVector(p2[0], p2[1]) + PVector(p1[0], p1[1])) / 2
 | 
			
		||||
            roundedCorner(p1, m1, m2, r)
 | 
			
		||||
    else:
 | 
			
		||||
        for p0, p1, p2, r in zip(p_list[:-1],
 | 
			
		||||
                                 [p_list[-1]] + p_list[:-2],
 | 
			
		||||
                                 [p_list[-2]] + [p_list[-1]] + p_list[:-3],
 | 
			
		||||
                                 [r_list[-1]] + r_list[:-2]
 | 
			
		||||
                                 ):
 | 
			
		||||
            m1 = (PVector(p0[0], p0[1]) + PVector(p1[0], p1[1])) / 2
 | 
			
		||||
            m2 = (PVector(p2[0], p2[1]) + PVector(p1[0], p1[1])) / 2
 | 
			
		||||
            roundedCorner(p1, m1, m2, r)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def roundedCorner(pc, p1, p2, 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
 | 
			
		||||
    if sweepAngle < 0:
 | 
			
		||||
        startAngle, endAngle = endAngle, startAngle
 | 
			
		||||
        sweepAngle = -sweepAngle
 | 
			
		||||
 | 
			
		||||
    if sweepAngle > PI:
 | 
			
		||||
        startAngle, endAngle = endAngle, startAngle
 | 
			
		||||
        sweepAngle = TWO_PI - sweepAngle
 | 
			
		||||
 | 
			
		||||
    with pushStyle():
 | 
			
		||||
        noStroke()
 | 
			
		||||
        beginShape()
 | 
			
		||||
        vertex(p1[0], p1[1])
 | 
			
		||||
        vertex(p1Cross[0], p1Cross[1])
 | 
			
		||||
        vertex(p2Cross[0], p2Cross[1])
 | 
			
		||||
        vertex(p2[0], p2[1])
 | 
			
		||||
        endShape(CLOSE)
 | 
			
		||||
 | 
			
		||||
    line(p1[0], p1[1], p1Cross[0], p1Cross[1])
 | 
			
		||||
    line(p2[0], p2[1], p2Cross[0], p2Cross[1])
 | 
			
		||||
    arc(circlePoint[0], circlePoint[1], 2 * max_r, 2 * max_r,
 | 
			
		||||
        startAngle, startAngle + sweepAngle)
 | 
			
		||||
										
											Plik binarny nie jest wyświetlany.
										
									
								
							| 
		 Po Szerokość: | Wysokość: | Rozmiar: 124 KiB  | 
| 
						 | 
				
			
			@ -0,0 +1,136 @@
 | 
			
		|||
# Alexandre B A Villares - https://abav.lugaralgum.com/sketch-a-day
 | 
			
		||||
# More explorations of lines in grids
 | 
			
		||||
 | 
			
		||||
from random import shuffle
 | 
			
		||||
from itertools import product, combinations, permutations, combinations_with_replacement
 | 
			
		||||
from gif_exporter import gif_export
 | 
			
		||||
add_library('GifAnimation')
 | 
			
		||||
from polys import *
 | 
			
		||||
 | 
			
		||||
space, border = 20, 20
 | 
			
		||||
position = 0  # initial position
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def setup():
 | 
			
		||||
    global line_combos, W, H, position, num
 | 
			
		||||
    size(800, 660)
 | 
			
		||||
    frameRate(1)
 | 
			
		||||
    rectMode(CENTER)
 | 
			
		||||
    strokeWeight(1.5)
 | 
			
		||||
    grid = product(range(-1, 2), repeat=2)  # 2X2
 | 
			
		||||
    # all line permutations on a grid
 | 
			
		||||
    possible_lines = list(combinations(grid, 3))
 | 
			
		||||
    # allow only some lines
 | 
			
		||||
    # possible_lines = []
 | 
			
		||||
    # for l in lines:
 | 
			
		||||
    #     (x0, y0), (x1, y1) = l[0], l[1]
 | 
			
		||||
    # if dist(x0, y0, x1, y1) < 2:  # rule defined here...
 | 
			
		||||
    #         possible_lines.append(l)
 | 
			
		||||
    num_possible_lines = len(possible_lines)
 | 
			
		||||
    println("Number of possible lines: {}".format(num_possible_lines))
 | 
			
		||||
    # main stuff
 | 
			
		||||
    line_combos = list(combinations(possible_lines, 2))
 | 
			
		||||
    # shuffle(line_combos) # ucomment to shuffle!
 | 
			
		||||
    num = len(line_combos)
 | 
			
		||||
    println("Number of permutations: {}".format(num))
 | 
			
		||||
    W = (width - border * 2) // space
 | 
			
		||||
    H = (height - border * 2) // space
 | 
			
		||||
    println("Cols: {} Rows: {} Visible grid: {}".format(W, H, W * H))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def draw():
 | 
			
		||||
    global position
 | 
			
		||||
    background(240)
 | 
			
		||||
    i = position
 | 
			
		||||
    for y in range(H):
 | 
			
		||||
        for x in range(W):
 | 
			
		||||
            if i < len(line_combos):
 | 
			
		||||
                pushMatrix()
 | 
			
		||||
                translate(border / 2 + space + space * x,
 | 
			
		||||
                          border / 2 + space + space * y)
 | 
			
		||||
                # translate(border + space + space * x,
 | 
			
		||||
                #           border + space + space * y)
 | 
			
		||||
                draw_combo(i)
 | 
			
		||||
                popMatrix()
 | 
			
		||||
                i += 1
 | 
			
		||||
    if i < len(line_combos):
 | 
			
		||||
        # gif_export(GifMaker, SKETCH_NAME)
 | 
			
		||||
        # gif_export(GifMaker, SKETCH_NAME[:-1] + "b") # B option
 | 
			
		||||
        position += H * W
 | 
			
		||||
    else:
 | 
			
		||||
        gif_export(GifMaker, finish=True)
 | 
			
		||||
 | 
			
		||||
def draw_combo(n):
 | 
			
		||||
    colorMode(RGB)
 | 
			
		||||
    siz = space / 2
 | 
			
		||||
    for i, sl in enumerate(line_combos[n]):
 | 
			
		||||
        colorMode(HSB)
 | 
			
		||||
        fill(i * 128, 128, 128, 100)
 | 
			
		||||
        (x0, y0), (x1, y1), (x2, y2) = sl[0], sl[1], sl[2]
 | 
			
		||||
        # noStroke()
 | 
			
		||||
        poly(((x0 * siz, y0 * siz),
 | 
			
		||||
             (x1 * siz, y1 * siz),
 | 
			
		||||
             (x2 * siz, y2 * siz)))
 | 
			
		||||
 | 
			
		||||
def keyPressed():
 | 
			
		||||
    global W, H
 | 
			
		||||
    if key == "s":
 | 
			
		||||
        saveFrame("####.png")
 | 
			
		||||
 | 
			
		||||
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/{2}/{0}) [[Py.Processing](https://villares.github.io/como-instalar-o-processing-modo-python/index-EN)]
 | 
			
		||||
""".format(SKETCH_NAME, OUTPUT, year())
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
def var_bar(p1x, p1y, p2x, p2y, r1, r2=None):
 | 
			
		||||
    """
 | 
			
		||||
    Tangent/tangent shape on 2 circles of arbitrary radius
 | 
			
		||||
    """
 | 
			
		||||
    if r2 is None:
 | 
			
		||||
        r2 = r1
 | 
			
		||||
    #line(p1x, p1y, p2x, p2y)
 | 
			
		||||
    d = dist(p1x, p1y, p2x, p2y)
 | 
			
		||||
    ri = r1 - r2
 | 
			
		||||
    if d > abs(ri):
 | 
			
		||||
        rid = (r1 - r2) / d
 | 
			
		||||
        if rid > 1:
 | 
			
		||||
            rid = 1
 | 
			
		||||
        if rid < -1:
 | 
			
		||||
            rid = -1
 | 
			
		||||
        beta = asin(rid) + HALF_PI
 | 
			
		||||
        with pushMatrix():
 | 
			
		||||
            translate(p1x, p1y)
 | 
			
		||||
            angle = atan2(p1x - p2x, p2y - p1y)
 | 
			
		||||
            rotate(angle + HALF_PI)
 | 
			
		||||
            x1 = cos(beta) * r1
 | 
			
		||||
            y1 = sin(beta) * r1
 | 
			
		||||
            x2 = cos(beta) * r2
 | 
			
		||||
            y2 = sin(beta) * r2
 | 
			
		||||
            #print((d, beta, ri, x1, y1, x2, y2))
 | 
			
		||||
            with pushStyle():
 | 
			
		||||
                noStroke()
 | 
			
		||||
                beginShape()
 | 
			
		||||
                vertex(-x1, -y1)
 | 
			
		||||
                vertex(d - x2, -y2)
 | 
			
		||||
                vertex(d, 0)
 | 
			
		||||
                vertex(d - x2, +y2)
 | 
			
		||||
                vertex(-x1, +y1)
 | 
			
		||||
                vertex(0, 0)
 | 
			
		||||
                endShape(CLOSE)
 | 
			
		||||
            line(-x1, -y1, d - x2, -y2)
 | 
			
		||||
            line(-x1, +y1, d - x2, +y2)
 | 
			
		||||
            arc(0, 0, r1 * 2, r1 * 2,
 | 
			
		||||
                -beta - PI, beta - PI)
 | 
			
		||||
            arc(d, 0, r2 * 2, r2 * 2,
 | 
			
		||||
                beta - PI, PI - beta)
 | 
			
		||||
    else:
 | 
			
		||||
        ellipse(p1x, p1y, r1 * 2, r1 * 2)
 | 
			
		||||
        ellipse(p2x, p2y, r2 * 2, r2 * 2)
 | 
			
		||||
		Ładowanie…
	
		Reference in New Issue