Skip to content

Commit b77bf55

Browse files
MrRedstone058Emc2356andrewhong04ScriptLineStudiosavaxar
authored
Added Line methods and length attribute (#3179)
* Added Line methods and 'length: attribute * fixed minor checks * Update geometry.pyi * commit geometry.Line changes * changed geometry docs * changed docs, if_else statements and decluttered * Compacted geometry_common.c * Update geometry_common.c * Update line.c --------- Co-authored-by: Emc2356 <63981925+emc2356@users.noreply.github.com> Co-authored-by: NovialRiptide <35881688+novialriptide@users.noreply.github.com> Co-authored-by: ScriptLineStudios <scriptlinestudios@protonmail.com> Co-authored-by: Avaxar <44055981+avaxar@users.noreply.github.com> Co-authored-by: maqa41 <amehebbet41@gmail.com> Co-authored-by: itzpr3d4t0r <103119829+itzpr3d4t0r@users.noreply.github.com>
1 parent 746197d commit b77bf55

File tree

7 files changed

+609
-30
lines changed

7 files changed

+609
-30
lines changed

buildconfig/stubs/pygame/geometry.pyi

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,8 @@ class Line:
163163
def b(self) -> tuple[float, float]: ...
164164
@b.setter
165165
def b(self, value: Point) -> None: ...
166+
@property
167+
def length(self) -> float: ...
166168
@overload
167169
def __init__(self, ax: float, ay: float, bx: float, by: float) -> None: ...
168170
@overload
@@ -171,3 +173,27 @@ class Line:
171173
def __init__(self, line: _LineLike) -> None: ...
172174
def __copy__(self) -> Line: ...
173175
def copy(self) -> Line: ...
176+
@overload
177+
def update(self, ax: float, ay: float, bx: float, by: float, /) -> None: ...
178+
@overload
179+
def update(self, a: Point, b: Point, /) -> None: ...
180+
@overload
181+
def update(self, line: _LineLike, /) -> None: ...
182+
@overload
183+
def move(self, x: float, y: float, /) -> Line: ...
184+
@overload
185+
def move(self, move_by: Point, /) -> Line: ...
186+
@overload
187+
def move_ip(self, x: float, y: float, /) -> None: ...
188+
@overload
189+
def move_ip(self, move_by: Point, /) -> None: ...
190+
@overload
191+
def scale(self, factor: float, origin: float, /) -> Line: ...
192+
@overload
193+
def scale(self, factor_and_origin: Tuple[float, float], /) -> Line: ...
194+
@overload
195+
def scale_ip(self, factor: float, origin: float, /) -> None: ...
196+
@overload
197+
def scale_ip(self, factor_and_origin: Tuple[float, float], /) -> None: ...
198+
def flip_ab(self) -> Line: ...
199+
def flip_ab_ip(self) -> None: ...

docs/reST/ref/geometry.rst

Lines changed: 136 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@
9898
| :sl:`x and y coordinates of the center of the circle`
9999
| :sg:`center -> (float, float)`
100100
101-
It's a tuple containing the circle's `x` and `y` coordinates representing its center.
101+
A tuple containing the circle's `x` and `y` coordinates representing its center.
102102
Reassigning it moves the circle to the new position.
103103

104104
.. versionadded:: 2.4.0
@@ -147,7 +147,7 @@
147147
| :sl:`top coordinate of the circle`
148148
| :sg:`top -> (float, float)`
149149
150-
It's a tuple containing the `x` and `y` coordinates that represent the top
150+
A tuple containing the `x` and `y` coordinates that represent the top
151151
of the circle.
152152
Reassigning it moves the circle to the new position. The radius will not be affected.
153153

@@ -160,7 +160,7 @@
160160
| :sl:`bottom coordinate of the circle`
161161
| :sg:`bottom -> (float, float)`
162162
163-
It's a tuple containing the `x` and `y` coordinates that represent the bottom
163+
A tuple containing the `x` and `y` coordinates that represent the bottom
164164
of the circle.
165165
Reassigning it moves the circle to the new position. The radius will not be affected.
166166

@@ -173,7 +173,7 @@
173173
| :sl:`left coordinate of the circle`
174174
| :sg:`left -> (float, float)`
175175
176-
It's a tuple containing the `x` and `y` coordinates that represent the left
176+
A tuple containing the `x` and `y` coordinates that represent the left
177177
of the circle.
178178
Reassigning it moves the circle to the new position. The radius will not be affected.
179179

@@ -186,7 +186,7 @@
186186
| :sl:`right coordinate of the circle`
187187
| :sg:`right -> (float, float)`
188188
189-
It's a tuple containing the `x` and `y` coordinates that represent the right
189+
A tuple containing the `x` and `y` coordinates that represent the right
190190
of the circle.
191191
Reassigning it moves the circle to the new position. The radius will not be affected.
192192

@@ -574,7 +574,7 @@
574574
| :sl:`the first point of the line`
575575
| :sg:`a -> (float, float)`
576576
577-
It's a tuple containing the `ax` and `ay` attributes representing the line's first point.
577+
A tuple containing the `ax` and `ay` attributes representing the line's first point.
578578
It can be reassigned to move the `Line`. If reassigned the `ax` and `ay` attributes
579579
will be changed to produce a `Line` with matching first point position.
580580
The `bx` and `by` attributes will not be affected.
@@ -588,7 +588,7 @@
588588
| :sl:`the second point of the line`
589589
| :sg:`b -> (float, float)`
590590
591-
It's a tuple containing `bx` and `by` attributes representing the line's second point.
591+
A tuple containing `bx` and `by` attributes representing the line's second point.
592592
It can be reassigned to move the `Line`. If reassigned the `bx` and `by` attributes
593593
will be changed to produce a `Line` with matching second point position.
594594
The `ax` and `ay` attributes will not be affected.
@@ -597,6 +597,19 @@
597597

598598
.. ## Line.b ##
599599
600+
.. attribute:: length
601+
602+
| :sl:`the length of the line`
603+
| :sg:`length -> float`
604+
605+
The length of the line. Calculated using the `sqrt((bx-ax)**2 + (by-ay)**2)` formula.
606+
This attribute is read-only, it cannot be reassigned. To change the line's length
607+
use the `scale` method or change its `a` or `b` attributes.
608+
609+
.. versionadded:: 2.5.3
610+
611+
.. ## Line.length ##
612+
600613
**Line Methods**
601614

602615
----
@@ -611,3 +624,119 @@
611624
.. versionadded:: 2.5.2
612625

613626
.. ## Line.copy ##
627+
628+
.. method:: move
629+
630+
| :sl:`moves the line by a given amount`
631+
| :sg:`move((x, y)) -> Line`
632+
| :sg:`move(x, y) -> Line`
633+
634+
Returns a new `Line` that is moved by the given offset. The original `Line` is
635+
not modified.
636+
637+
This method is equivalent to the following code:
638+
639+
.. code-block:: python
640+
641+
Line(line.ax + x, line.ay + y, line.bx + x, line.by + y)
642+
643+
.. versionadded:: 2.5.3
644+
645+
.. ## Line.move ##
646+
647+
.. method:: move_ip
648+
649+
| :sl:`moves the line by a given amount`
650+
| :sg:`move_ip((x, y)) -> None`
651+
| :sg:`move_ip(x, y) -> None`
652+
653+
Moves the `Line` by the given offset. The original `Line` is modified. Always returns
654+
`None`.
655+
656+
This method is equivalent to the following code:
657+
658+
.. code-block:: python
659+
660+
line.ax += x
661+
line.ay += y
662+
line.bx += x
663+
line.by += y
664+
665+
.. versionadded:: 2.5.3
666+
667+
.. ## Line.move_ip ##
668+
669+
.. method:: update
670+
671+
| :sl:`updates the line's attributes`
672+
| :sg:`update((ax, ay), (bx, by)) -> None`
673+
| :sg:`update(ax, ay, bx, by) -> None`
674+
| :sg:`update(line) -> None`
675+
676+
Updates the `Line`'s attributes. The original `Line` is modified. Always returns `None`.
677+
678+
This method is equivalent to the following code:
679+
680+
.. code-block:: python
681+
682+
line.ax = ax
683+
line.ay = ay
684+
line.bx = bx
685+
line.by = by
686+
687+
.. versionadded:: 2.5.3
688+
689+
.. ## Line.update ##
690+
691+
.. method:: scale
692+
693+
| :sl:`scales the line by the given factor from the given origin`
694+
| :sg:`scale(factor, origin) -> Line`
695+
| :sg:`scale(factor_and_origin) -> Line`
696+
697+
Returns a new `Line` which is scaled by the given factor from the specified origin with 0.0 being
698+
the starting point, 0.5 being the center and 1.0 being the end point.
699+
The original `Line` is not modified.
700+
701+
.. versionadded:: 2.5.3
702+
703+
.. ## Line.scale ##
704+
705+
.. method:: scale_ip
706+
707+
| :sl:`scales the line by the given factor from the given origin in place`
708+
| :sg:`scale_ip(factor, origin) -> None`
709+
| :sg:`scale_ip(factor_and_origin) -> None`
710+
711+
Scales the `Line` by the given factor from the specified origin with 0.0 being
712+
the starting point, 0.5 being the center and 1.0 being the end point.
713+
The original `Line` is modified.
714+
Always returns `None`.
715+
716+
.. versionadded:: 2.5.3
717+
718+
.. ## Line.scale_ip ##
719+
720+
.. method:: flip_ab
721+
722+
| :sl:`flips the line a and b points`
723+
| :sg:`flip_ab() -> Line`
724+
725+
Returns a new `Line` that has the `a` and `b` points flipped.
726+
The original `Line` is not modified.
727+
728+
.. versionadded:: 2.5.3
729+
730+
.. ## Line.flip_ab ##
731+
732+
.. method:: flip_ab_ip
733+
734+
| :sl:`flips the line a and b points, in place`
735+
| :sg:`flip_ab_ip() -> None`
736+
737+
Flips the `Line`'s `a` and `b` points. The original `Line` is modified.
738+
Always returns `None`.
739+
740+
.. versionadded:: 2.5.3
741+
742+
.. ## Line.flip_ab_ip ##

src_c/doc/geometry_doc.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,12 @@
3636
#define DOC_LINE_BY "by -> float\ny coordinate of the end point of the line"
3737
#define DOC_LINE_A "a -> (float, float)\nthe first point of the line"
3838
#define DOC_LINE_B "b -> (float, float)\nthe second point of the line"
39+
#define DOC_LINE_LENGTH "length -> float\nthe length of the line"
3940
#define DOC_LINE_COPY "copy() -> Line\ncopies the line"
41+
#define DOC_LINE_MOVE "move((x, y)) -> Line\nmove(x, y) -> Line\nmoves the line by a given amount"
42+
#define DOC_LINE_MOVEIP "move_ip((x, y)) -> None\nmove_ip(x, y) -> None\nmoves the line by a given amount"
43+
#define DOC_LINE_UPDATE "update((ax, ay), (bx, by)) -> None\nupdate(ax, ay, bx, by) -> None\nupdate(line) -> None\nupdates the line's attributes"
44+
#define DOC_LINE_SCALE "scale(factor, origin) -> Line\nscale(factor_and_origin) -> Line\nscales the line by the given factor from the given origin"
45+
#define DOC_LINE_SCALEIP "scale_ip(factor, origin) -> None\nscale_ip(factor_and_origin) -> None\nscales the line by the given factor from the given origin in place"
46+
#define DOC_LINE_FLIPAB "flip_ab() -> Line\nflips the line a and b points"
47+
#define DOC_LINE_FLIPABIP "flip_ab_ip() -> None\nflips the line a and b points, in place"

src_c/geometry_common.c

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -162,29 +162,23 @@ pgLine_FromObject(PyObject *obj, pgLineBase *out)
162162
length = PySequence_Fast_GET_SIZE(obj);
163163
PyObject **farray = PySequence_Fast_ITEMS(obj);
164164

165-
if (length == 4) {
166-
if (!pg_DoubleFromObj(farray[0], &out->ax) ||
167-
!pg_DoubleFromObj(farray[1], &out->ay) ||
168-
!pg_DoubleFromObj(farray[2], &out->bx) ||
169-
!pg_DoubleFromObj(farray[3], &out->by)) {
170-
return 0;
171-
}
172-
return 1;
173-
}
174-
else if (length == 2) {
175-
if (!pg_TwoDoublesFromObj(farray[0], &out->ax, &out->ay) ||
176-
!pg_TwoDoublesFromObj(farray[1], &out->bx, &out->by)) {
177-
PyErr_Clear();
165+
switch (length) {
166+
case 4:
167+
return pg_DoubleFromObj(farray[0], &out->ax) &&
168+
pg_DoubleFromObj(farray[1], &out->ay) &&
169+
pg_DoubleFromObj(farray[2], &out->bx) &&
170+
pg_DoubleFromObj(farray[3], &out->by);
171+
case 2:
172+
return pg_TwoDoublesFromObj(farray[0], &out->ax, &out->ay) &&
173+
pg_TwoDoublesFromObj(farray[1], &out->bx, &out->by);
174+
case 1: /*looks like an arg?*/
175+
if (PyUnicode_Check(farray[0]) ||
176+
!pgLine_FromObject(farray[0], out)) {
177+
return 0;
178+
}
179+
return 1;
180+
default:
178181
return 0;
179-
}
180-
return 1;
181-
}
182-
else if (length == 1) /*looks like an arg?*/ {
183-
if (PyUnicode_Check(farray[0]) ||
184-
!pgLine_FromObject(farray[0], out)) {
185-
return 0;
186-
}
187-
return 1;
188182
}
189183
}
190184
else if (PySequence_Check(obj)) {
@@ -276,6 +270,26 @@ pgLine_FromObject(PyObject *obj, pgLineBase *out)
276270
return 1;
277271
}
278272

273+
int
274+
pgLine_FromObjectFastcall(PyObject *const *args, Py_ssize_t nargs,
275+
pgLineBase *out)
276+
{
277+
switch (nargs) {
278+
case 1:
279+
return pgLine_FromObject(args[0], out);
280+
case 2:
281+
return pg_TwoDoublesFromObj(args[0], &out->ax, &out->ay) &&
282+
pg_TwoDoublesFromObj(args[1], &out->bx, &out->by);
283+
case 4:
284+
return pg_DoubleFromObj(args[0], &out->ax) &&
285+
pg_DoubleFromObj(args[1], &out->ay) &&
286+
pg_DoubleFromObj(args[2], &out->bx) &&
287+
pg_DoubleFromObj(args[3], &out->by);
288+
default:
289+
return 0;
290+
}
291+
}
292+
279293
static inline int
280294
double_compare(double a, double b)
281295
{

src_c/geometry_common.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ pgCircle_FromObjectFastcall(PyObject *const *args, Py_ssize_t nargs,
1616
int
1717
pgLine_FromObject(PyObject *obj, pgLineBase *out);
1818

19+
int
20+
pgLine_FromObjectFastcall(PyObject *const *args, Py_ssize_t nargs,
21+
pgLineBase *out);
22+
1923
static inline int
2024
double_compare(double a, double b);
2125

0 commit comments

Comments
 (0)