kopia lustrzana https://github.com/villares/sketch-a-day
Update index.html
rodzic
beb2d0e795
commit
b12d975986
|
@ -1069,6 +1069,327 @@ popStyle = pop
|
|||
pushMatrix = push
|
||||
pushStyle = push
|
||||
|
||||
# PVector is a wrapper/helper class for p5.Vector objets
|
||||
# providing names similar to Processing Python or Java modes
|
||||
# but mostly keeping p5js functionality
|
||||
|
||||
from numbers import Number
|
||||
|
||||
class PVector:
|
||||
|
||||
def __init__(self, x=0, y=0, z=0):
|
||||
self.__vector = createVector(x, y, z)
|
||||
self.add = self.__instance_add__
|
||||
self.sub = self.__instance_sub__
|
||||
self.mult = self.__instance_mult__
|
||||
self.div = self.__instance_div__
|
||||
self.cross = self.__instance_cross__
|
||||
self.dist = self.__instance_dist__
|
||||
self.dot = self.__instance_dot__
|
||||
self.lerp = self.__instance_lerp__
|
||||
|
||||
@property
|
||||
def x(self):
|
||||
return self.__vector.x
|
||||
|
||||
@x.setter
|
||||
def x(self, x):
|
||||
self.__vector.x = x
|
||||
|
||||
@property
|
||||
def y(self):
|
||||
return self.__vector.y
|
||||
|
||||
@y.setter
|
||||
def y(self, y):
|
||||
self.__vector.y = y
|
||||
|
||||
@property
|
||||
def z(self):
|
||||
return self.__vector.z
|
||||
|
||||
@z.setter
|
||||
def z(self, z):
|
||||
self.__vector.z = z
|
||||
|
||||
def mag(self):
|
||||
return self.__vector.mag()
|
||||
|
||||
def magSq(self):
|
||||
return self.__vector.magSq()
|
||||
|
||||
def setMag(self, mag):
|
||||
self.__vector.setMag(mag)
|
||||
return self
|
||||
|
||||
def normalize(self):
|
||||
self.__vector.normalize()
|
||||
return self
|
||||
|
||||
def limit(self, max):
|
||||
self.__vector.limit(max)
|
||||
return self
|
||||
|
||||
def heading(self):
|
||||
return self.__vector.heading()
|
||||
|
||||
def rotate(self, angle):
|
||||
self.__vector.rotate(angle)
|
||||
return self
|
||||
|
||||
def __instance_add__(self, *args):
|
||||
if len(args) == 1:
|
||||
return PVector.add(self, args[0], self)
|
||||
else:
|
||||
return PVector.add(self, PVector(*args), self)
|
||||
|
||||
def __instance_sub__(self, *args):
|
||||
if len(args) == 1:
|
||||
return PVector.sub(self, args[0], self)
|
||||
else:
|
||||
return PVector.sub(self, PVector(*args), self)
|
||||
|
||||
def __instance_mult__(self, o):
|
||||
return PVector.mult(self, o, self)
|
||||
|
||||
def __instance_div__(self, f):
|
||||
return PVector.div(self, f, self)
|
||||
|
||||
def __instance_cross__(self, o):
|
||||
return PVector.cross(self, o, self)
|
||||
|
||||
def __instance_dist__(self, o):
|
||||
return PVector.dist(self, o)
|
||||
|
||||
def __instance_dot__(self, *args):
|
||||
if len(args) == 1:
|
||||
v = args[0]
|
||||
else:
|
||||
v = args
|
||||
return self.x * v[0] + self.y * v[1] + self.z * v[2]
|
||||
|
||||
def __instance_lerp__(self, *args):
|
||||
if len(args) == 2:
|
||||
return PVector.lerp(self, args[0], args[1], self)
|
||||
else:
|
||||
vx, vy, vz, f = args
|
||||
return PVector.lerp(self, PVector(vx, vy, vz), f, self)
|
||||
|
||||
def get(self):
|
||||
return PVector(self.x, self.y, self.z)
|
||||
|
||||
def copy(self):
|
||||
return PVector(self.x, self.y, self.z)
|
||||
|
||||
def __getitem__(self, k):
|
||||
return getattr(self, ('x', 'y', 'z')[k])
|
||||
|
||||
def __setitem__(self, k, v):
|
||||
setattr(self, ('x', 'y', 'z')[k], v)
|
||||
|
||||
def __copy__(self):
|
||||
return PVector(self.x, self.y, self.z)
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
return PVector(self.x, self.y, self.z)
|
||||
|
||||
def __repr__(self): # PROVISÓRIO
|
||||
return f'PVector({self.x}, {self.y}, {self.z})'
|
||||
|
||||
def set(self, *args):
|
||||
"""
|
||||
Sets the x, y, and z component of the vector using two or three separate
|
||||
variables, the data from a p5.Vector, or the values from a float array.
|
||||
"""
|
||||
self.__vector.set(*args)
|
||||
|
||||
@classmethod
|
||||
def add(cls, a, b, dest=None):
|
||||
if dest is None:
|
||||
return PVector(a.x + b[0], a.y + b[1], a.z + b[2])
|
||||
dest.__vector.set(a.x + b[0], a.y + b[1], a.z + b[2])
|
||||
return dest
|
||||
|
||||
@classmethod
|
||||
def sub(cls, a, b, dest=None):
|
||||
if dest is None:
|
||||
return PVector(a.x - b[0], a.y - b[1], a.z - b[2])
|
||||
dest.__vector.set(a.x - b[0], a.y - b[1], a.z - b[2])
|
||||
return dest
|
||||
|
||||
@classmethod
|
||||
def mult(cls, a, b, dest=None):
|
||||
if dest is None:
|
||||
return PVector(a.x * b, a.y * b, a.z * b)
|
||||
dest.__vector.set(a.x * b, a.y * b, a.z * b)
|
||||
return dest
|
||||
|
||||
@classmethod
|
||||
def div(cls, a, b, dest=None):
|
||||
if dest is None:
|
||||
return PVector(a.x / b, a.y / b, a.z / b)
|
||||
dest.__vector.set(a.x / b, a.y / b, a.z / b)
|
||||
return dest
|
||||
|
||||
@classmethod
|
||||
def dist(cls, a, b):
|
||||
return a.__vector.dist(b.__vector)
|
||||
|
||||
@classmethod
|
||||
def dot(cls, a, b):
|
||||
return a.__vector.dot(b.__vector)
|
||||
|
||||
def __add__(a, b):
|
||||
return PVector.add(a, b, None)
|
||||
|
||||
def __sub__(a, b):
|
||||
return PVector.sub(a, b, None)
|
||||
|
||||
def __isub__(a, b):
|
||||
a.sub(b)
|
||||
return a
|
||||
|
||||
def __iadd__(a, b):
|
||||
a.add(b)
|
||||
return a
|
||||
|
||||
def __mul__(a, b):
|
||||
if not isinstance(b, Number):
|
||||
raise TypeError(
|
||||
"The * operator can only be used to multiply a PVector by a number")
|
||||
return PVector.mult(a, float(b), None)
|
||||
|
||||
def __rmul__(a, b):
|
||||
if not isinstance(b, Number):
|
||||
raise TypeError(
|
||||
"The * operator can only be used to multiply a PVector by a number")
|
||||
return PVector.mult(a, float(b), None)
|
||||
|
||||
def __imul__(a, b):
|
||||
if not isinstance(b, Number):
|
||||
raise TypeError(
|
||||
"The *= operator can only be used to multiply a PVector by a number")
|
||||
a.__vector.mult(float(b))
|
||||
return a
|
||||
|
||||
def __truediv__(a, b):
|
||||
if not isinstance(b, Number):
|
||||
raise TypeError(
|
||||
"The * operator can only be used to multiply a PVector by a number")
|
||||
return PVector(a.x / float(b), a.y / float(b), a.z / float(b))
|
||||
|
||||
def __itruediv__(a, b):
|
||||
if not isinstance(b, Number):
|
||||
raise TypeError(
|
||||
"The /= operator can only be used to multiply a PVector by a number")
|
||||
a.__vector.set(a.x / float(b), a.y / float(b), a.z / float(b))
|
||||
return a
|
||||
|
||||
def __eq__(a, b):
|
||||
return a.x == b[0] and a.y == b[1] and a.z == b[2]
|
||||
|
||||
def __lt__(a, b):
|
||||
return a.magSq() < b.magSq()
|
||||
|
||||
def __le__(a, b):
|
||||
return a.magSq() <= b.magSq()
|
||||
|
||||
def __gt__(a, b):
|
||||
return a.magSq() > b.magSq()
|
||||
|
||||
def __ge__(a, b):
|
||||
return a.magSq() >= b.magSq()
|
||||
|
||||
# Problematic class methods, we would rather use p5.Vector when possible...
|
||||
|
||||
@classmethod
|
||||
def lerp(cls, a, b, f, dest=None):
|
||||
v = createVector(a.x, a.y, a.z)
|
||||
v.lerp(b.__vector, f)
|
||||
if dest is None:
|
||||
return PVector(v.x, v.y, v.z)
|
||||
dest.set(v.x, v.y, v.z)
|
||||
return dest
|
||||
|
||||
@classmethod
|
||||
def cross(cls, a, b, dest=None):
|
||||
x = a.y * b[2] - b[1] * a.z
|
||||
y = a.z * b[0] - b[2] * a.x
|
||||
z = a.x * b[1] - b[0] * a.y
|
||||
if dest is None:
|
||||
return PVector(x, y, z)
|
||||
dest.set(x, y, z)
|
||||
return dest
|
||||
|
||||
@classmethod
|
||||
def fromAngle(cls, angle, length=1):
|
||||
# https://github.com/processing/p5.js/blob/3f0b2f0fe575dc81c724474154f5b23a517b7233/src/math/p5.Vector.js
|
||||
return PVector(length * cos(angle), length * sin(angle), 0)
|
||||
|
||||
@classmethod
|
||||
def fromAngles(theta, phi, length=1):
|
||||
# https://github.com/processing/p5.js/blob/3f0b2f0fe575dc81c724474154f5b23a517b7233/src/math/p5.Vector.js
|
||||
cosPhi = cos(phi)
|
||||
sinPhi = sin(phi)
|
||||
cosTheta = cos(theta)
|
||||
sinTheta = sin(theta)
|
||||
return PVector(length * sinTheta * sinPhi,
|
||||
-length * cosTheta,
|
||||
length * sinTheta * cosPhi)
|
||||
|
||||
@classmethod
|
||||
def random2D(cls):
|
||||
return PVector.fromAngle(random(TWO_PI))
|
||||
|
||||
@classmethod
|
||||
def random3D(cls, dest=None):
|
||||
angle = random(TWO_PI)
|
||||
vz = random(2) - 1
|
||||
mult = sqrt(1 - vz * vz)
|
||||
vx = mult * cos(angle)
|
||||
vy = mult * sin(angle)
|
||||
if dest is None:
|
||||
return PVector(vx, vy, vz)
|
||||
dest.set(vx, vy, vz)
|
||||
return dest
|
||||
|
||||
@classmethod
|
||||
def angleBetween(cls, a, b):
|
||||
return acos(a.dot(b) / sqrt(a.magSq() * b.magSq()))
|
||||
|
||||
# Other harmless p5js methods
|
||||
|
||||
def equals(self, v):
|
||||
return self == v
|
||||
|
||||
def heading2D(self):
|
||||
return self.__vector.heading()
|
||||
|
||||
def reflect(self, *args):
|
||||
# Reflect the incoming vector about a normal to a line in 2D, or about
|
||||
# a normal to a plane in 3D This method acts on the vector directly
|
||||
r = self.__vector.reflect(*args)
|
||||
return r
|
||||
|
||||
def array(self):
|
||||
# Return a representation of this vector as a float array. This is only
|
||||
# for temporary use. If used in any w fashion, the contents should be
|
||||
# copied by using the p5.Vector.copy() method to copy into your own
|
||||
# array.
|
||||
return self.__vector.array()
|
||||
|
||||
def toString(self):
|
||||
# Returns a string representation of a vector v by calling String(v) or v.toString().
|
||||
# return self.__vector.toString() would be something like "p5.vector
|
||||
# Object […, …, …]"
|
||||
return str(self)
|
||||
|
||||
def rem(self, *args):
|
||||
# Gives remainder of a vector when it is divided by anw vector. See
|
||||
# examples for more context.
|
||||
self.__vector.rem(*args)
|
||||
return self
|
||||
|
||||
def pre_draw(p5_instance, draw_func):
|
||||
"""
|
||||
We need to run this before the actual draw to insert and update p5 env variables
|
||||
|
|
Ładowanie…
Reference in New Issue