Replies: 3 comments 7 replies
-
Unfortunately there is no Vector2 class with methods you can override. It’s a ctype struct, not a class. |
Beta Was this translation helpful? Give feedback.
5 replies
-
I believe I’ve wrapped all the Vector2 functions. Hopefully, this helps someone. Personally, I find it quite convenient because the code looks more Pythonic and involves less boilerplate. If you find any problem let me know. from pyray import *
class Vec2:
def __init__(self, x, y) -> None:
self.x = x
self.y = y
@property
def vector2(self):
"""
Cast Vec2 to Vector2.
"""
return Vector2(self.x, self.y)
@staticmethod
def to_Vec2(v: Vector2):
"""
Cast Vector2 to Vec2.
"""
return Vec2(v.x, v.y)
def __repr__(self) -> str:
return f"{self.x}, {self.y}"
def __eq__(self, other):
if isinstance(other, Vec2):
return self.x == other.x and self.y == other.y
return False
def __add__(self, other):
if isinstance(other, Vec2):
return Vec2(self.x + other.x, self.y + other.y)
return Vec2(self.x + other, self.y + other)
def __iadd__(self, other):
if isinstance(other, Vec2):
self.x += other.x
self.y += other.y
else:
res = vector2_add_value(self, other)
self.x = res.x
self.y = res.y
return self
def __radd__(self, other):
return self + other
def __sub__(self, other):
if isinstance(other, Vec2):
return Vec2(self.x - other.x, self.y - other.y)
return Vec2(self.x - other, self.y - other)
def __isub__(self, other):
if isinstance(other, Vec2):
self.x -= other.x
self.y -= other.y
else:
self.x -= other
self.y -= other
return self
def __rsub__(self, other):
return Vec2(other - self.x, other - self.y)
def __mul__(self, other):
if isinstance(other, Vec2):
res = vector2_multiply(self.vector2, other.vector2)
return self.to_Vec2(res)
return Vec2(self.x * other, self.y * other)
def __imul__(self, other):
if isinstance(other, Vec2):
res = vector2_multiply(self.vector2, other.vector2)
else:
res = vector2_scale(self.vector2, other)
self.x = res.x
self.y = res.y
return self
def __truediv__(self, other):
if isinstance(other, Vec2):
res = vector_2divide(self.vector2, other.vector2)
return self.to_Vec2(res)
return Vec2(self.x / other, self.y / other)
def __itruediv__(self, other):
if isinstance(other, Vec2):
res = vector_2divide(self.vector2, other.vector2)
else:
res = vector2_scale(self.vector2, 1/other)
self.x = res.x
self.y = res.y
return self
def __neg__(self):
return Vec2(-self.x, -self.y)
def __pos__(self):
return Vec2(self.x, self.y)
def __pow__(self, exponent):
return Vec2(self.x ** exponent, self.y ** exponent)
# PyRay mapped vector2 functions
def angle(self, other):
return vector2_angle(self.vector2, other.vector2)
def clamp(self, min_vec2, max_vec2):
res = vector2_clamp(self.vector2, min_vec2.vector2, max_vec2.vector2)
return self.to_Vec2(res)
def clamp_value(self, min_val: float, max_val: float):
res = vector2_clamp_value(self.vector2, min_val, max_val)
return self.to_Vec2(res)
def distance(self, v):
return vector_2distance(self.vector2, v.vector2)
def distance_sqr(self, v) -> float:
return vector_2distance_sqr(self.vector2, v.vector2)
def dot_product(self, v) -> float:
return vector_2dot_product(self.vector2, v.vector2)
def invert(self):
res = vector2_invert(self.vector2)
return self.to_Vec2(res)
def length(self):
return vector2_length(self.vector2)
def length_sqr(self) -> float:
return vector2_length_sqr(self.vector2)
def lerp(self, v, amount: float):
res = vector2_lerp(self.vector2, v.vector2, amount)
return self.to_Vec2(res)
def move_towards(self, target_v, max_distance: float):
res = vector2_move_towards(self.vector2, target_v.vector2, max_distance)
return self.to_Vec2(res)
def negate(self):
res = vector2_negate(self.vector2)
return self.to_Vec2(res)
def normalize(self):
res = vector2_normalize(self.vector2)
return self.to_Vec2(res)
def reflect(self, normal_v):
res = vector2_reflect(self.vector2, normal_v.vector2)
return self.to_Vec2(res)
def rotate(self, angle: float):
res = vector2_rotate(self.vector2, angle)
return self.to_Vec2(res)
def transform(self, mat: Matrix):
res = vector2_transform(self.vector2, mat)
return self.to_Vec2(res)
@staticmethod
def line_angle(start_v, end_v) -> float:
return vector2_line_angle(start_v.vector2, end_v.vector2)
@staticmethod
def one():
return Vec2(1, 1)
@staticmethod
def zero():
return Vec2(0, 0)
if __name__ == "__main__":
# Arithmetic ops
v1 = Vec2(5, 5)
v2 = Vec2(10, 10)
print(v1 + v2) # 15, 15
print(v1 - v2) # -5, -5
print(v1 * v2) # 50.0, 50.0
print(v1 / v2) # 0.5, 0.5
print(v1 * 2) # 10, 10
print(v2 / 2) # 5.0, 5.0
v1+=v2
print(v1) #15, 15
v2-=v1
print(v2) #-5, -5
v1/=-v2
print(v1) #3.0, 3.0
v2*=v1
print(v2) #-15.0, -15.0
v3 = Vec2(3, 5)
print(v3 ** 2) #9, 25
v1 = Vec2.one()
print(v1)
v0 = Vec2.zero()
print(v0)
# Vector2 pyry methods
v1 = Vec2(3, 4)
v2 = Vec2(1, 2)
v_min = Vec2(0, 0)
v_max = Vec2(5, 5)
print("Angle:", v1.angle(v2))
print("Clamp:", v1.clamp(v_min, v_max))
print("Clamp value:", v1.clamp_value(1.5, 3.5))
print("Distance:", v1.distance(v2))
print("Distance Sqr:", v1.distance_sqr(v2))
print("Dot Product:", v1.dot_product(v2))
print("Invert:", v1.invert())
print("Length:", v1.length())
print("Length Sqr:", v1.length_sqr())
print("Lerp:", v1.lerp(v2, 0.5))
print("Line Angle:", Vec2.line_angle(v1, v2))
print("Move Towards:", v1.move_towards(v2, 0.5))
print("Negate:", v1.negate())
print("Normalize:", v1.normalize())
print("Reflect:", v1.reflect(v2))
print("Rotate:", v1.rotate(45))
# I don't know why this not work
# mat = Matrix2x2(1, 0, 0, 1)
# print("Transform:", v1.transform(mat))
|
Beta Was this translation helpful? Give feedback.
2 replies
-
Here is the modified version using list as suggested, thanks @electronstudio for your time. from pyray import *
class Vec2(list):
def __init__(self, x, y):
super(Vec2, self).__init__([x, y])
@property
def x(self):
return self[0]
@x.setter
def x(self, value):
self[0]= value
@property
def y(self):
return self[1]
@y.setter
def y(self, value):
self[1]= value
@staticmethod
def to_Vec2(v: Vector2):
"""
Cast Vector2 to Vec2.
"""
return Vec2(v.x, v.y)
def __repr__(self) -> str:
return f"{self.x}, {self.y}"
def __eq__(self, other):
if isinstance(other, Vec2):
return self.x == other.x and self.y == other.y
return False
def __add__(self, other):
if isinstance(other, Vec2):
return Vec2(self.x + other.x, self.y + other.y)
return Vec2(self.x + other, self.y + other)
def __iadd__(self, other):
if isinstance(other, Vec2):
self.x += other.x
self.y += other.y
else:
res = vector2_add_value(self, other)
self.x = res.x
self.y = res.y
return self
def __radd__(self, other):
return self + other
def __sub__(self, other):
if isinstance(other, Vec2):
return Vec2(self.x - other.x, self.y - other.y)
return Vec2(self.x - other, self.y - other)
def __isub__(self, other):
if isinstance(other, Vec2):
self.x -= other.x
self.y -= other.y
else:
self.x -= other
self.y -= other
return self
def __rsub__(self, other):
return Vec2(other - self.x, other - self.y)
def __mul__(self, other):
if isinstance(other, Vec2):
res = vector2_multiply(self, other)
return self.to_Vec2(res)
return Vec2(self.x * other, self.y * other)
def __imul__(self, other):
if isinstance(other, Vec2):
res = vector2_multiply(self, other)
else:
res = vector2_scale(self, other)
self.x = res.x
self.y = res.y
return self
def __truediv__(self, other):
if isinstance(other, Vec2):
res = vector_2divide(self, other)
return self.to_Vec2(res)
return Vec2(self.x / other, self.y / other)
def __itruediv__(self, other):
if isinstance(other, Vec2):
res = vector_2divide(self, other)
else:
res = vector2_scale(self, 1/other)
self.x = res.x
self.y = res.y
return self
def __neg__(self):
return Vec2(-self.x, -self.y)
def __pos__(self):
return Vec2(self.x, self.y)
def __pow__(self, exponent):
return Vec2(self.x ** exponent, self.y ** exponent)
# PyRay mapped vector2 functions
def angle(self, vec2):
return vector2_angle(self, vec2)
def clamp(self, min_vec2, max_vec2):
res = vector2_clamp(self, min_vec2, max_vec2)
return self.to_Vec2(res)
def clamp_value(self, min_val: float, max_val: float):
res = vector2_clamp_value(self, min_val, max_val)
return self.to_Vec2(res)
def distance(self, vec2):
return vector_2distance(self, vec2)
def distance_sqr(self, vec2) -> float:
return vector_2distance_sqr(self, vec2)
def dot_product(self, vec2) -> float:
return vector_2dot_product(self, vec2)
def invert(self):
res = vector2_invert(self)
return self.to_Vec2(res)
def length(self):
return vector2_length(self)
def length_sqr(self) -> float:
return vector2_length_sqr(self)
def lerp(self, vec2, amount: float):
res = vector2_lerp(self, vec2, amount)
return self.to_Vec2(res)
def move_towards(self, target_vec2, max_distance: float):
res = vector2_move_towards(self, target_vec2, max_distance)
return self.to_Vec2(res)
def negate(self):
res = vector2_negate(self)
return self.to_Vec2(res)
def normalize(self):
res = vector2_normalize(self)
return self.to_Vec2(res)
def reflect(self, normal_vec2):
res = vector2_reflect(self, normal_vec2)
return self.to_Vec2(res)
def rotate(self, angle: float):
res = vector2_rotate(self, angle)
return self.to_Vec2(res)
def transform(self, mat: Matrix):
res = vector2_transform(self, mat)
return self.to_Vec2(res)
@staticmethod
def line_angle(start_vec2, end_vec2) -> float:
return vector2_line_angle(start_vec2, end_vec2)
@staticmethod
def one():
return Vec2(1, 1)
@staticmethod
def zero():
return Vec2(0, 0)
if __name__ == "__main__":
# Arithmetic ops
v1 = Vec2(5, 5)
v2 = Vec2(10, 10)
print(v1 + v2) # 15, 15
print(v1 - v2) # -5, -5
print(v1 * v2) # 50.0, 50.0
print(v1 / v2) # 0.5, 0.5
print(v1 * 2) # 10, 10
print(v2 / 2) # 5.0, 5.0
v1+=v2
print(v1) #15, 15
v2-=v1
print(v2) #-5, -5
v1/=-v2
print(v1) #3.0, 3.0
v2*=v1
print(v2) #-15.0, -15.0
v3 = Vec2(3, 5)
print(v3 ** 2) #9, 25
v1 = Vec2.one()
print(v1)
v0 = Vec2.zero()
print(v0)
# Vector2 pyray methods
v1 = Vec2(3, 4)
v2 = Vec2(1, 2)
v_min = Vec2(0, 0)
v_max = Vec2(5, 5)
print("Angle:", v1.angle(v2))
print("Clamp:", v1.clamp(v_min, v_max))
print("Clamp value:", v1.clamp_value(1.5, 3.5))
print("Distance:", v1.distance(v2))
print("Distance Sqr:", v1.distance_sqr(v2))
print("Dot Product:", v1.dot_product(v2))
print("Invert:", v1.invert())
print("Length:", v1.length())
print("Length Sqr:", v1.length_sqr())
print("Lerp:", v1.lerp(v2, 0.5))
print("Line Angle:", Vec2.line_angle(v1, v2))
print("Move Towards:", v1.move_towards(v2, 0.5))
print("Negate:", v1.negate())
print("Normalize:", v1.normalize())
print("Reflect:", v1.reflect(v2))
print("Rotate:", v1.rotate(45))
# I don't know why this not work
# mat = Matrix2x2(1, 0, 0, 1)
# print("Transform:", v1.transform(mat))
|
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Hello everyone,
I'd like to propose adding arithmetic functionality between vector classes (such as Vector2, Vector3, etc.) in pyray, utilizing Python's built-in arithmetic operators (+, -, *, /, etc.). This would make use of python advantages.
Why is this useful?
Being able to directly perform arithmetic operations between vectors would not only improve code readability but also make it easier to work with common tasks in graphics and physics, where these operations are frequently used.
Allowing direct addition, subtraction, multiplication, and division between vectors would align pyray with the expected behavior of other Python objects, which already support operator overloading (e.g., list, tuple).
Usage examples
Vector addition:
Instead of doing something like this:
We could simply do:
Vector subtraction:
Scalar multiplication:
Scalar division:
Advantages
Readability: Vector operations become clearer and more concise, making the code easier to understand.
Consistency: It aligns with what developers expect when working with overloaded operators in other Python libraries.
Efficiency: By allowing direct operations, we avoid repetitive code.
Possible Implementation
The implementation could be done by overriding the arithmetic methods such as add, sub, mul, and truediv in the vector classes (Vector2, Vector3, etc.). This would provide a clean and user-friendly solution.
For example, for vector addition, we could have something like:
What do you think about this idea?
Beta Was this translation helpful? Give feedback.
All reactions