Contributing to Curvipy

We welcome contributions to Curvipy! Whether you are a seasoned developer or just getting started, there are many ways to get involved.

Non-Code Contributions

There are many ways to contribute to Curvipy without writing any code:

  • Share Curvipy with others: Share the library with your friends, colleagues, and online communities. The more people that know about Curvipy, the more likely it is to grow and improve. Additionally, you can contribute to Curvipy by using it to explain math topics on blogs, YouTube, and other platforms. This helps to reach a wider audience and increases the visibility of the library.

  • Improve documentation: Curvipy’s documentation is always in need of improvement. If you see any typos, errors, or areas that could be clearer, feel free to open a pull request or issue to suggest improvements.

  • Suggest new features: Do you have an idea for a new feature that would make Curvipy even better? We welcome feature proposals! Simply open an issue with your idea and we’ll discuss it.

Code Contributions

If you are interested in contributing code to Curvipy, here are a few things to keep in mind:

  • Code formatting: Curvipy uses Black for code formatting. Please run Black on your code before submitting a pull request to ensure that it meets the project’s formatting standards.

  • Open an issue: Before making a pull request, we recommend opening an issue to discuss your proposed changes. This helps to ensure that your pull request is focused and addresses a specific problem or need.

  • Commit messages: When committing your changes, please use clear and concise commit messages that starts with a verb in the present tense. For example: “Add new feature” or “Fix bug”.

  • Pull request template: When creating a pull request, please include a clear and concise description of the changes you are proposing. Be sure to follow the pull request template provided by the project.

We appreciate any and all contributions to Curvipy! Thank you for your interest in helping to improve the library❤️

Notes for developers

How Plotter works

Coordinates system

curvipy.Plotter works with a virtual set of coordinates defined by the a logical width and height. The logical screen size is independent of the real window size, and virtual coordinates are translated to real window coordinates. Despite setting a logical width and height do not affect the window size, it defines the xy-plane coordinate system. This is useful for precisely calibrating the distance between the axes ticks.

If we want the x-axis to have \(n \in \mathbb{N}\) total ticks with a distance \(\Delta x \in \mathbb{R}\) between their self, that is

\[\text{x-axis ticks} = \{ \Delta x \cdot i \mid i \in \mathbb{N} \land -\frac{n}{2} \leq i \leq \frac{n}{2} \}\]

and the y-axis to have \(m \in \mathbb{N}\) total ticks with a distance \(\Delta y \in \mathbb{R}\) between their self, that is

\[\text{y-axis ticks} = \{ \Delta y \cdot j \mid j \in \mathbb{N} \land -\frac{m}{2} \leq j \leq \frac{m}{2} \}\]

then

\[ \begin{align}\begin{aligned}\text{logical width} = n \cdot \Delta x\\\text{logical height} = m \cdot \Delta y\end{aligned}\end{align} \]

Note that the x-axis length equals the logical width and the y-axis length equals the logical height.

Plotting mechanic

For plotting curves and vectors, curvipy.Plotter uses the ScreenFacade class for drawing lines, polylines and arrows on screen.

class curvipy._screen.ScreenFacade(window_title: str, background_color: str, window_width: int, window_height: int, logical_width: int, logical_height: int)

Screen with a virtual system of coordinates for drawing figures such as lines, polylines, arrows and more. It encapsulates the turtle package functionalities.

ScreenFacade lets the users define a logical (or virtual) screen size by translating the given logical points (a screen position with user virtual coordinates) to a real point (the actual coordinates of the given point).

Parameters
  • window_title (str) – Title to display on window.

  • background_color (str) – Background color. Can either be a name or a hex color code.

  • window_width (int or None) – Width of the screen window (in pixels). If None, window_width equals to 50% of the display width.

  • window_height (int or None) – Height of the screen window (in pixels). If None, window_height equals to 75% of the display height.

  • logical_width (int) – Logical width of the screen. This is the width that the users of ScreenFacade class will operate with. While window_width is the real width of the screen, logical_width is a virtual representation of it.

  • logical_height (int) – Logical height of the screen. This is the height that the users of ScreenFacade class will operate with. While window_height is the real height of the screen, logical_height is a virtual representation of it.

get_screen_size() tuple[int, int]

Returns the real width and height of the screen minus an offset.

The offset is used to fix turtle.Screen.window_width() and turtle.Screen.window_height() precision.

get_real_point(logical_point: tuple[Union[int, float], Union[int, float]]) tuple[Union[int, float], Union[int, float]]

Translates the given logical point to a real point.

Parameters

logical_point (tuple[int or float, int or float]) – Virtual position to be translated.

Returns

Translated real position.

Return type

tuple[int or float, int or float]

goto_drawing(point: tuple[Union[int, float], Union[int, float]], drawing_speed: int) None

Moves pen to the given real point leaving a trace.

Parameters
  • point (tuple[int or float, int or float]) – Point (real position) to which the pen will go leaving a trace.

  • drawing_speed (int) – Speed at which the pen will move. Integer from 1 to 10.

goto_without_drawing(point: tuple[Union[int, float], Union[int, float]], drawing_speed: int) None

Moves pen to the given real point without leaving a trace.

Parameters
  • point (tuple[int or float, int or float]) – Point (real position) to which the pen will go.

  • drawing_speed (int) – Speed at which the pen will move. Integer from 1 to 10.

draw_line(start_point: tuple[Union[int, float], Union[int, float]], end_point: tuple[Union[int, float], Union[int, float]], line_width: int, line_color: str, drawing_speed: int) None

Draws a line from start position to end position.

Parameters
  • start_point (tuple[int or float, int or float]) – Logical position at which the line starts. start_point is translated to a real position.

  • end_point (tuple[int or float, int or float]) – Logical position at which the line ends. end_point is translated to a real position.

  • line_width (int) – Line width.

  • line_color (str) – Line color.

  • drawing_speed (int) – Drawing speed. Integer from 1 to 10.

draw_polyline(points: list[tuple[Union[int, float], Union[int, float]]], polyline_width: int, polyline_color: str, drawing_speed: int) None

Draws a polyline by joining the given points.

Parameters
  • points (list[tuple[int or float, int or float]]) – List of the logical position of the polyline points.

  • polyline_width (int) – Polyline width.

  • polyline_color (str) – Polyline color.

  • drawing_speed (int) – Drawing speed. Integer from 1 to 10.

draw_arrow(point: tuple[Union[int, float], Union[int, float]], arrow_size: int, arrow_angle: Union[int, float], arrow_width: int, arrow_color: str, drawing_speed: int) None

Draws an arrow > at the given point.

Parameters
  • point (tuple[int or float, int or float]) – Logical position where the arrow will be drawn.

  • arrow_size (int) – Size of the arrow.

  • arrow_angle (str) – Angle in radians. Indicates arrow direction.

  • arrow_width (int) – Width of the arrow.

  • arrow_color (str) – Color of the arrow.

  • drawing_speed (int) – Drawing speed. Integer from 1 to 10.

draw_text(text: str, point: tuple[Union[int, float], Union[int, float]], text_font: tuple[str, str, str], text_color: str, align: str) None

Display the given text at the specified point.

Parameters
  • text (str) – Text to be displayed.

  • point (tuple[int or float, int or float]) – Logical position where the text will be drawn.

  • text_font (tuple[str, str, str]) – A triple (fontname, fontsize, fonttype).

  • text_color (str) – Text color.

  • align (str) – Text alignment.

clean() None

Removes all drawings from screen.

exit_on_click()

Exits screen when clicked.

Note: ScreenFacade is a composite of curvipy.Plotter, therefore users should not access this class (that is why you will not find ScreenFacade on the Documentation section).

Thanks to this class, the plotter can work with logical points (also known as virtual points), i.e. the actual mathematical coordinates of points. Evidently, logical points do not represent the real positions where the points will be drawn on screen, the real points. Real points depend on the screen size and the scale of the axes. The ScreenFacade.get_real_point() method translates a logical point to a real point. In other words, it returns the window position on which the logical point sits:

Given a virtual point \(P_{v} = (x_{v}, y_{v})\), a real point \(P_{r} = (x_{r}, y_{r})\), and the screen real width \(w_{r}\), real height \(h_{r}\), virtual width \(w_{v}\) and virtual height \(h_{v}\), the function \(f: \mathbb{R}^2 \rightarrow \mathbb{R}^2\) that maps a virtual point to its respective real point is defined as:

\[f(P_{v}) = (x_{v} \cdot \frac{w_{r}}{w_{v}}, y_{v} \cdot \frac{h_{r}}{h_{v}}) = P_{r}\]