Skip to content

Commit

Permalink
Misc fixes and additions! (#63)
Browse files Browse the repository at this point in the history
  • Loading branch information
marcovicci committed Dec 30, 2022
1 parent 1d38c53 commit 88bfa4c
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@
"id": "dddc9f3d",
"metadata": {},
"source": [
"You might save this file as *amoeba.py*, since its only purpose will be defining the Amoeba class. That strange looking method, `__init__()`, is automatically called when the amoeba is actually created.\n",
"You might save this file as *`amoeba.py`*, since its only purpose will be defining the Amoeba class. That strange looking method, `__init__()`, is automatically called when the amoeba is actually created.\n",
"\n",
"We'll also be creating a sketch for everything else we're planning on doing, like setting up a background color and spawning our amoebas. I've named mine *microscope.py*, since the experience will be not unlike looking into a microscope focused on a slide. Either way, the very first thing I'll be doing is importing the Amoeba class I've just created (and put in a file called amoeba.py). \n",
"We'll also be creating a sketch for everything else we're planning on doing, like setting up a background color and spawning our amoebas. I've named mine *`microscope.py`*, since the experience will be not unlike looking into a microscope focused on a slide. Either way, the very first thing I'll be doing is importing the Amoeba class I've just created (and put in a file called *`amoeba.py`*). \n",
"\n",
"Next, we actually want to create an amoeba *object* from this class we defined. Since it's meant to represent a living thing (even a single-celled living thing), why not give this individual amoeba a name?"
]
Expand Down Expand Up @@ -138,15 +138,15 @@
"id": "40efdc98",
"metadata": {},
"source": [
"No matter how you choose to format it, running the all-in-one code or your *microscope.py* file will print the line \"amoeba initialized\" to the console. We can't see it yet, but py5 has created a new amoeba object, which is of course based on the class we defined. To get some visual output associated with our amoeba, we're going to need to give it some attributes. \n",
"No matter how you choose to format it, running the all-in-one code or your *`microscope.py`* file will print the line \"amoeba initialized\" to the console. We can't see it yet, but py5 has created a new amoeba object, which is of course based on the class we defined. To get some visual output associated with our amoeba, we're going to need to give it some attributes. \n",
"\n",
"As discussed in the tutorial for creating your own functions, most functions (including methods) will have *parameters* defined when you create them, which correspond to *arguments* you provide whenever you use that function. Right now, when the amoeba is initialized and `__init__()` is run, it only has a single possible parameter, `self`. This parameter is used to store everything associated with a specific amoeba, like Bob, rather than amoebas as a class. Let's add a few more parameters into `__init__()`, and then pass them as arguments when we create Bob. \n",
"\n",
"First, we'll actually add those parameters to `__init__()`. Inside of the method, we'll take them and make sure they're applied to some *attributes* of `self`, in this case Bob. Once we've given Bob an attribute like `self.x`, we'll be able to reference it with `bob.x` and get that value back.\n",
"\n",
"Here's where things will start to get a bit more visual. We'll also add `setup()` and `draw()` into our sketch so that we can see the amoeba. If you'll recall from other tutorials, `setup()` runs once at the start of the sketch, and `draw()` runs every frame. \n",
"\n",
"(The three sections below will correspond to amoeba.py, microscope.py, and an all-in-one file. Use whichever setup you prefer.)"
"(The three sections below will correspond to *`amoeba.py`*, *`microscope.py`*, and an all-in-one file. Use whichever setup you prefer.)"
]
},
{
Expand Down Expand Up @@ -576,7 +576,7 @@
"source": [
"There's one more change we'll have to make before we start letting our amoebas run around the screen. In the real world, an amoeba is not perfectly circular -- its surface ripples and distorts like a water balloon. We'll be replacing our `circle()` function with a series of Bezier curves to draw a wobbly amoeba. To stop us from having to calculate these points manually, we'll also be adding a new method to do a bit of that math for us. \n",
"\n",
"This new `circle_point()` method will go inside our `Amoeba` class, and use the radius of the amoeba, plus a bit of clever trigonometry, to find us the right x and y positions. By passing it an argument based on the current frame count in our sketch, we'll get an amoeba that ripples and wiggles as time passes. You'll only need to modify your *amoeba.py* file (or the methods inside of the `Amoeba` class, if you're using a single file) to see the changes. \n",
"This new `circle_point()` method will go inside our `Amoeba` class, and use the radius of the amoeba, plus a bit of clever trigonometry, to find us the right x and y positions. By passing it an argument based on the current frame count in our sketch, we'll get an amoeba that ripples and wiggles as time passes. You'll only need to modify your *`amoeba.py`* file (or the methods inside of the `Amoeba` class, if you're using a single file) to see the changes. \n",
"\n",
"One important thing to note: below, when we use `frame_count` to get the current number of elapsed frames, we actually write `cs.frame_count` because we've defined `cs` as the *current sketch* at the top of the window. If you're working in a single file, omit this `cs.` reference."
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ class Amoeba():
print('amoeba initialized')
```

You might save this file as *amoeba.py*, since its only purpose will be defining the Amoeba class. That strange looking method, `__init__()`, is automatically called when the amoeba is actually created.
You might save this file as *`amoeba.py`*, since its only purpose will be defining the Amoeba class. That strange looking method, `__init__()`, is automatically called when the amoeba is actually created.

We'll also be creating a sketch for everything else we're planning on doing, like setting up a background color and spawning our amoebas. I've named mine *microscope.py*, since the experience will be not unlike looking into a microscope focused on a slide. Either way, the very first thing I'll be doing is importing the Amoeba class I've just created (and put in a file called amoeba.py).
We'll also be creating a sketch for everything else we're planning on doing, like setting up a background color and spawning our amoebas. I've named mine *`microscope.py`*, since the experience will be not unlike looking into a microscope focused on a slide. Either way, the very first thing I'll be doing is importing the Amoeba class I've just created (and put in a file called *`amoeba.py`*).

Next, we actually want to create an amoeba *object* from this class we defined. Since it's meant to represent a living thing (even a single-celled living thing), why not give this individual amoeba a name?

Expand All @@ -89,15 +89,15 @@ class Amoeba():
bob = Amoeba()
```

No matter how you choose to format it, running the all-in-one code or your *microscope.py* file will print the line "amoeba initialized" to the console. We can't see it yet, but py5 has created a new amoeba object, which is of course based on the class we defined. To get some visual output associated with our amoeba, we're going to need to give it some attributes.
No matter how you choose to format it, running the all-in-one code or your *`microscope.py`* file will print the line "amoeba initialized" to the console. We can't see it yet, but py5 has created a new amoeba object, which is of course based on the class we defined. To get some visual output associated with our amoeba, we're going to need to give it some attributes.

As discussed in the tutorial for creating your own functions, most functions (including methods) will have *parameters* defined when you create them, which correspond to *arguments* you provide whenever you use that function. Right now, when the amoeba is initialized and `__init__()` is run, it only has a single possible parameter, `self`. This parameter is used to store everything associated with a specific amoeba, like Bob, rather than amoebas as a class. Let's add a few more parameters into `__init__()`, and then pass them as arguments when we create Bob.

First, we'll actually add those parameters to `__init__()`. Inside of the method, we'll take them and make sure they're applied to some *attributes* of `self`, in this case Bob. Once we've given Bob an attribute like `self.x`, we'll be able to reference it with `bob.x` and get that value back.

Here's where things will start to get a bit more visual. We'll also add `setup()` and `draw()` into our sketch so that we can see the amoeba. If you'll recall from other tutorials, `setup()` runs once at the start of the sketch, and `draw()` runs every frame.

(The three sections below will correspond to amoeba.py, microscope.py, and an all-in-one file. Use whichever setup you prefer.)
(The three sections below will correspond to *`amoeba.py`*, *`microscope.py`*, and an all-in-one file. Use whichever setup you prefer.)

```{code-cell} ipython3
# amoeba.py
Expand Down Expand Up @@ -431,7 +431,7 @@ def draw():

There's one more change we'll have to make before we start letting our amoebas run around the screen. In the real world, an amoeba is not perfectly circular -- its surface ripples and distorts like a water balloon. We'll be replacing our `circle()` function with a series of Bezier curves to draw a wobbly amoeba. To stop us from having to calculate these points manually, we'll also be adding a new method to do a bit of that math for us.

This new `circle_point()` method will go inside our `Amoeba` class, and use the radius of the amoeba, plus a bit of clever trigonometry, to find us the right x and y positions. By passing it an argument based on the current frame count in our sketch, we'll get an amoeba that ripples and wiggles as time passes. You'll only need to modify your *amoeba.py* file (or the methods inside of the `Amoeba` class, if you're using a single file) to see the changes.
This new `circle_point()` method will go inside our `Amoeba` class, and use the radius of the amoeba, plus a bit of clever trigonometry, to find us the right x and y positions. By passing it an argument based on the current frame count in our sketch, we'll get an amoeba that ripples and wiggles as time passes. You'll only need to modify your *`amoeba.py`* file (or the methods inside of the `Amoeba` class, if you're using a single file) to see the changes.

One important thing to note: below, when we use `frame_count` to get the current number of elapsed frames, we actually write `cs.frame_count` because we've defined `cs` as the *current sketch* at the top of the window. If you're working in a single file, omit this `cs.` reference.

Expand Down
6 changes: 6 additions & 0 deletions tutorials/intro_to_py5_and_python_20_3d.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@
"\n",
"Before we draw anything, or even change the renderer to P3D, we need to talk about how we position objects in 3D space. First, we'll have to look beyond the `x, y` positioning system, since it only accounts for two dimensions. In a 3D space, we'll be using `x, y, z` positioning to place objects. The Z axis is our missing third dimension. A negative Z value will move a 3D object \"farther away\" from the viewer, and a positive Z value will move it \"closer\" to the viewer. \n",
"\n",
"It's important to note that this system is not universal! The way that the Z axis works in py5 is not, for example, the way that it works in the interface OpenGL. py5 is a \"left-handed\" coordinate system, and OpenGL is \"right-handed\". What does this mean? If you use your right hand, then point your index finger along the Y axis (upwards) and your thumb along the X axis, then bend your middle finger, it will be pointing along the Z axis, towards a \"positive\" value for a right-handed system. For a left-handed system, you can do the same thing with your left hand. The right-hand rule is even depicted on one of the banknotes for the Swiss franc:\n",
"\n",
"<img src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/c/c0/CHF_200_9_front.jpg/277px-CHF_200_9_front.jpg\">\n",
"\n",
"*Front of the Swiss 200-franc banknote, ninth series (issued in 2018), from [Wikimedia Commons](https://commons.wikimedia.org/wiki/File:CHF_200_9_front.jpg)*\n",
"\n",
"However, we also need to address the expectations you may have on *how* you can position these objects in 3D space. When drawing a 2D object, like a `rect()`, you typically pass it arguments to position it, as well as to size it.\n",
"\n",
"```\n",
Expand Down
6 changes: 6 additions & 0 deletions tutorials/intro_to_py5_and_python_20_3d.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ The P3D renderer (Processing 3D) is a three-dimensional graphics renderer that m

Before we draw anything, or even change the renderer to P3D, we need to talk about how we position objects in 3D space. First, we'll have to look beyond the `x, y` positioning system, since it only accounts for two dimensions. In a 3D space, we'll be using `x, y, z` positioning to place objects. The Z axis is our missing third dimension. A negative Z value will move a 3D object "farther away" from the viewer, and a positive Z value will move it "closer" to the viewer.

It's important to note that this system is not universal! The way that the Z axis works in py5 is not, for example, the way that it works in the interface OpenGL. py5 is a "left-handed" coordinate system, and OpenGL is "right-handed". What does this mean? If you use your right hand, then point your index finger along the Y axis (upwards) and your thumb along the X axis, then bend your middle finger, it will be pointing along the Z axis, towards a "positive" value for a right-handed system. For a left-handed system, you can do the same thing with your left hand. The right-hand rule is even depicted on one of the banknotes for the Swiss franc:

<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/c/c0/CHF_200_9_front.jpg/277px-CHF_200_9_front.jpg">

*Front of the Swiss 200-franc banknote, ninth series (issued in 2018), from [Wikimedia Commons](https://commons.wikimedia.org/wiki/File:CHF_200_9_front.jpg)*

However, we also need to address the expectations you may have on *how* you can position these objects in 3D space. When drawing a 2D object, like a `rect()`, you typically pass it arguments to position it, as well as to size it.

```
Expand Down

0 comments on commit 88bfa4c

Please sign in to comment.