kopia lustrzana https://github.com/villares/sketch-a-day
goToLoop
rodzic
b360e3c21a
commit
f219e7ab65
|
|
@ -50,7 +50,8 @@ def draw():
|
|||
rotateY(angle)
|
||||
angle += ANGLE_STEP
|
||||
|
||||
beta <= SEGS_LIMIT and addKnot()
|
||||
if beta <= SEGS_LIMIT:
|
||||
addKnot()
|
||||
beta += BETA_STEP
|
||||
|
||||
with beginShape():
|
||||
|
|
@ -61,7 +62,7 @@ def draw():
|
|||
|
||||
def mousePressed():
|
||||
global paused
|
||||
paused ^= True
|
||||
paused = not paused
|
||||
noLoop() if paused else loop()
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -47,28 +47,29 @@ def draw():
|
|||
global angle, beta
|
||||
|
||||
background(0)
|
||||
# translate(width>>1, height>>1)
|
||||
rect(20,20, 20,20)
|
||||
translate(width>>1, height>>1)
|
||||
rotateY(angle)
|
||||
angle += ANGLE_STEP
|
||||
|
||||
beta <= SEGS_LIMIT and addKnot()
|
||||
if beta <= SEGS_LIMIT:
|
||||
addKnot()
|
||||
beta += BETA_STEP
|
||||
|
||||
beginShape():
|
||||
beginShape()
|
||||
for k in knots:
|
||||
#stroke(frameCount % 100, 255, 255)
|
||||
stroke(k.c)
|
||||
vertex(k.v.x, k.v.y, k.v.z)
|
||||
vertex(k.v[0], k.v[1], k.v[2])
|
||||
endShape()
|
||||
|
||||
def mousePressed():
|
||||
global paused
|
||||
paused ^= True
|
||||
paused = not paused
|
||||
noLoop() if paused else loop()
|
||||
|
||||
|
||||
# def keyPressed(): mousePressed()
|
||||
|
||||
|
||||
def addKnot():
|
||||
r = MAG * (.8 + 1.6 * sin(6 * beta))
|
||||
theta = 2 * beta
|
||||
|
|
@ -81,18 +82,19 @@ def addKnot():
|
|||
|
||||
knot = Knot(x, y, z)
|
||||
knots.append(knot)
|
||||
print '%d: %s' % (len(knots), knot)
|
||||
# quebrado:
|
||||
#print('%d: %s' % (len(knots), knot))
|
||||
|
||||
|
||||
class Knot:
|
||||
def __init__(k, *vec):
|
||||
k.v = vec[0] if len(vec) is 1 else PVector(*vec)
|
||||
k.c = color(k.v.mag(), 255, 255)
|
||||
|
||||
|
||||
def __str__(k): return 'Vec: %s \tHSB: %d' % (k.v, k.c)
|
||||
|
||||
|
||||
def __init__(self, *vec):
|
||||
self.v = vec[0] if len(vec) else tuple(*vec)
|
||||
x, y, z = self.v
|
||||
mag = sqrt(x*x + y*y + z*z)
|
||||
self.c = color(mag, 255, 255)
|
||||
|
||||
def __str__(self):
|
||||
return 'Vec: %s \tHSB: %d' % (self.v, self.c)
|
||||
|
||||
# This is required by pyp5js to work
|
||||
start_p5(setup, draw)
|
||||
|
|
|
|||
Plik diff jest za duży
Load Diff
File diff suppressed because one or more lines are too long
|
|
@ -1,285 +0,0 @@
|
|||
# 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 (' ', ' ')
|
||||
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
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
// Transcrypt'ed from Python, 2019-05-06 13:38:07
|
||||
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 {CLOSE, DEGREES, HALF_PI, PI, QUARTER_PI, RADIANS, TAU, TWO_PI, _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, deviceMoved, deviceOrientation, deviceShaken, deviceTurned, directionalLight, disableFriendlyErrors, displayDensity, displayHeight, displayWidth, dist, doubleClicked, 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, keyPressed, keyReleased, keyTyped, 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, mouseClicked, mouseDragged, mouseIsPressed, mouseMoved, mouseReleased, mouseWheel, 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, touchEnded, touchMoved, touchStarted, touches, translate, triangle, trim, turnAxis, unchar, unhex, updatePixels, vertex, width, winMouseX, winMouseY, windowHeight, windowResized, windowWidth, year} from './pytop5js.js';
|
||||
var __name__ = '__main__';
|
||||
var __left0__ = tuple ([0.02, 0.01]);
|
||||
export var ANGLE_STEP = __left0__ [0];
|
||||
export var BETA_STEP = __left0__ [1];
|
||||
var __left0__ = tuple ([100.0, PI + BETA_STEP]);
|
||||
export var MAG = __left0__ [0];
|
||||
export var SEGS_LIMIT = __left0__ [1];
|
||||
export var PI_DOT_6 = PI * 0.6;
|
||||
var __left0__ = 0.0;
|
||||
export var angle = __left0__;
|
||||
export var beta = __left0__;
|
||||
export var paused = false;
|
||||
export var knots = list ([]);
|
||||
export var setup = function () {
|
||||
createCanvas (600, 600, 'webgl');
|
||||
smooth (8);
|
||||
colorMode ('hsb');
|
||||
noFill ();
|
||||
strokeWeight (8.0);
|
||||
};
|
||||
export var draw = function () {
|
||||
background (0);
|
||||
rect (20, 20, 20, 20);
|
||||
translate (width >> 1, height >> 1);
|
||||
rotateY (angle);
|
||||
angle += ANGLE_STEP;
|
||||
if (beta <= SEGS_LIMIT) {
|
||||
addKnot ();
|
||||
}
|
||||
beta += BETA_STEP;
|
||||
beginShape ();
|
||||
for (var k of knots) {
|
||||
stroke (k.c);
|
||||
vertex (k.v [0], k.v [1], k.v [2]);
|
||||
}
|
||||
endShape ();
|
||||
};
|
||||
export var mousePressed = function () {
|
||||
paused = !(paused);
|
||||
(paused ? noLoop () : loop ());
|
||||
};
|
||||
export var addKnot = function () {
|
||||
var r = MAG * (0.8 + 1.6 * sin (6 * beta));
|
||||
var theta = 2 * beta;
|
||||
var phi = PI_DOT_6 * sin (12 * beta);
|
||||
var rCosPhi = r * cos (phi);
|
||||
var x = rCosPhi * cos (theta);
|
||||
var y = rCosPhi * sin (theta);
|
||||
var z = r * sin (phi);
|
||||
var knot = Knot (x, y, z);
|
||||
knots.append (knot);
|
||||
};
|
||||
export var Knot = __class__ ('Knot', [object], {
|
||||
__module__: __name__,
|
||||
get __init__ () {return __get__ (this, function (self) {
|
||||
var vec = tuple ([].slice.apply (arguments).slice (1));
|
||||
self.v = (len (vec) ? vec [0] : tuple (...vec));
|
||||
var __left0__ = self.v;
|
||||
var x = __left0__ [0];
|
||||
var y = __left0__ [1];
|
||||
var z = __left0__ [2];
|
||||
var mag = sqrt ((x * x + y * y) + z * z);
|
||||
self.c = color (mag, 255, 255);
|
||||
});},
|
||||
get __str__ () {return __get__ (this, function (self) {
|
||||
return __mod__ ('Vec: %s \tHSB: %d', tuple ([self.v, self.c]));
|
||||
});}
|
||||
});
|
||||
start_p5 (setup, draw);
|
||||
|
||||
//# sourceMappingURL=sketch_190506b.map
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"version": 3,
|
||||
"file": "sketch_190506b.js",
|
||||
"sources": [
|
||||
"sketch_190506b.py"
|
||||
],
|
||||
"mappings": "AAAA;AAAA;AAAA;AAAA;AA4BA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAEA;AAAA;AAAA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AAGA;AAGA;AACA;AACA;AACA;AAAA;AAGA;AACA;AAAA;AAAA;AAGA;AACA;AAEA;AACA;AAAA;AACA;AAAA;AAEA;AAEA;AACA;AAAA;AAIA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAAA;AAKA;AAAA;AACA;AAAA;AACA;AACA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AAEA;AACA;AAAA;AAAA;AAGA;AAnGA"
|
||||
}
|
||||
Plik binarny nie jest wyświetlany.
|
|
@ -0,0 +1,100 @@
|
|||
from pytop5js import *
|
||||
|
||||
"""
|
||||
* 3D Knot (2017/Dec)
|
||||
* Daniel Shiffman
|
||||
* https://YouTu.be/r6YMKr1X0VA
|
||||
*
|
||||
* Mod GoToLoop (v1.0.3) (2018/Oct/16)
|
||||
* https://OpenProcessing.org/sketch/608725 (pjs)
|
||||
* https://OpenProcessing.org/sketch/608726 (p5js)
|
||||
*
|
||||
* https://Discourse.Processing.org/t/
|
||||
* vertex-loop-and-draw-along-a-vertex-path/4545/4
|
||||
"""
|
||||
|
||||
"""
|
||||
* http://PaulBourke.net/geometry/knots/
|
||||
* Knot 4 (1992/Oct):
|
||||
*
|
||||
* r(beta) = 0.8 + 1.6 * sin(6 * beta)
|
||||
* theta(beta) = 2 * beta
|
||||
* phi(beta) = 0.6 * pi * sin(12 * beta)
|
||||
*
|
||||
* x = r * cos(phi) * cos(theta)
|
||||
* y = r * cos(phi) * sin(theta)
|
||||
* z = r * sin(phi)
|
||||
"""
|
||||
|
||||
ANGLE_STEP, BETA_STEP = .02, .01
|
||||
MAG, SEGS_LIMIT = 100.0, PI + BETA_STEP
|
||||
PI_DOT_6 = PI * .6
|
||||
|
||||
angle = beta = 0.0
|
||||
paused = False
|
||||
|
||||
knots = []
|
||||
|
||||
def setup():
|
||||
createCanvas(600, 600, 'webgl')
|
||||
smooth(8)
|
||||
colorMode('hsb')
|
||||
noFill()
|
||||
strokeWeight(8.0)
|
||||
|
||||
|
||||
def draw():
|
||||
global angle, beta
|
||||
|
||||
background(0)
|
||||
rect(20,20, 20,20)
|
||||
translate(width>>1, height>>1)
|
||||
rotateY(angle)
|
||||
angle += ANGLE_STEP
|
||||
|
||||
if beta <= SEGS_LIMIT:
|
||||
addKnot()
|
||||
beta += BETA_STEP
|
||||
|
||||
beginShape()
|
||||
for k in knots:
|
||||
#stroke(frameCount % 100, 255, 255)
|
||||
stroke(k.c)
|
||||
vertex(k.v[0], k.v[1], k.v[2])
|
||||
endShape()
|
||||
|
||||
def mousePressed():
|
||||
global paused
|
||||
paused = not paused
|
||||
noLoop() if paused else loop()
|
||||
|
||||
# def keyPressed(): mousePressed()
|
||||
|
||||
def addKnot():
|
||||
r = MAG * (.8 + 1.6 * sin(6 * beta))
|
||||
theta = 2 * beta
|
||||
phi = PI_DOT_6 * sin(12 * beta)
|
||||
rCosPhi = r * cos(phi)
|
||||
|
||||
x = rCosPhi * cos(theta)
|
||||
y = rCosPhi * sin(theta)
|
||||
z = r * sin(phi)
|
||||
|
||||
knot = Knot(x, y, z)
|
||||
knots.append(knot)
|
||||
# quebrado:
|
||||
#print('%d: %s' % (len(knots), knot))
|
||||
|
||||
|
||||
class Knot:
|
||||
def __init__(self, *vec):
|
||||
self.v = vec[0] if len(vec) else tuple(*vec)
|
||||
x, y, z = self.v
|
||||
mag = sqrt(x*x + y*y + z*z)
|
||||
self.c = color(mag, 255, 255)
|
||||
|
||||
def __str__(self):
|
||||
return 'Vec: %s \tHSB: %d' % (self.v, self.c)
|
||||
|
||||
# This is required by pyp5js to work
|
||||
start_p5(setup, draw)
|
||||
Ładowanie…
Reference in New Issue