From 5a78eef35af41813e16b234debe01ce098e849ec Mon Sep 17 00:00:00 2001 From: VeriTas-arch <145042207+VeriTas-arch@users.noreply.github.com> Date: Wed, 6 Nov 2024 01:36:15 +0800 Subject: [PATCH 1/5] improve docs of `vec2d.py` by unifying doc styles --- pymunk/vec2d.py | 93 +++++++++++++++++++++++++------------------------ 1 file changed, 47 insertions(+), 46 deletions(-) diff --git a/pymunk/vec2d.py b/pymunk/vec2d.py index df6a00e7..e7266057 100644 --- a/pymunk/vec2d.py +++ b/pymunk/vec2d.py @@ -73,11 +73,11 @@ def __repr__(self) -> str: # Addition def __add__(self, other: Tuple[float, float]) -> "Vec2d": # type: ignore[override] - """Add a Vec2d with another Vec2d or Tuple of size 2 + """Add a Vec2d with another Vec2d or Tuple of size 2. - >>> Vec2d(3,4) + Vec2d(1,2) + >>> Vec2d(3, 4) + Vec2d(1, 2) Vec2d(4, 6) - >>> Vec2d(3,4) + (1,2) + >>> Vec2d(3, 4) + (1, 2) Vec2d(4, 6) """ assert ( @@ -87,28 +87,28 @@ def __add__(self, other: Tuple[float, float]) -> "Vec2d": # type: ignore[overri return Vec2d(self.x + other[0], self.y + other[1]) def __radd__(self, other: Tuple[float, float]) -> "Vec2d": - """Add a Tuple of size 2 with a Vec2d + """Add a Tuple of size 2 with a Vec2d. - >>> (1,2) + Vec2d(3,4) + >>> (1, 2) + Vec2d(3, 4) Vec2d(4, 6) """ return self.__add__(other) # Subtraction def __sub__(self, other: Tuple[float, float]) -> "Vec2d": - """Subtract a Vec2d with another Vec2d or Tuple of size 2 + """Subtract a Vec2d with another Vec2d or Tuple of size 2. - >>> Vec2d(3,4) - Vec2d(1,2) + >>> Vec2d(3, 4) - Vec2d(1, 2) Vec2d(2, 2) - >>> Vec2d(3,4) - (1,2) + >>> Vec2d(3, 4) - (1, 2) Vec2d(2, 2) """ return Vec2d(self.x - other[0], self.y - other[1]) def __rsub__(self, other: Tuple[float, float]) -> "Vec2d": - """Subtract a Tuple of size 2 with a Vec2d + """Subtract a Tuple of size 2 with a Vec2d. - >>> (1,2) - Vec2d(3,4) + >>> (1, 2) - Vec2d(3, 4) Vec2d(-2, -2) """ assert ( @@ -118,36 +118,36 @@ def __rsub__(self, other: Tuple[float, float]) -> "Vec2d": # Multiplication def __mul__(self, other: float) -> "Vec2d": # type: ignore[override] - """Multiply with a float + """Multiply a Vec2d with a float. - >>> Vec2d(3,6) * 2.5 + >>> Vec2d(3, 6) * 2.5 Vec2d(7.5, 15.0) """ assert isinstance(other, numbers.Real) return Vec2d(self.x * other, self.y * other) def __rmul__(self, other: float) -> "Vec2d": # type: ignore[override] - """Multiply a float with a Vec2d + """Multiply a float with a Vec2d. - >>> 2.5 * Vec2d(3,6) + >>> 2.5 * Vec2d(3, 6) Vec2d(7.5, 15.0) """ return self.__mul__(other) # Division def __floordiv__(self, other: float) -> "Vec2d": - """Floor division by a float (also known as integer division) + """Floor division by a float (also known as integer division). - >>> Vec2d(3,6) // 2.0 + >>> Vec2d(3, 6) // 2.0 Vec2d(1.0, 3.0) """ assert isinstance(other, numbers.Real) return Vec2d(self.x // other, self.y // other) def __truediv__(self, other: float) -> "Vec2d": - """Division by a float + """Division by a float. - >>> Vec2d(3,6) / 2.0 + >>> Vec2d(3, 6) / 2.0 Vec2d(1.5, 3.0) """ assert isinstance(other, numbers.Real) @@ -155,9 +155,9 @@ def __truediv__(self, other: float) -> "Vec2d": # Unary operations def __neg__(self) -> "Vec2d": - """Return the negated version of the Vec2d + """Return the negated version of the Vec2d. - >>> -Vec2d(1,-2) + >>> -Vec2d(1, -2) Vec2d(-1, 2) """ return Vec2d(operator.neg(self.x), operator.neg(self.y)) @@ -165,15 +165,15 @@ def __neg__(self) -> "Vec2d": def __pos__(self) -> "Vec2d": """Return the unary pos of the Vec2d. - >>> +Vec2d(1,-2) + >>> +Vec2d(1, -2) Vec2d(1, -2) """ return Vec2d(operator.pos(self.x), operator.pos(self.y)) def __abs__(self) -> float: - """Return the length of the Vec2d + """Return the length of the Vec2d. - >>> abs(Vec2d(3,4)) + >>> abs(Vec2d(3, 4)) 5.0 """ return self.length @@ -181,11 +181,11 @@ def __abs__(self) -> float: # vectory functions def get_length_sqrd(self) -> float: """Get the squared length of the vector. - If the squared length is enough it is more efficient to use this method + If the squared length is enough, it is more efficient to use this method instead of first calling get_length() or access .length and then do a x**2. - >>> v = Vec2d(3,4) + >>> v = Vec2d(3, 4) >>> v.get_length_sqrd() == v.length**2 True @@ -231,13 +231,13 @@ def rotated_degrees(self, angle_degrees: float) -> "Vec2d": """Create and return a new vector by rotating this vector by angle_degrees degrees. - :return: Rotade vector + :return: Rotated vector """ return self.rotated(math.radians(angle_degrees)) @property def angle(self) -> float: - """The angle (in radians) of the vector + """The angle (in radians) of the vector. >>> '%.2f' % Vec2d(-1, 0).angle '3.14' @@ -250,7 +250,7 @@ def angle(self) -> float: @property def angle_degrees(self) -> float: - """Gets the angle (in degrees) of a vector + """Get the angle (in degrees) of a vector. >>> Vec2d(0, 1).angle_degrees 90.0 @@ -260,7 +260,7 @@ def angle_degrees(self) -> float: return math.degrees(self.angle) def get_angle_between(self, other: Tuple[float, float]) -> float: - """Get the angle between the vector and the other in radians + """Get the angle between the vector and the other in radians. >>> '%.2f' % Vec2d(3, 0).get_angle_between(Vec2d(-1, 0)) '3.14' @@ -275,7 +275,7 @@ def get_angle_between(self, other: Tuple[float, float]) -> float: return math.atan2(cross, dot) def get_angle_degrees_between(self, other: "Vec2d") -> float: - """Get the angle between the vector and the other in degrees + """Get the angle between the vector and the other in degrees. >>> Vec2d(3, 0).get_angle_degrees_between(Vec2d(-1, 0)) 180.0 @@ -287,7 +287,7 @@ def get_angle_degrees_between(self, other: "Vec2d") -> float: return math.degrees(self.get_angle_between(other)) def normalized(self) -> "Vec2d": - """Get a normalized copy of the vector + """Get a normalized copy of the vector. Note: This function will return 0 if the length of the vector is 0. >>> Vec2d(3, 0).normalized() @@ -303,7 +303,7 @@ def normalized(self) -> "Vec2d": return Vec2d(0, 0) def normalized_and_length(self) -> Tuple["Vec2d", float]: - """Normalize the vector and return its length before the normalization + """Normalize the vector and return its length before the normalization. >>> Vec2d(3, 0).normalized_and_length() (Vec2d(1.0, 0.0), 3.0) @@ -345,7 +345,7 @@ def perpendicular_normal(self) -> "Vec2d": return Vec2d(self.x, self.y) def dot(self, other: Tuple[float, float]) -> float: - """The dot product between the vector and other vector + """The dot product between the vector and other vector. v1.dot(v2) -> v1.x*v2.x + v1.y*v2.y >>> Vec2d(5, 0).dot((0, 5)) @@ -357,7 +357,7 @@ def dot(self, other: Tuple[float, float]) -> float: return float(self.x * other[0] + self.y * other[1]) def get_distance(self, other: Tuple[float, float]) -> float: - """The distance between the vector and other vector + """The distance between the vector and other vector. >>> Vec2d(0, 2).get_distance((0, -3)) 5.0 @@ -369,11 +369,11 @@ def get_distance(self, other: Tuple[float, float]) -> float: return math.sqrt((self.x - other[0]) ** 2 + (self.y - other[1]) ** 2) def get_dist_sqrd(self, other: Tuple[float, float]) -> float: - """The squared distance between the vector and other vector + """The squared distance between the vector and other vector. It is more efficent to use this method than to call get_distance() first and then do a square() on the result. - >>> Vec2d(1, 0).get_dist_sqrd((1,10)) + >>> Vec2d(1, 0).get_dist_sqrd((1, 10)) 100 >>> Vec2d(1, 2).get_dist_sqrd((10, 11)) 162 @@ -384,7 +384,7 @@ def get_dist_sqrd(self, other: Tuple[float, float]) -> float: return (self.x - other[0]) ** 2 + (self.y - other[1]) ** 2 def projection(self, other: Tuple[float, float]) -> "Vec2d": - """Project this vector on top of other vector + """Project this vector on top of other vector. >>> Vec2d(10, 1).projection((5.0, 0)) Vec2d(10.0, 0.0) @@ -397,12 +397,13 @@ def projection(self, other: Tuple[float, float]) -> "Vec2d": other_length_sqrd = other[0] * other[0] + other[1] * other[1] if other_length_sqrd == 0.0: return Vec2d(0, 0) - projected_length_times_other_length = self.dot(other) - new_length = projected_length_times_other_length / other_length_sqrd + # projected_length_times_other_length = self.dot(other) + # new_length = projected_length_times_other_length / other_length_sqrd + new_length = self.dot(other) / other_length_sqrd return Vec2d(other[0] * new_length, other[1] * new_length) def cross(self, other: Tuple[float, float]) -> float: - """The cross product between the vector and other vector + """The cross product between the vector and the other. v1.cross(v2) -> v1.x*v2.y - v1.y*v2.x @@ -426,7 +427,7 @@ def interpolate_to(self, other: Tuple[float, float], range: float) -> "Vec2d": def convert_to_basis( self, x_vector: Tuple[float, float], y_vector: Tuple[float, float] ) -> "Vec2d": - """Converts the vector to a new basis defined by the given x and y vectors. + """Convert the vector to a new basis defined by the given x and y vectors. >>> Vec2d(10, 1).convert_to_basis((5, 0), (0, 0.5)) Vec2d(2.0, 2.0) @@ -440,7 +441,7 @@ def convert_to_basis( @property def int_tuple(self) -> Tuple[int, int]: """The x and y values of this vector as a tuple of ints. - Uses round() to round to closest int. + Use `round()` to round to closest int. >>> Vec2d(0.9, 2.4).int_tuple (1, 2) @@ -458,7 +459,7 @@ def zero() -> "Vec2d": @staticmethod def unit() -> "Vec2d": - """A unit vector pointing up + """A unit vector pointing up. >>> Vec2d.unit() Vec2d(0, 1) @@ -467,7 +468,7 @@ def unit() -> "Vec2d": @staticmethod def ones() -> "Vec2d": - """A vector where both x and y is 1 + """A vector where both x and y is 1. >>> Vec2d.ones() Vec2d(1, 1) @@ -490,14 +491,14 @@ def from_polar(length: float, angle: float) -> "Vec2d": # Extra functions, mainly for chipmunk def cpvrotate(self, other: Tuple[float, float]) -> "Vec2d": - """Uses complex multiplication to rotate this vector by the other.""" + """Use complex multiplication to rotate this vector by the other.""" assert len(other) == 2 return Vec2d( self.x * other[0] - self.y * other[1], self.x * other[1] + self.y * other[0] ) def cpvunrotate(self, other: Tuple[float, float]) -> "Vec2d": - """The inverse of cpvrotate""" + """The inverse of cpvrotate.""" assert len(other) == 2 return Vec2d( self.x * other[0] + self.y * other[1], self.y * other[0] - self.x * other[1] From a8976cb1c7d15c730b4bef993316f595fbb189af Mon Sep 17 00:00:00 2001 From: VeriTas-arch <145042207+VeriTas-arch@users.noreply.github.com> Date: Thu, 7 Nov 2024 13:59:38 +0800 Subject: [PATCH 2/5] Add a note on the convex poly constraints. --- pymunk/shapes.py | 63 ++++++++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/pymunk/shapes.py b/pymunk/shapes.py index 71719f1d..d22ae354 100644 --- a/pymunk/shapes.py +++ b/pymunk/shapes.py @@ -24,11 +24,11 @@ class Shape(PickleMixin, TypingAttrMixing, object): """Base class for all the shapes. - You usually dont want to create instances of this class directly but use + You usually don't want to create instances of this class directly but use one of the specialized shapes instead (:py:class:`Circle`, :py:class:`Poly` or :py:class:`Segment`). - All the shapes can be copied and pickled. If you copy/pickle a shape the + All the shapes can be copied and pickled. If you copy/pickle a shape, the body (if any) will also be copied. """ @@ -79,7 +79,7 @@ def shapefree(cp_shape: ffi.CData) -> None: @property def _id(self) -> int: - """Unique id of the Shape + """Unique id of the Shape. .. note:: Experimental API. Likely to change in future major, minor orpoint @@ -102,8 +102,8 @@ def _set_mass(self, mass: float) -> None: _set_mass, doc="""The mass of this shape. - This is useful when you let Pymunk calculate the total mass and inertia - of a body from the shapes attached to it. (Instead of setting the body + This is useful when you let Pymunk calculate the total mass and inertia + of a body from the shapes attached to it. (Instead of setting the body mass and inertia directly) """, ) @@ -118,9 +118,9 @@ def _set_density(self, density: float) -> None: _get_density, _set_density, doc="""The density of this shape. - - This is useful when you let Pymunk calculate the total mass and inertia - of a body from the shapes attached to it. (Instead of setting the body + + This is useful when you let Pymunk calculate the total mass and inertia + of a body from the shapes attached to it. (Instead of setting the body mass and inertia directly) """, ) @@ -168,7 +168,7 @@ def _set_collision_type(self, t: int) -> None: _set_collision_type, doc="""User defined collision type for the shape. - See :py:meth:`Space.add_collision_handler` function for more + See :py:meth:`Space.add_collision_handler` function for more information on when to use this property. """, ) @@ -295,7 +295,7 @@ def update(self, transform: Transform) -> BB: return BB(_bb.l, _bb.b, _bb.r, _bb.t) def cache_bb(self) -> BB: - """Update and returns the bounding box of this shape""" + """Update and returns the bounding box of this shape.""" _bb = cp.cpShapeCacheBB(self._shape) return BB(_bb.l, _bb.b, _bb.r, _bb.t) @@ -391,7 +391,7 @@ def _hashid(self, v: int) -> None: cp.cpShapeSetHashID(self._shape, v) def __getstate__(self) -> _State: - """Return the state of this object + """Return the state of this object. This method allows the usage of the :mod:`copy` and :mod:`pickle` modules with this class. @@ -407,9 +407,9 @@ def __getstate__(self) -> _State: class Circle(Shape): - """A circle shape defined by a radius + """A circle shape defined by a radius. - This is the fastest and simplest collision shape + This is the fastest and simplest collision shape. """ _pickle_attrs_init = Shape._pickle_attrs_init + ["radius", "offset"] @@ -445,7 +445,7 @@ def unsafe_set_radius(self, r: float) -> None: @property def radius(self) -> float: - """The Radius of the circle""" + """The Radius of the circle.""" return cp.cpCircleShapeGetRadius(self._shape) def unsafe_set_offset(self, o: Tuple[float, float]) -> None: @@ -468,7 +468,7 @@ def offset(self) -> Vec2d: class Segment(Shape): - """A line segment shape between two points + """A line segment shape between two points. Meant mainly as a static shape. Can be beveled in order to give them a thickness. @@ -483,7 +483,7 @@ def __init__( b: Tuple[float, float], radius: float, ) -> None: - """Create a Segment + """Create a Segment. It is legal to send in None as body argument to indicate that this shape is not attached to a body. However, you must attach it to a body @@ -516,7 +516,7 @@ def _get_b(self) -> Vec2d: def unsafe_set_endpoints( self, a: Tuple[float, float], b: Tuple[float, float] ) -> None: - """Set the two endpoints for this segment + """Set the two endpoints for this segment. .. note:: This change is only picked up as a change to the position @@ -535,7 +535,7 @@ def normal(self) -> Vec2d: return Vec2d(v.x, v.y) def unsafe_set_radius(self, r: float) -> None: - """Set the radius of the segment + """Set the radius of the segment. .. note:: This change is only picked up as a change to the position @@ -547,7 +547,7 @@ def unsafe_set_radius(self, r: float) -> None: @property def radius(self) -> float: - """The radius/thickness of the segment""" + """The radius/thickness of the segment.""" return cp.cpSegmentShapeGetRadius(self._shape) def set_neighbors( @@ -578,14 +578,15 @@ def __init__( ) -> None: """Create a polygon. - A convex hull will be calculated from the vertexes automatically. + A convex hull will be calculated from the vertexes automatically. Note + that concave ones will be converted to a convex hull. - Adding a small radius will bevel the corners and can significantly + Add a small radius will bevel the corners and can significantly reduce problems where the poly gets stuck on seams in your geometry. It is legal to send in None as body argument to indicate that this shape is not attached to a body. However, you must attach it to a body - before adding the shape to a space or used for a space shape query. + before adding the shape to a space or using for a space shape query. .. note:: Make sure to put the vertices around (0,0) or the shape might @@ -615,8 +616,8 @@ def __init__( :param Body body: The body to attach the poly to :param [(float,float)] vertices: Define a convex hull of the polygon - with a counterclockwise winding. - :param Transform transform: Transform will be applied to every vertex. + with a counterclockwise winding + :param Transform transform: Transform will be applied to every vertex :param float radius: Set the radius of the poly shape """ @@ -652,10 +653,10 @@ def radius(self) -> float: def create_box( body: Optional["Body"], size: Tuple[float, float] = (10, 10), radius: float = 0 ) -> "Poly": - """Convenience function to create a box given a width and height. + """Convenience function to create a box with given width and height. The boxes will always be centered at the center of gravity of the - body you are attaching them to. If you want to create an off-center + body you are attaching them to. If you want to create an off-center box, you will need to use the normal constructor Poly(...). Adding a small radius will bevel the corners and can significantly @@ -680,7 +681,7 @@ def create_box_bb(body: Optional["Body"], bb: BB, radius: float = 0) -> "Poly": """Convenience function to create a box shape from a :py:class:`BB`. The boxes will always be centered at the center of gravity of the - body you are attaching them to. If you want to create an off-center + body you are attaching them to. If you want to create an off-center box, you will need to use the normal constructor Poly(..). Adding a small radius will bevel the corners and can significantly @@ -700,7 +701,7 @@ def create_box_bb(body: Optional["Body"], bb: BB, radius: float = 0) -> "Poly": return self def get_vertices(self) -> List[Vec2d]: - """Get the vertices in local coordinates for the polygon + """Get the vertices in local coordinates for the polygon. If you need the vertices in world coordinates then the vertices can be transformed by adding the body position and each vertex rotated by the @@ -722,8 +723,8 @@ def get_vertices(self) -> List[Vec2d]: :rtype: [:py:class:`Vec2d`] """ verts = [] - l = cp.cpPolyShapeGetCount(self._shape) - for i in range(l): + lines = cp.cpPolyShapeGetCount(self._shape) + for i in range(lines): v = cp.cpPolyShapeGetVert(self._shape, i) verts.append(Vec2d(v.x, v.y)) return verts @@ -748,7 +749,7 @@ def unsafe_set_vertices( cp.cpPolyShapeSetVerts(self._shape, len(vertices), vertices, transform) def __getstate__(self) -> _State: - """Return the state of this object + """Return the state of this object. This method allows the usage of the :mod:`copy` and :mod:`pickle` modules with this class. From 436edadd569576424e4c97d33d7b20f5ef660db7 Mon Sep 17 00:00:00 2001 From: VeriTas-arch <145042207+VeriTas-arch@users.noreply.github.com> Date: Thu, 7 Nov 2024 14:02:13 +0800 Subject: [PATCH 3/5] minor change --- pymunk/shapes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pymunk/shapes.py b/pymunk/shapes.py index d22ae354..65eaf65a 100644 --- a/pymunk/shapes.py +++ b/pymunk/shapes.py @@ -564,7 +564,7 @@ def set_neighbors( class Poly(Shape): - """A convex polygon shape + """A convex polygon shape. Slowest, but most flexible collision shape. """ From c61b4c9fa319d2cea484a41362a300f16af256a6 Mon Sep 17 00:00:00 2001 From: Veritas <145042207+VeriTas-arch@users.noreply.github.com> Date: Sat, 9 Nov 2024 03:13:16 +0000 Subject: [PATCH 4/5] doc: add more description on convex ploy transformation. --- pymunk/shapes.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pymunk/shapes.py b/pymunk/shapes.py index 65eaf65a..b2c03f2c 100644 --- a/pymunk/shapes.py +++ b/pymunk/shapes.py @@ -579,7 +579,8 @@ def __init__( """Create a polygon. A convex hull will be calculated from the vertexes automatically. Note - that concave ones will be converted to a convex hull. + that concave ones will be converted to a convex hull using the Quickhull + algorithm. Add a small radius will bevel the corners and can significantly reduce problems where the poly gets stuck on seams in your geometry. From 4feef9529bbca230bb664e20d5317143e62e2e78 Mon Sep 17 00:00:00 2001 From: Veritas <145042207+VeriTas-arch@users.noreply.github.com> Date: Sat, 9 Nov 2024 12:20:20 +0000 Subject: [PATCH 5/5] review fix --- pymunk/shapes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pymunk/shapes.py b/pymunk/shapes.py index b2c03f2c..5d1162fc 100644 --- a/pymunk/shapes.py +++ b/pymunk/shapes.py @@ -582,7 +582,7 @@ def __init__( that concave ones will be converted to a convex hull using the Quickhull algorithm. - Add a small radius will bevel the corners and can significantly + Adding a small radius will bevel the corners and can significantly reduce problems where the poly gets stuck on seams in your geometry. It is legal to send in None as body argument to indicate that this