diff --git a/docs/img/dist.png b/docs/img/dist.png
new file mode 100644
index 0000000..5c5a58e
Binary files /dev/null and b/docs/img/dist.png differ
diff --git a/docs/img/dist_2.png b/docs/img/dist_2.png
new file mode 100644
index 0000000..2c64daa
Binary files /dev/null and b/docs/img/dist_2.png differ
diff --git a/docs/img/frame_rate.png b/docs/img/frame_rate.png
new file mode 100644
index 0000000..e714959
Binary files /dev/null and b/docs/img/frame_rate.png differ
diff --git a/docs/img/scale_1.png b/docs/img/scale_1.png
new file mode 100644
index 0000000..fddee84
Binary files /dev/null and b/docs/img/scale_1.png differ
diff --git a/docs/img/scale_2.png b/docs/img/scale_2.png
new file mode 100644
index 0000000..fffe299
Binary files /dev/null and b/docs/img/scale_2.png differ
diff --git a/docs/img/translate.png b/docs/img/translate.png
new file mode 100644
index 0000000..b3a74b8
Binary files /dev/null and b/docs/img/translate.png differ
diff --git a/docs/index.md b/docs/index.md
index 1a9d138..335b753 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -102,7 +102,7 @@ def setup():
size(200, 200) # You can change 200, 200 to any integers
```
-You can also use the draw() function, which will execute the code constantly that is inside it. This makes it ideal for things like animation, and any code that will update itself over time. **Most of the time this will be the setup you want**:
+You can also use the draw() function, which will execute the code constantly that is inside it. The draw function executes 30 times per second. This makes it ideal for things like animation, and any code that will update itself over time. **Most of the time this will be the setup you want**:
```python
%%ignite
diff --git a/docs/utilities.md b/docs/utilities.md
index d523224..1bcefdd 100644
--- a/docs/utilities.md
+++ b/docs/utilities.md
@@ -56,7 +56,71 @@ Results in:
![random demo](img/randint.png)
+### Distance between two points (x1, y1) and (x2, y2)
+![dist explanation](img/dist.png)
+
+To find the distance between two points (x1, y1) and (x2, y2), use the following command:
+
+```python
+dist(x1, y1, x2, y2)
+```
+
+**Parameters**
+
+- x1: (float) The x-coordinate of the first point
+- y1: (float) The y-coordinate of the first point
+- x2: (float) The x-coordinate of the second point
+- y2: (float) The y-coordinate of the second point
+
+**Example(s):**
+
+*Print the distance between (125, 125) and (375, 375)*
+
+```python hl_lines="4"
+%%ignite
+
+def setup():
+ print(dist(125, 125, 375, 375))
+```
+
+Results in:
+
+![dist demo](img/dist_2.png)
+
+### Translate
+
+Change the origin of the canvas.
+
+Usage:
+
+```python
+translate(x, y)
+```
+**Parameters**
+
+- x: (float) The horizontal distance to translate the canvas.
+- y: (float) The vertical distance to translate the canvas.
+
+**Example(s):**
+
+*Translate the canvas 50 units right and 75 units down*
+
+```python hl_lines="8"
+%%ignite
+
+def setup():
+ size(400, 400)
+ fill_style("red")
+
+ # move canvas 50 units right, and 75 units down
+ translate(50, 75)
+ circle(0, 0, 100)
+```
+
+Results in:
+
+![translate demo](img/translate.png)
### Rotation
@@ -64,7 +128,7 @@ Results in:
Transformations are always done to the **canvas**, not the individual shapes themselves. Rotation is done around the origin, point (0, 0) and affects all shapes drawn afterwards. You can use our built-in `pi` variable to express radians, or convert from degrees to radians by multiplying your number of degrees by `pi / 180`.
-Note that canvas transformations are not removed automatically. In other words, if you want to rotate just one shape in your `draw()` function, you should rotate the canvas by `r` radians, draw your shape, and then rotate by `-r` radians to undo the effect.
+Note that canvas transformations are not removed automatically. In other words, if you want to rotate just one shape in your `draw()` function, you should rotate the canvas by `r` radians, draw your shape, and then rotate by `-r` radians to undo the effect. Also note that you can rotate on a point other than the origin by first calling `translate` to change the origin to the new point.
To rotate the canvas clockwise around the origin, use:
@@ -92,4 +156,112 @@ def setup():
Results in:
-![rotate demo](img/rotate.png)
\ No newline at end of file
+![rotate demo](img/rotate.png)
+
+### Scale
+
+Scales the canvas. Note that scaling applies to the canvas, not to individual shapes. You can scale on a point other than the origin by first calling `translate` to change the origin to the new point.
+
+There are two ways to use scale:
+
+| Method | Description | Syntax |
+| -------------------------------- | -----------------------------------------------------------------------------|-----------------|
+|[1 float](#scale-with-one-float) | Scale canvas width and height by some amount, i.e. 1.5 | scale(1.5) |
+|[2 floats](#scale-with-two-floats)| Scale canvas width by first number and height by second number, i.e. 2.5, 3.5| scale(2.5, 3.5) |
+
+#### Scale with one float
+
+```python
+scale(n)
+```
+**Parameters**
+
+- n: (float) The amount to scale the height and width of the canvas.
+
+**Example(s):**
+
+*Double height and width of canvas using scale*
+
+```python hl_lines="8"
+%%ignite
+
+def setup():
+ size(400, 400)
+ fill_style("red")
+
+ # apply scale of 2, this will scale canvas units by factor of 2 horizontally and vertically
+ scale(2)
+ circle(100, 100, 100)
+```
+
+Results in:
+
+![scale demo](img/scale_1.png)
+
+#### Scale with two floats
+
+```python
+scale(x, y)
+```
+**Parameters**
+
+- x: (float) The amount to scale the width of the canvas.
+- y: (float) The amount to scale the height of the canvas.
+
+**Example(s):**
+
+*Scale canvas width by 0.75 and canvas height by 1.25*
+
+```python hl_lines="8"
+%%ignite
+
+def setup():
+ size(400, 400)
+ fill_style("red")
+
+ # apply scale of (0.75, 1.25), this will scale canvas units by factor of 0.75 horizontally and 1.25 vertically
+ scale(0.75, 1.25)
+ circle(100, 100, 100)
+```
+
+Results in:
+![scale demo](img/scale_2.png)
+
+
+### Accessing the canvas frame rate
+
+The frame rate of the canvas can be accessed through the built-in variable
+
+```python
+FRAME_RATE
+```
+
+The value of FRAME_RATE is set to 30 by default, and should not be changed by the user. Changing this manually will not change the actual frame rate, and will likely result in errors.
+
+**Example:**
+
+```python
+%%ignite
+
+def setup():
+ print(FRAME_RATE)
+```
+
+Results in:
+
+![FRAME_RATE demo](img/frame_rate.png)
+
+The use-cases of this of this variable are fairly limited, but can be used for example to set a speed variable in terms of the frame rate. For example:
+
+```python
+x = 10
+speed = 300/FRAME_RATE
+
+def draw():
+ global x, speed
+ circle(x, 100, 50)
+ x += speed
+```
+will result in the circle moving across the screen at 300 pixels per second.
+
+
diff --git a/setup.py b/setup.py
index 7a86262..bb9da52 100644
--- a/setup.py
+++ b/setup.py
@@ -5,7 +5,7 @@
setuptools.setup(
name="schulich-ignite",
- version="0.1.2",
+ version="0.1.3",
author="Schulich Ignite",
author_email="info@shulichignite.com",
description="Spark library for Shulich Ignite sessions",
diff --git a/spark/core.py b/spark/core.py
index 46ba78b..18cf942 100644
--- a/spark/core.py
+++ b/spark/core.py
@@ -139,6 +139,12 @@ def height(self, val):
self._globals_dict["height"] = val
self.canvas.height = val
+ @property
+ @ignite_global
+ def FRAME_RATE(self):
+ return FRAME_RATE
+
+
### Library init ###
# Updates last activity time
@@ -331,8 +337,14 @@ def clear(self, *args): pass
@extern
def background(self, *args): pass
+ @extern
+ def translate(self, *args): pass
+
@extern
def rotate(self, *args): pass
+
+ @extern
+ def scale(self, *args): pass
# From util.helper_functions.rect_functions
@@ -463,3 +475,6 @@ def collided(self, *args): pass
@extern
def axis_overlapped(self, *args): pass
+
+ @extern
+ def dist(self, *args): pass
diff --git a/spark/util/helper_functions/canvas_functions.py b/spark/util/helper_functions/canvas_functions.py
index ceb6c17..ad7b15b 100644
--- a/spark/util/helper_functions/canvas_functions.py
+++ b/spark/util/helper_functions/canvas_functions.py
@@ -40,3 +40,13 @@ def helper_background(self, *args):
@ignite_global
def helper_rotate(self, *args):
self.canvas.rotate(args[0])
+
+@validate_args([Real, Real])
+@ignite_global
+def helper_translate(self, *args):
+ self.canvas.translate(args[0], args[1])
+
+@validate_args([Real], [Real, Real])
+@ignite_global
+def helper_scale(self, *args):
+ self.canvas.scale(*args)
diff --git a/spark/util/helper_functions/misc_functions.py b/spark/util/helper_functions/misc_functions.py
index 92b5f9e..4d02b30 100644
--- a/spark/util/helper_functions/misc_functions.py
+++ b/spark/util/helper_functions/misc_functions.py
@@ -4,6 +4,7 @@
from ..Errors import *
from numbers import Real
from math import pi
+from math import sqrt
import random
@@ -131,3 +132,10 @@ def helper_axis_overlapped(self, *args):
return point1 + length1 >= point2 and point2 + length2 >= point1
else:
return point1 + length1 > point2 and point2 + length2 > point1
+
+@validate_args([Real, Real, Real, Real])
+@ignite_global
+def helper_dist(self, *args):
+ x1, y1, x2, y2 = args[:4]
+ return sqrt((y2 - y1)**2 + (x2 - x1)**2)
+
diff --git a/test/DistTest.ipynb b/test/DistTest.ipynb
new file mode 100644
index 0000000..5566c9b
--- /dev/null
+++ b/test/DistTest.ipynb
@@ -0,0 +1,278 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "wanted-crown",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import spark\n",
+ "%reload_ext spark"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "european-lewis",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "
\n"
+ ],
+ "text/latex": [
+ "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
+ "Done drawing.\n",
+ "\\end{Verbatim}\n"
+ ],
+ "text/plain": [
+ "Done drawing."
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "67ec2a95eafc4430abe3bcc14f232ec2",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Canvas(height=100, width=100)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "ERROR! Expected distance to be 6 actual value: 5.0\n",
+ "
\n"
+ ],
+ "text/latex": [
+ "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
+ "ERROR! Expected distance to be 6 actual value: 5.0\n",
+ "\\end{Verbatim}\n"
+ ],
+ "text/plain": [
+ "ERROR! Expected distance to be 6 actual value: 5.0"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "%%ignite\n",
+ "\n",
+ "def setup():\n",
+ " \n",
+ " # defining x and y coordinate for first point\n",
+ " x1 = 1\n",
+ " y1 = 2\n",
+ " \n",
+ " # defining x and y coordinates for second point\n",
+ " x2 = 4\n",
+ " y2 = 6\n",
+ " \n",
+ " # the distance between (1,2) and (4,6) is 5\n",
+ " expected_value = 5\n",
+ " \n",
+ " # use dist function to calculate distance between the points (x1, y1) and (x2, y2) \n",
+ " actual_value = dist(x1, y1, x2, y2)\n",
+ " \n",
+ " if abs(expected_value - actual_value) > 0.001: # Floating point comparison\n",
+ " print(\"ERROR! Expected distance to be\", expected_value, \"actual value: \", actual_value)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "surprised-increase",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "commercial-toolbox",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.8.6"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/test/FrameRateTest.ipynb b/test/FrameRateTest.ipynb
new file mode 100644
index 0000000..bd52172
--- /dev/null
+++ b/test/FrameRateTest.ipynb
@@ -0,0 +1,512 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "turned-warrior",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import spark\r\n",
+ "%reload_ext spark\r\n",
+ "\r\n",
+ "# Unit test for FRAME_RATE"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "id": "commercial-islam",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n"
+ ],
+ "text/latex": [
+ "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
+ "\\PY{err}{S}\\PY{err}{t}\\PY{err}{o}\\PY{err}{p}\\PY{err}{p}\\PY{err}{e}\\PY{err}{d}\n",
+ "\\end{Verbatim}\n"
+ ],
+ "text/plain": [
+ "Stopped"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "e90b48a28d754b98a473c7ceef8ca21e",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Button(description='Stop', style=ButtonStyle())"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "840a907740a1451cb8e72795767c686e",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Canvas(height=100, width=100)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n"
+ ],
+ "text/latex": [
+ "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
+ "\\PY{err}{f}\\PY{err}{r}\\PY{err}{a}\\PY{err}{m}\\PY{err}{e}\\PY{err}{ }\\PY{err}{r}\\PY{err}{a}\\PY{err}{t}\\PY{err}{e}\\PY{err}{:}\\PY{err}{ }\\PY{err}{3}\\PY{err}{0}\n",
+ "\\end{Verbatim}\n"
+ ],
+ "text/plain": [
+ "frame rate: 30"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "%%ignite\n",
+ "\n",
+ "# The FRAME_RATE variable is accessible to the user\n",
+ "# It's value should not be changed.\n",
+ "\n",
+ "def setup():\n",
+ " size(200, 100)\n",
+ " background(\"light blue\")\n",
+ " print(\"frame rate:\", FRAME_RATE)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 19,
+ "id": "norwegian-estonia",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n"
+ ],
+ "text/latex": [
+ "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
+ "\\PY{err}{S}\\PY{err}{t}\\PY{err}{o}\\PY{err}{p}\\PY{err}{p}\\PY{err}{e}\\PY{err}{d}\n",
+ "\\end{Verbatim}\n"
+ ],
+ "text/plain": [
+ "Stopped"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "7ccab1ce0b2b4ef8ab1db8ea85bfa5e7",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Button(description='Stop', style=ButtonStyle())"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "d4a8b0faf6a54cf995b9fc7b6ecd7c49",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Canvas(height=100, width=100)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n"
+ ],
+ "text/latex": [
+ "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
+ "\\PY{err}{f}\\PY{err}{r}\\PY{err}{a}\\PY{err}{m}\\PY{err}{e}\\PY{err}{ }\\PY{err}{r}\\PY{err}{a}\\PY{err}{t}\\PY{err}{e}\\PY{err}{:}\\PY{err}{ }\\PY{err}{3}\\PY{err}{0}\n",
+ "\\end{Verbatim}\n"
+ ],
+ "text/plain": [
+ "frame rate: 30"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "%%ignite\n",
+ "\n",
+ "# An example use-case is to set speeds in pixels/second using FRAME_RATE\n",
+ "\n",
+ "def setup():\n",
+ " size(500, 300)\n",
+ " background(\"light blue\")\n",
+ " print(\"frame rate:\", FRAME_RATE)\n",
+ "\n",
+ "x = 0\n",
+ "speed = 250/FRAME_RATE # this speed will be 200 pixels/second\n",
+ "\n",
+ "def draw():\n",
+ " background(\"light blue\")\n",
+ " global x, speed\n",
+ " circle(x, 50, 30)\n",
+ " x += speed"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "married-fabric",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.9.1"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/test/ScaleTest.ipynb b/test/ScaleTest.ipynb
new file mode 100644
index 0000000..0121178
--- /dev/null
+++ b/test/ScaleTest.ipynb
@@ -0,0 +1,1751 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "intimate-crest",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import spark\n",
+ "%reload_ext spark"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 30,
+ "id": "original-donna",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n"
+ ],
+ "text/latex": [
+ "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
+ "Done drawing.\n",
+ "\\end{Verbatim}\n"
+ ],
+ "text/plain": [
+ "Done drawing."
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "36adef58bab442ceb9792fd10e871a30",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Canvas(height=100, width=100)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n"
+ ],
+ "text/latex": [
+ "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
+ "\n",
+ "\\end{Verbatim}\n"
+ ],
+ "text/plain": []
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "%%ignite\n",
+ "def setup():\n",
+ " size(400, 400)\n",
+ " circle(100, 100, 100)\n",
+ " fill_style(\"red\")\n",
+ " \n",
+ " # apply scale of 1, should not change anything\n",
+ " scale(1)\n",
+ " circle(100, 100, 100)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 31,
+ "id": "temporal-caution",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n"
+ ],
+ "text/latex": [
+ "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
+ "Done drawing.\n",
+ "\\end{Verbatim}\n"
+ ],
+ "text/plain": [
+ "Done drawing."
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "482847c670a44454a5d53c09d81c082b",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Canvas(height=100, width=100)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n"
+ ],
+ "text/latex": [
+ "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
+ "\n",
+ "\\end{Verbatim}\n"
+ ],
+ "text/plain": []
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "%%ignite\n",
+ "def setup():\n",
+ " size(400, 400)\n",
+ " circle(100, 100, 100)\n",
+ " fill_style(\"red\")\n",
+ " \n",
+ " # apply scale of 2, this will scale canvas units by factor of 2 horizontally and vertically\n",
+ " scale(2)\n",
+ " circle(100, 100, 100)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 32,
+ "id": "rotary-insert",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n"
+ ],
+ "text/latex": [
+ "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
+ "Done drawing.\n",
+ "\\end{Verbatim}\n"
+ ],
+ "text/plain": [
+ "Done drawing."
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "92ba410863a84bcab3483e90b7430cea",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Canvas(height=100, width=100)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n"
+ ],
+ "text/latex": [
+ "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
+ "\n",
+ "\\end{Verbatim}\n"
+ ],
+ "text/plain": []
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "%%ignite\n",
+ "def setup():\n",
+ " size(400, 400)\n",
+ " circle(100, 100, 100)\n",
+ " fill_style(\"red\")\n",
+ " \n",
+ " # apply scale of 0.5, this will scale canvas units by factor of 0.5 horizontally and vertically\n",
+ " scale(0.5)\n",
+ " circle(100, 100, 100)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 33,
+ "id": "collectible-hacker",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n"
+ ],
+ "text/latex": [
+ "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
+ "Done drawing.\n",
+ "\\end{Verbatim}\n"
+ ],
+ "text/plain": [
+ "Done drawing."
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "c6bfbc56c2ab44af9c9c35df77a95004",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Canvas(height=100, width=100)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n"
+ ],
+ "text/latex": [
+ "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
+ "\n",
+ "\\end{Verbatim}\n"
+ ],
+ "text/plain": []
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "%%ignite\n",
+ "def setup():\n",
+ " size(400, 400)\n",
+ " circle(100, 100, 100)\n",
+ " fill_style(\"red\")\n",
+ " \n",
+ " # apply scale of (1, 3), this will scale canvas units by factor of 3 vertically\n",
+ " scale(1, 3)\n",
+ " circle(100, 100, 100)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 34,
+ "id": "covered-interest",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n"
+ ],
+ "text/latex": [
+ "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
+ "Done drawing.\n",
+ "\\end{Verbatim}\n"
+ ],
+ "text/plain": [
+ "Done drawing."
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "7743615c75c944be8c29d0ff5a3c82e8",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Canvas(height=100, width=100)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n"
+ ],
+ "text/latex": [
+ "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
+ "\n",
+ "\\end{Verbatim}\n"
+ ],
+ "text/plain": []
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "%%ignite\n",
+ "def setup():\n",
+ " size(400, 400)\n",
+ " circle(100, 100, 100)\n",
+ " fill_style(\"red\")\n",
+ " \n",
+ " # apply scale of (3, 1), this will scale canvas units by factor of 3 horizontally\n",
+ " scale(3, 1)\n",
+ " circle(100, 100, 100)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 35,
+ "id": "variable-waste",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n"
+ ],
+ "text/latex": [
+ "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
+ "Done drawing.\n",
+ "\\end{Verbatim}\n"
+ ],
+ "text/plain": [
+ "Done drawing."
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "83cbb21bd81c482e90dc34e8da50f28d",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Canvas(height=100, width=100)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n"
+ ],
+ "text/latex": [
+ "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
+ "\n",
+ "\\end{Verbatim}\n"
+ ],
+ "text/plain": []
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "%%ignite\n",
+ "def setup():\n",
+ " size(400, 400)\n",
+ " circle(100, 100, 100)\n",
+ " fill_style(\"red\")\n",
+ " \n",
+ " # apply scale of (0.75, 1.25), this will scale canvas units by factor of 0.75 horizontally and 1.25 vertically\n",
+ " scale(0.75, 1.25)\n",
+ " circle(100, 100, 100)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "id": "perfect-carry",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n"
+ ],
+ "text/latex": [
+ "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
+ "Done drawing.\n",
+ "\\end{Verbatim}\n"
+ ],
+ "text/plain": [
+ "Done drawing."
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "0214b3ea53534ec895bd658b5661edfd",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Canvas(height=100, width=100)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n"
+ ],
+ "text/latex": [
+ "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
+ "\n",
+ "\\end{Verbatim}\n"
+ ],
+ "text/plain": []
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "%%ignite\n",
+ "def setup():\n",
+ " size(400, 400)\n",
+ " circle(100, 100, 100)\n",
+ " fill_style(\"red\")\n",
+ " \n",
+ " # apply scale of (0, 1.25), meaning the red circle will have no width\n",
+ " scale(0, 1.25)\n",
+ " circle(100, 100, 100)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 19,
+ "id": "metropolitan-prophet",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n"
+ ],
+ "text/latex": [
+ "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
+ "Done drawing.\n",
+ "\\end{Verbatim}\n"
+ ],
+ "text/plain": [
+ "Done drawing."
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "261976be66d64d97a30ca0884e3cc593",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Canvas(height=100, width=100)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n"
+ ],
+ "text/latex": [
+ "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
+ "\n",
+ "\\end{Verbatim}\n"
+ ],
+ "text/plain": []
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "%%ignite\n",
+ "def setup():\n",
+ " size(400, 400)\n",
+ " fill_style(\"red\")\n",
+ " \n",
+ " # apply scale of (-0.75, 1.25)\n",
+ " scale(-0.75, 1.25)\n",
+ " \n",
+ " # translate to be able to see negative x value locations\n",
+ " translate(-200, 0)\n",
+ " \n",
+ " circle(100, 100, 100)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "unsigned-record",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.8.6"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/test/TranslateTest.ipynb b/test/TranslateTest.ipynb
new file mode 100644
index 0000000..986cded
--- /dev/null
+++ b/test/TranslateTest.ipynb
@@ -0,0 +1,1109 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "legendary-cyprus",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import spark\n",
+ "%reload_ext spark"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "id": "invalid-banks",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n"
+ ],
+ "text/latex": [
+ "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
+ "Done drawing.\n",
+ "\\end{Verbatim}\n"
+ ],
+ "text/plain": [
+ "Done drawing."
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "fea9cdb438cd449284a7a42f94771d9b",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Canvas(height=100, width=100)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n"
+ ],
+ "text/latex": [
+ "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
+ "\n",
+ "\\end{Verbatim}\n"
+ ],
+ "text/plain": []
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "%%ignite\n",
+ "def setup():\n",
+ " size(400, 400)\n",
+ " circle(100, 100, 100)\n",
+ " fill_style(\"red\")\n",
+ " \n",
+ " # move canvas 50 units right, and 75 units down\n",
+ " translate(50, 75)\n",
+ " circle(100, 100, 100)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "brown-shadow",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n"
+ ],
+ "text/latex": [
+ "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
+ "Done drawing.\n",
+ "\\end{Verbatim}\n"
+ ],
+ "text/plain": [
+ "Done drawing."
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "31c3b1fd61914814bee2e5b5e90586e6",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Canvas(height=100, width=100)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n"
+ ],
+ "text/latex": [
+ "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
+ "\n",
+ "\\end{Verbatim}\n"
+ ],
+ "text/plain": []
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "%%ignite\n",
+ "def setup():\n",
+ " size(400, 400)\n",
+ " circle(100, 100, 100)\n",
+ " fill_style(\"red\")\n",
+ " \n",
+ " # move by 0 units on the x-axis and 0 units on the y-axis --- red circle should overlap with black circle\n",
+ " translate(0, 0)\n",
+ " circle(100, 100, 100)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "id": "quarterly-discretion",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n"
+ ],
+ "text/latex": [
+ "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
+ "Done drawing.\n",
+ "\\end{Verbatim}\n"
+ ],
+ "text/plain": [
+ "Done drawing."
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "a5aa3bbeb47f406caa87f80e858cb20a",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Canvas(height=100, width=100)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n"
+ ],
+ "text/latex": [
+ "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
+ "\n",
+ "\\end{Verbatim}\n"
+ ],
+ "text/plain": []
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "%%ignite\n",
+ "def setup():\n",
+ " size(400, 400)\n",
+ " circle(100, 100, 100)\n",
+ " fill_style(\"red\")\n",
+ " \n",
+ " # move canvas 25 units left, and 10 units up\n",
+ " translate(-25, -10)\n",
+ " circle(100, 100, 100)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 14,
+ "id": "african-orbit",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n"
+ ],
+ "text/latex": [
+ "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
+ "Done drawing.\n",
+ "\\end{Verbatim}\n"
+ ],
+ "text/plain": [
+ "Done drawing."
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "e56d236f558345eba65586f98b4452ff",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Canvas(height=100, width=100)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n"
+ ],
+ "text/latex": [
+ "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
+ "\n",
+ "\\end{Verbatim}\n"
+ ],
+ "text/plain": []
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "%%ignite\n",
+ "def setup():\n",
+ " size(400, 400)\n",
+ " circle(100, 100, 100)\n",
+ " fill_style(\"red\")\n",
+ " \n",
+ " # move canvas 30 units right, and 60 units up\n",
+ " translate(30, -60)\n",
+ " circle(100, 100, 100)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "thick-dance",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n"
+ ],
+ "text/latex": [
+ "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
+ "Done drawing.\n",
+ "\\end{Verbatim}\n"
+ ],
+ "text/plain": [
+ "Done drawing."
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "c27d788da0564689bf923f301bd4c2cd",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Canvas(height=100, width=100)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n"
+ ],
+ "text/latex": [
+ "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
+ "\n",
+ "\\end{Verbatim}\n"
+ ],
+ "text/plain": []
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "%%ignite\n",
+ "def setup():\n",
+ " size(400, 400)\n",
+ " circle(100, 100, 100)\n",
+ " fill_style(\"red\")\n",
+ " \n",
+ " # move canvas 50.5 units left, and 80.5 units down\n",
+ " translate(-50.5, 80.5)\n",
+ " circle(100, 100, 100)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "encouraging-bones",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.8.6"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}