# Renderable

{% hint style="warning" %}
Quick Reference can help with simple issues or give you a basic understanding of the methods available, but it can never replace full documentation which is available [here](https://pydraw.graphics/api).
{% endhint %}

## Initialization

We can initialize the default 3 shapes by calling their respective constructors:

```python
rectangle = Rectangle(screen, x, y, width, height)
oval = Oval(screen, x, y, width, height)
triangle = Triangle(screen, x, y, width, height)
```

The constructor has more arguments that are optional:

```python
Renderable(screen, x, y, width, height, color, border, fill, rotation, visible)
```

{% hint style="info" %}
It's crucial to note that all Renderables are rendered from the top-left. So the passed (x, y) for a Rectangle would be its top left corner.
{% endhint %}

## Types

There are a few different Renderables that can be created:

```python
rectangle = Rectangle(screen, x, y, width, height)
oval = Oval(screen, x, y, width, height)
triangle = Triangle(screen, x, y, width, height)

# Note that for Polygon we specify num_sides before (x, y)
polygon = Polygon(screen, num_sides, x, y, width, height)

# We can create an irregular polygon by specifying vertices
irregular = CustomPolygon(screen, vertices, color, border, fill, rotation, visible)
```

{% hint style="info" %}
Although Text is classified as a Renderable, it is not directly resizable and has specific methods unique to Text: [Reference](/quick-reference/text.md).
{% endhint %}

## Movement

Moving any Renderable is alike to moving a Location:

```python
renderable.x(new_x)  # Get or set the x-coordinate
renderable.y(new_y)  # Get or set the y-coordinate

renderable.move(dx, dy)  # Move by (dx, dy)
renderable.move((dx, dy))  # Tuple representation of (dx, dy)
renderable.move(dx=100)  # Move the x-coordinate by +100

renderable.moveto(x, y)  # Move to (x, y)
renderable.moveto((x, y))  # Tuple representation of (x, y)
renderable.moveto(y=100)  # Move the y-coordinate to +100
```

We can also make a Renderable move forward at its current heading/angle via:

```python
renderable.forward(distance)  # Move forward at current angle by distance
renderable.backward(distance)  # Move backward at current angle by distance
```

{% hint style="info" %}
Note that these methods utilize the Renderables [rotation](/quick-reference/renderable.md#rotation).
{% endhint %}

## Location

You can also retrieve the Location with:

```python
renderable.location()
```

## Center

You can get the Location of the center of any Renderable:

```python
renderable.center()
```

{% hint style="info" %}
Note: This calculates the center by default (except for CustomPolygons), but you can get the [*centroid*](https://en.wikipedia.org/wiki/Centroid) of the shape by setting `centroid=True` in the method arguments.
{% endhint %}

You can also use this method to move the Renderable to place its center in a certain location:

```python
renderable.center(x, y)
renderable.center(location)
renderable.center((x, y))
```

## Rotation

You can get or modify the rotation of a Renderable like so:

```python
renderable.rotation()  # Get the current angle
renderable.rotation(angle)  # Set a new angle of rotation

renderable.rotate(angle_change)  # Change the angle by a specified argument
```

You can also just make a Renderable look at a Location or Renderable:

```python
renderable.lookat(other)  # Look at another Renderable
renderable.lookat(location)  # Look at a Location
```

You can also check the angle of the Renderable against any Object or Location:

```python
renderable.angleto(obj)
renderable.angleto(location)
renderable.angleto((x, y))
```

## Size

You can retrieve or modify the size of the Renderable like so:

```python
renderable.width()  # Get the current width
renderable.width(width)  # Modify the width
renderable.width(width, ratio=True)  # Maintain the ratio of the Renderable

erable.height()  # Get the current height
renderable.height(height)  # Modify the height
renderable.height(height, ratio=True)  # Maintain the ratio of the Renderable
```

{% hint style="info" %}
Note: Width and Height refer to the width and height of the original shape, regardless of rotation.
{% endhint %}

## Color

All Renderables have a default Color of black; the color can be retrieved or set via:

```python
renderable.color()  # Get the color
renderable.color(color)  # Set a new color
```

## Border and Fill

Renderables also have an optional border that is set to Color.NONE by default. You can set or retrieve the border like so:

```python
renderable.border()  # Get the border's color. If none is set, returns Color.NONE
renderable.border(color)  # Set a new color for the border
renderable.border(color, width=5)  # Set a new color and a borderwidth
renderable.border(color, fill=False)  # Set a new color and disable the fill
```

You can get or set the `border_width` seperately with:

```python
renderable.border_width()  # returns border width
renderable.border_width(5)  # sets to 5
```

Fill exists (as seen above) to create Framed Renderables with ease. Fill can be toggled without calling the `border()` method like so:

```python
renderable.fill(False)  # Change the fill to False.
```

## Visibility

You can make any Object in pyDraw invisible with:

```python
renderable.visible(False)  # Make the Object invisible
```

## Ordering

You can move objects to the front or back of layers with:

```python
renderable.front()  # Move to the front
renderable.back()  # Move to the back
```

## Distance

You can get the distance between a Renderable and another Renderable, or Location like so:

```python
renderable.distance(other)  # Pass in another renderable
renderable.distance(location)  # Pass in a Location
```

## Transform and Cloning

A transform is a data structure that represents the width, height, and rotation. You can copy the transform of a Renderable and set it to another transform:

```python
renderable.transform()  # Retrieve the transform
renderable.transform(transform)  # Set a new transform
```

{% hint style="warning" %}
You should only set the transform to other transforms retrieved from Renderables, however, it is possible to create one yourself:

```python
transform = (width, height, angle);
```

{% endhint %}

You can also clone a Renderable by calling the aptly named:

```python
renderable.clone()
```

## Vertices

For those who want to perform more advanced mathematics with their shapes, you can retrieve a (copy) list of vertices:

```python
renderable.vertices()
```

{% hint style="info" %}
Vertices usually will begin at the top left and work clockwise.
{% endhint %}

## Bounds

You can get the location and dimensions of a bounding box calculated by pyDraw around any Renderable:

```python
renderable.bounds()  # returns (Location, width, height)
```

## Contains and Overlaps

You can check if a point is contained in any Renderable like so:

```python
renderable.contains(location)  # Pass in a normal location
renderable.contains(x, y)  # Or you can specify x and y
renderable.contains((x, y))  # Or you can pass in a tuple
```

Or you can check if two Renderables are overlapping:

```python
renderable.overlaps(other)
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.pydraw.graphics/quick-reference/renderable.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
