.. currentmodule:: pygame_geometry
The Line class provides many useful methods for collision, transform and intersection. A Line can be created from a pair of coordinates that represent the first and second point of the Line. Lines can also be created from python objects that are already a Line or have an attribute named "line".
Specifically, to construct a Line you can pass the xa, ya, xb, yb values as separate arguments or inside a sequence(list or tuple).
Functions that require a Line argument may also accept these values as Lines:
((xa, ya), (xb, yb)) (xa, ya, xb, yb)
You cannot create degenerate Lines(lines with the same start and end point). If you try, the `Line` will not be created and an error will be raised.
The Line class has both virtual and non-virtual attributes. Non-virtual attributes are attributes that are stored in the Line object itself. Virtual attributes are the result of calculations that utilize the Line's non-virtual attributes.
Here is the list of all the attributes of the Line class:
.. attribute:: xa | :sl:`x coordinate of the first point of the line` | :sg:`xa -> float` The `x` coordinate of the first point of the `Line`. It can be reassigned to move the `Line`. Reassigning the `xa` attribute will move x position of the first point to the new `x` coordinate. The `ya`, `xb`, `yb` attributes will not be affected... attribute:: ya | :sl:`y coordinate of the first point of the line` | :sg:`ya -> float` The `y` coordinate of the first point of the `Line`. It can be reassigned to move the `Line`. Reassigning the `ya` attribute will move x position of the first point to the new `y` coordinate. The `xa`, `xb`, `yb` attributes will not be affected... attribute:: xb | :sl:`x coordinate of the second point of the line` | :sg:`xb -> float` The `x` coordinate of the second point of the `Line`. It can be reassigned to move the `Line`. Reassigning the `xb` attribute will move x position of the first point to the new `x` coordinate. The `xa`, `ya`, `yb` attributes will not be affected... attribute:: yb | :sl:`y coordinate of the second point of the line` | :sg:`yb -> float` The `y` coordinate of the second point of the `Line`. It can be reassigned to move the `Line`. Reassigning the `yb` attribute will move x position of the first point to the new y` coordinate. The `xa`, `ya`, `xb` attributes will not be affected... attribute:: a | :sl:`the first point of the line` | :sg:`a -> (float, float)` It's a tuple containing the `xa` and `ya` attributes representing the line's first point. It can be reassigned to move the `Line`. If reassigned the `xa` and `ya` attributes will be changed to produce a `Line` with matching first point position. The `xb` and `yb` attributes will not be affected... attribute:: b | :sl:`the second point of the line` | :sg:`b -> (float, float)` It's a tuple containing `xb` and `yb` attributes representing the line's second point. It can be reassigned to move the `Line`. If reassigned the `xb` and `yb` attributes will be changed to produce a `Line` with matching second point position. The `xa` and `ya` attributes will not be affected... attribute:: length | :sl:`the length of the line` | :sg:`length -> float` The length of the line. Calculated using the `sqrt((xb-xa)**2 + (yb-ya)**2)` formula. This attribute is read-only, it cannot be reassigned. To change the line's length use the `scale` method or change its `a` or `b` attributes... attribute:: angle | :sl:`the angle of the line` | :sg:`angle -> float` The angle of the line representing its orientation. Calculated using the `atan2(yb - ya, xb - xa)` formula. This attribute is read-only, it cannot be reassigned. To change the line's angle use the `rotate` method or change its `a` or `b` attributes... attribute:: slope | :sl:`the slope of the line` | :sg:`slope -> float` The slope of the line. Calculated using the `(yb - ya) / (xb - xa)` formula. This attribute is read-only, it cannot be reassigned. To change the line's slope use the `rotate` method or change its `a` or `b` attributes... attribute:: center | :sl:`the coordinate of the middle point of the line` | :sg:`center -> (float, float)` The center of the line. Calculated using the `((xa + xb) / 2, (ya + yb) / 2)` formula. It can be reassigned to move the `Line`. If reassigned the `xa`, `ya`, `xb`, `yb` attributes will be changed in order to produce a `Line` with matching center... attribute:: centerx | :sl:`the x coordinate of the middle point of the line` | :sg:`centerx -> float` The `x` coordinate of the center of the line, it's calculated using the `((xa + xb) / 2)` formula. It can be reassigned to move the `Line`. If reassigned the `xa` and `xb` attributes will be changed in order to produce a `Line` with matching center. The `ya` and `yb` attributes will not be affected... attribute:: centery | :sl:`the y coordinate of the middle point of the line` | :sg:`centery -> float` The `y` coordinate of the center of the `Line`, it's calculated using the `((ya + yb) / 2)` formula. It can be reassigned to move the `Line`. If reassigned the `ya` and `yb` attributes will be changed in order to produce a `Line` with matching center. The `xa` and `xb` attributes will not be affected.
The Line functions which modify the position, orientation or size return a new copy of the Line with the affected changes. The original Line is not modified. Some methods have an alternate "in-place" version that returns None but affects the original Line. These "in-place" methods are denoted with the "ip" suffix.
Here is the list of all the methods of the Line class:
.. method:: move | :sl:`moves the line by a given amount` | :sg:`move((x, y)) -> Line` | :sg:`move(x, y) -> Line` Returns a new Line that is moved by the given offset. The original Line is not modified. .. note:: This method is equivalent(behaviour wise) to the following code: :: Line(line.xa + x, line.ya + y, line.xb + x, line.yb + y) .. ## Line.move ##.. method:: move_ip | :sl:`moves the line by a given amount` | :sg:`move_ip((x, y)) -> None` | :sg:`move_ip(x, y) -> None` Moves the Line by the given offset. The original Line is modified. Always returns None. .. note:: This method is equivalent(behaviour wise) to the following code: :: line.xa += x line.ya += y line.xb += x line.yb += y .. ## Line.move_ip ##.. method:: update | :sl:`updates the line's attributes` | :sg:`update((xa, ya), (xb, yb)) -> None` | :sg:`update(xa, ya, xb, yb) -> None` | :sg:`update(Line) -> None` Updates the `Line`'s attributes. The original Line is modified. Always returns None. .. note:: This method is equivalent(behaviour wise) to the following code: :: line.xa = xa line.ya = ya line.xb = xb line.yb = yb .. ## Line.update ##.. method:: as_rect | :sl:`returns the line as a Rect` | :sg:`as_rect() -> Rect` Returns a `pygame.Rect` object that contains the Line. The Rect object will be the smallest rectangle that contains the Line. .. ## Line.as_rect ##.. method:: scale | :sl:`scales the line by the given factor from the given origin` | :sg:`scale(factor, origin) -> Line` | :sg:`scale(factor_and_origin) -> Line` Returns a new `Line` which is scaled by the given factor from the specified origin with 0.0 being the startpoint, 0.5 being the center and 1.0 being the end point. The original `Line` is not modified. .. ## Line.scale ##.. method:: scale_ip | :sl:`scales the line by the given factor from the given origin in place` | :sg:`scale_ip(factor, origin) -> None` | :sg:`scale_ip(factor_and_origin) -> None` Scales the `Line` by the given factor from the specified origin with 0.0 being the startpoint, 0.5 being the center and 1.0 being the end point. The original `Line` is modified. .. ## Line.scale_ip ##.. method:: flip_ab | :sl:`flips the line a and b points` | :sg:`flip_ab() -> Line` Returns a new `Line` that has the `a` and `b` points flipped. The original `Line` is not modified. .. ## Line.flip_ab ##.. method:: flip_ab_ip | :sl:`flips the line a and b points, in place` | :sg:`flip_ab_ip() -> None` Flips the `Line`'s `b` and `b` points. The original `Line` is modified. Always returns None. .. ## Line.flip_ab_ip ##.. method:: is_parallel | :sl:`test if the line is parallel to another line` | :sg:`is_parallel(Line) -> bool` Returns True if the `Line` is parallel to the given `Line`, False otherwise. .. ## Line.is_parallel ##.. method:: is_perpendicular | :sl:`test if the line is perpendicular to another line` | :sg:`is_perpendicular(Line) -> bool` Returns True if the `Line` is perpendicular to the given `Line`, False otherwise. .. ## Line.is_perpendicular ##.. method:: collidepoint | :sl:`test if a point is on the line` | :sg:`collidepoint((x, y)) -> bool` | :sg:`collidepoint(x, y) -> bool` | :sg:`collidepoint(Vector2) -> bool` Returns True if the given point is on the `Line`, False otherwise. .. ## Line.collidepoint ##.. method:: collideline | :sl:`test if a line intersects with another line` | :sg:`collideline(Line) -> bool` | :sg:`collideline((xa, ya), (xb, yb)) -> bool` | :sg:`collideline(xa, ya, xb, yb) -> bool` Returns True if the `Line` intersects with the given `Line`, False otherwise. .. ## Line.collideline ##.. method:: colliderect | :sl:`test if a line intersects with a rectangle` | :sg:`colliderect(Rect) -> bool` | :sg:`colliderect((x, y, w, h)) -> bool` | :sg:`colliderect(x, y, w, h) -> bool` Returns True if the `Line` intersects with the given `Rect`, False otherwise. .. ## Line.colliderect ##.. method:: collidecircle | :sl:`test if a line intersects with a circle` | :sg:`collidecircle(Circle) -> bool` | :sg:`collidecircle((x, y, r)) -> bool` | :sg:`collidecircle(x, y, r) -> bool` Returns True if the `Line` intersects with the given `Circle`, False otherwise. .. ## Line.collidecircle ##.. method:: collidepolygon | :sl:`test if a line intersects with a polygon` | :sg:`collidepolygon(Polygon, only_edges=False) -> bool` | :sg:`collidepolygon((xa, ya), (xb, yb), ..., only_edges=False) -> bool` | :sg:`collidepolygon(xa, ya, xb, yb, ..., only_edges=False) -> bool` Tests whether a given `Polygon` collides with the `Line`. It takes either a `Polygon` or Polygon-like object as an argument and it returns `True` if the polygon collides with the `Line`, `False` otherwise. The optional `only_edges` argument can be set to `True` to only test whether the edges of the polygon intersect the `Line`. This means that a Line that is inscribed by the `Polygon` or completely outside of it will not be considered colliding. This can be useful for performance reasons if you only care about the edges of the polygon. .. note:: Keep in mind that the more vertices the polygon has, the more CPU time it will take to calculate the collision. .. ## Line.collidepolygon ##.. method:: collide | :sl:`test if a shape or point and the line collide` | :sg:`collide(Line) -> bool` | :sg:`collide(Circle) -> bool` | :sg:`collide(Rect) -> bool` | :sg:`collide(Polygon) -> bool` | :sg:`collide((x, y)) -> bool` | :sg:`contains(Vector2) -> bool` Returns `True` if any portion of the shape or point overlaps with the Line, `False` otherwise. This is a general alternative to the collision problem as it can be used to test for collisions with any shape or point. The shape can be a `Line`, `Circle`, `Polygon`, or `Rect`. The point can be a tuple or list containing the x and y coordinates of the point or a Vector2. .. note:: If a shape is passed it must be an actual single shape object. It cannot be a tuple or list of coordinates that represent the shape. This is because there is no way to determine what type of shape the coordinates represent. .. note:: Collisions with a `Polygon` object are evaluated the same way the :meth:`collidepolygon` method does by default, meaning with only_edges set to `False`. .. ## Line.collide ##.. method:: as_circle | :sl:`returns a circle that extends over the line` | :sg:`as_circle() -> Circle` Returns a `Circle` object, with the center point being the center point of the `Line`, and the diameter being the length of the `Line`. .. ## Line.as_circle ##.. method:: at | :sl:`returns the point at a given distance from the line's a point` | :sg:`at(fac) -> (x, y)` Returns the point at the given distance from the line's a point. The distance can be negative, in which case the point will be on the continuation of the line, but in the opposite direction. .. ## Line.at ##.. method:: copy | :sl:`returns a copy of the line` | :sg:`copy() -> Line` Returns a new `Line` having the same position and radius as the original. .. ## Line.copy ##.. method:: as_segments | :sl:`returns the line as a list of segments` | :sg:`as_segments(n_segments) -> [(x, y), (x, y)]` Segments the original line into N Lines of equal length and returns a list of them. The number of segments is determined by the `n_segments` parameter. .. note:: The original line is not modified. The returned list of lines will always have the first line's `a` point at the same position as the original line's `a` point and the last line's `b` point at the same position as the original line's `b` point. .. ## Line.as_segments ##.. method:: as_points | :sl:`returns the line as a list of points` | :sg:`as_points(n_points) -> [(x, y), (x, y)]` Returns a list of points that represent the line. The first point in the list will be the line's `a` point and the last point will be the line's `b` point. The number of points is determined by the `n_points` parameter. .. note:: The n_points parameter refers to the number of points that will created in between the line's `a` and `b` points. The number of points returned will always be n_points + 2. Because of this the n_points parameter must be at least 0. .. ## Line.as_points ##