Skip to content

Commit 2ef1b3b

Browse files
committed
updated Coordinates and Transformations tutorial, added illustration, updated examples
1 parent b4901b6 commit 2ef1b3b

File tree

3 files changed

+82
-122
lines changed

3 files changed

+82
-122
lines changed
113 KB
Loading

src/assets/learn/basic3d/rotateExample.js

Lines changed: 8 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ function setup() {
1616

1717
debugMode();
1818

19-
p = document.querySelector('#axisText')
19+
p = document.querySelector('#axisText');
2020
}
2121

2222
function draw() {
@@ -40,8 +40,11 @@ function draw() {
4040

4141
// also added: draw lines along x, y, z axes in rotated space
4242
strokeWeight(4);
43+
stroke('red');
4344
line(0, 0, 0, 100, 0, 0);
45+
stroke('green');
4446
line(0, 0, 0, 0, 100, 0);
47+
stroke('blue');
4548
line(0, 0, 0, 0, 0, 100);
4649

4750
normalMaterial();
@@ -50,59 +53,8 @@ function draw() {
5053

5154
noFill();
5255

53-
p.innerHTML = 'rotateX('+parseFloat(xAxisSlider.value).toFixed(3)+') <br />';
54-
p.innerHTML += 'rotateY('+parseFloat(yAxisSlider.value).toFixed(3)+') <br />';
55-
p.innerHTML += 'rotateZ('+parseFloat(zAxisSlider.value).toFixed(3)+') <br />'
56-
57-
// // draw axes vector
58-
// push();
59-
60-
// /*
61-
// here I should be able to apply a rotation
62-
// that will align the visualization to the rotateAxis
63-
64-
// I can't seem to figure out how calculate the right rotation.
65-
// */
66-
67-
// let a = rotateVector
68-
// let b = createVector(0,-1,0)
69-
// let na = a.copy()
70-
// let nb = b.copy()
71-
72-
// na.normalize()
73-
// nb.normalize()
74-
75-
// let angle = acos(p5.Vector.dot(na,nb))
76-
// let c = p5.Vector.cross(a,b)
77-
78-
// rotate(-angle, c)
79-
80-
// stroke(0);
81-
// strokeWeight(5);
82-
// // line(
83-
// // -100,
84-
// // 0,
85-
// // 0,
86-
// // 100,
87-
// // 0,
88-
// // 0
89-
// // );
90-
91-
// // rotate so that arc is oriented correctly
92-
// // this seems to work correctly
93-
// rotateX(PI / 2);
94-
// stroke(255, 0, 255);
95-
// arc(0, 0, 200, 200, 0, angleSlider.value());
96-
// pop();
97-
98-
// scale(1000);
99-
100-
// line(
101-
// -xAxisSlider.value(),
102-
// -yAxisSlider.value(),
103-
// -zAxisSlider.value(),
104-
// xAxisSlider.value(),
105-
// yAxisSlider.value(),
106-
// zAxisSlider.value()
107-
// );
56+
p.innerHTML = 'angleMode(DEGREES) <br /><br />';
57+
p.innerHTML += 'rotateX('+parseFloat(degrees(xAxisSlider.value)).toFixed(1)+') <br />';
58+
p.innerHTML += 'rotateY('+parseFloat(degrees(yAxisSlider.value)).toFixed(1)+') <br />';
59+
p.innerHTML += 'rotateZ('+parseFloat(degrees(zAxisSlider.value)).toFixed(1)+') <br />'
10860
}

src/templates/pages/learn/getting-started-in-webgl-coords-and-transform.hbs

Lines changed: 74 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@ slug: learn/
1212
.additionalInformation {
1313
width: 100%;
1414
background-color: #dedeff;
15-
font-size: 15px;
15+
font-size: 17px;
1616
padding: 10px;
1717
margin: 30px 0;
1818
}
1919
2020
.toc {
2121
width: 100%;
2222
background-color: #eee;
23-
font-size: 15px;
23+
font-size: 17px;
2424
padding: 10px;
2525
margin: 30px 0;
2626
}
@@ -46,7 +46,7 @@ slug: learn/
4646
<h1>Coordinates and Transformations</h1>
4747

4848
<p>p5.js is a powerful tool for creating 2D graphics but it's also capable of 3D graphics.
49-
Before we can get started in 3D there are some new concepts to learn and this document will introduce some ideas
49+
To get started in 3D there are some new concepts to learn and this document will introduce some ideas
5050
that will be important to any 3D sketch.</p>
5151

5252
<div class="toc">
@@ -63,7 +63,7 @@ slug: learn/
6363

6464
<h2 id="what_is_webgl">What is WebGL</h2>
6565

66-
<p>WebGL is an API that gives us the tools we need to create 3D graphics within a web browser. To put it simply,
66+
<p>WebGL is a library that gives us the tools we need to create 3D graphics within a web browser. To put it simply,
6767
it allows us to do all kinds of math that help arrange and display objects in 3D. p5.js makes it easier to work
6868
with WebGL
6969
through its special WebGL mode.</p>
@@ -78,7 +78,7 @@ slug: learn/
7878
</p>
7979

8080
<p>
81-
Let's get started by setting up the p5.js canvas to use WebGL mode.
81+
Let's get started by setting up the p5.js to use WebGL, by passing a third parameter into <a class="code">createCanvas()</a>.
8282
</p>
8383

8484
<pre><code class="language-javascript">
@@ -96,12 +96,12 @@ slug: learn/
9696

9797
<div class="additionalInformation">
9898
If coordinates systems aren't making sense it might be helpful to revisit the tutorial titled
99-
<a href="{{root}}/learn/coordinate-system-and-shapes.html">Coordinate System and Shapes</a>
99+
<a href="{{root}}/learn/coordinate-system-and-shapes.html">Coordinate System and Shapes</a>.
100100
</div>
101101

102102
<p>One of the most fundamental differences between working in 2D and working in 3D is the most obvious: there is
103103
one more dimension to work with. In addition to the horizontal and vertical position (x and y axes) of an
104-
element in our drawing, 3D adds depth, (the z-axis). </p>
104+
element in our drawing, 3D adds depth, the z-axis. </p>
105105

106106
<p>When drawing in 2D, the point (0,0) is located at the top left corner of the screen. In WebGL mode, the
107107
origin of the sketch (0,0,0) is located in the middle of the screen. By default, the x-axis goes left-to-right,
@@ -126,10 +126,11 @@ slug: learn/
126126
<iframe src="{{assets}}/learn/basic3D/translateExample.html" width="720" height="350">
127127
</iframe>
128128

129-
<p><a class="code" href="{{root}}/reference/#/p5/translate">translate()</a> moves our origin point in a
130-
given direction. Anything drawn after we call translate will be
129+
<p><a class="code" href="{{root}}/reference/#/p5/translate">translate()</a> moves the origin in a
130+
given direction. Anything drawn after we call <a class="code">translate()</a> will be
131131
positioned relative to that point. <a class="code">translate()</a> accepts arguments for x, y, and z
132-
values.</p>
132+
values. Use the sliders in the sketch above to change the translation of the box, and see how it moves along
133+
each axis.</p>
133134

134135
<pre><code class="language-javascript">
135136
...
@@ -151,8 +152,9 @@ slug: learn/
151152
<p>There are a few methods that can be used to rotate an object in 3D. Most of the time it's easiest to call
152153
methods like like <a class="code" href="{{root}}/reference/#/p5/rotateX">rotateX()</a>, <a class="code"
153154
href="{{root}}/reference/#/p5/rotateY">rotateY()</a>, and <a class="code"
154-
href="{{root}}/reference/#/p5/rotateZ">rotateZ()</a>, which allows for rotation around a specific axis.
155-
Each of these methods accept a single argument specifying the angle of rotation.
155+
href="{{root}}/reference/#/p5/rotateZ">rotateZ()</a>, which each allow for rotation around a specific axis.
156+
Each of these methods accept a single argument specifying the angle of rotation. Try moving the sliders in the
157+
example above to see how rotation is performed on each axis.
156158
</p>
157159

158160
<pre><code class="language-javascript">
@@ -165,7 +167,7 @@ slug: learn/
165167
..
166168
</code></pre>
167169

168-
<p>By default p5.js will expect angles to be in radians. Radians use numbers from 0 - TWO_PI to specify an
170+
<p>By default p5.js will expect angles to be in radians. Radians use numbers from 0 - <a class="code">TWO_PI</a> to specify an
169171
angle. To use degrees, either convert degrees to radians using <a class="code">radians()</a>, or use
170172
<a class="code">angleMode(DEGREES)</a>.
171173
</p>
@@ -182,17 +184,19 @@ slug: learn/
182184
..
183185
</code></pre>
184186

185-
<p>You can also use <a class="code" href="{{root}}/reference/#/p5/rotate">rotate()</a>, which allows
186-
you to specify which axis you'd like to rotate around using a vector as the second argument.</p>
187-
188-
<pre><code class="language-javascript">
189-
...
190-
// rotate 90 degrees around the y-axis
191-
let axis = createVector(0,1,0);
192-
rotate(HALF_PI, axis);
193-
box();
194-
..
195-
</code></pre>
187+
<div class="additionalInformation">
188+
<p>You can also use <a class="code" href="{{root}}/reference/#/p5/rotate">rotate()</a>, which allows
189+
you to specify which axis you'd like to rotate around using a vector as the second argument.</p>
190+
191+
{{!-- <pre><code class="language-javascript">
192+
...
193+
// rotate 90 degrees around the y-axis
194+
let axis = createVector(0,1,0);
195+
rotate(HALF_PI, axis);
196+
box();
197+
...
198+
</code></pre> --}}
199+
</div>
196200

197201
<h3>scale(): Size in Space</h3>
198202

@@ -203,14 +207,15 @@ slug: learn/
203207
<p><a class="code" href="{{root}}/reference/#/p5/scale">scale()</a> changes the size of whatever is
204208
drawn after it. Like the other methods described so far, it accepts arguments for x, y, and z values.</p>
205209

206-
<h2 id="order">Order</h2>
210+
<h2 id="order">The Order of Transformations Matters!</h2>
207211

208-
<p>Something that can feel unpredictable at first is the order of transformations. Each transformation can affect
212+
<p>Something that can feel unpredictable at first is the order of transformations. Each transformation always affects
209213
the next one. For example, if <a class="code">rotate()</a> is called, followed by <a class="code">translate()</a>, the direction of that translation will
210214
be affected by the rotation. The entire coordinate system is rotating and moving, not just the shape itself.
211215
</p>
212216

213-
<p>Transformations can be performed in any order, but using <strong>translate</strong>, <strong>rotate</strong>, and then <strong>scale</strong> will be the most intuitive.</p>
217+
<p>Transformations can be performed in any order, but using <strong>translate</strong>, <strong>rotate</strong>, and then <strong>scale</strong> will be the most intuitive.
218+
Translation, followed by rotation, produces the effect of moving the shape <em>and then</em> rotating around that new location.</p>
214219

215220
<p>In the below example, try changing the order of <a class="code">translate()</a> and <a
216221
class="code">rotateY()</a> and see how it affects where the object is
@@ -245,7 +250,9 @@ function draw(){
245250
class="code">push()</a> and
246251
<a class="code">pop()</a>, you have to keep track of whatever transformations have already taken place, which
247252
can get complicated
248-
and difficult to follow.
253+
and difficult to follow. Consider this following example, which places two boxes in our sketch. To position the second box
254+
without <a class="code">push()</a> and <a class="code">pop()</a>, you have to account for the first transformation. This
255+
can be a lot to keep track of in a more complex 3D scene.
249256
</p>
250257

251258
<pre><code class="language-javascript">
@@ -284,7 +291,7 @@ function draw(){
284291
transformation matrix is combined with the view matrix and the projection matrix, both of which help simulate
285292
the view of a camera, and this combination results in our 3D scene! </p>
286293
<a href="https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_model_view_projection">
287-
https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_model_view_projection
294+
Learn more about Model View Projection
288295
</a>
289296
</div>
290297

@@ -294,44 +301,46 @@ function draw(){
294301

295302
{{!-- push and pop example --}}
296303
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
297-
function setup() {
298-
createCanvas(windowWidth, windowHeight, WEBGL);
299-
}
304+
function setup() {
305+
createCanvas(150, 216, WEBGL);
306+
debugMode();
307+
}
300308
301-
function draw(){
302-
background(255);
303-
//
304-
push(); // detach our coordinate system
305-
// draw a box 100 units to the right
306-
translate(100,0,0);
307-
box();
308-
pop(); // return to our original coordinate system
309+
function draw() {
310+
background(255);
311+
camera(100, -100, 100);
309312
310-
translate(-100,0,0);
311-
box();
312-
}
313+
push(); // detach our coordinate system
314+
315+
// draw a box 100 units along the x-axis
316+
translate(50, 0, 0);
317+
rotateY(PI/4);
318+
box(30);
319+
pop(); // return to our original coordinate system
320+
321+
// draw a second box -50 units along the x-axis
322+
translate(-50, 0, 0);
323+
rotateY(PI/4);
324+
box(30);
325+
}
313326
</script>
314327

315328
<h2 id="basic_shapes">Basic Shapes in 3D</h2>
316329

317330
<p>So far we have only been using <a class="code">box()</a> but p5.js has seven different predefined geometries
318331
that you can use in
319-
your sketch. These basic predefined geometries are often referred to as 'primitives'. <a
320-
href="{{root}}/examples/3d-geometries.html">Click here</a> to view an example showing off each
321-
of these types.</p>
322-
323-
<ul>
324-
<li><a class="code" href="{{root}}/reference/#/p5/box">box(width, height, depth, detailX, detailY)</a></li>
325-
<li><a class="code" href="{{root}}/reference/#/p5/plane">plane(width, height, detailX, detailY)</a></li>
326-
<li><a class="code" href="{{root}}/reference/#/p5/sphere">sphere(radius, detailX, detailY)</a></li>
327-
<li><a class="code" href="{{root}}/reference/#/p5/ellipsoid">ellipsoid(radiusx, radiusy, radiusz, detailX,
328-
detailY)</a></li>
329-
<li><a class="code" href="{{root}}/reference/#/p5/cone">cone(radius, height, detailX, detailY, cap)</a></li>
330-
<li><a class="code" href="{{root}}/reference/#/p5/cylinder">cylinder(radius, height, detailX, detailY,
331-
bottomCap, topCap)</a></li>
332-
<li><a class="code" href="{{root}}/reference/#/p5/torus">torus(radius, tubeRadius, detailX, detailY)</a>
333-
</li>
334-
</ul>
332+
your sketch. These basic predefined geometries are often referred to as 'primitives'.</p>
333+
334+
<img style="padding:60px;" src='{{assets}}/learn/basic3D/images/primitives_example.png'
335+
alt="an illustration showing each of the available primitives in p5.js">
336+
337+
<p>These primitive shape methods are: <a class="code" href="{{root}}/reference/#/p5/box">box()</a>,
338+
<a class="code" href="{{root}}/reference/#/p5/plane">plane()</a>,
339+
<a class="code" href="{{root}}/reference/#/p5/sphere">sphere()</a>,
340+
<a class="code" href="{{root}}/reference/#/p5/ellipsoid">ellipsoid()</a>,
341+
<a class="code" href="{{root}}/reference/#/p5/cone">cone()</a>,
342+
<a class="code" href="{{root}}/reference/#/p5/cylinder">cylinder()</a>, and
343+
<a class="code" href="{{root}}/reference/#/p5/torus">torus()</a></p>
335344

336345
<p>It is also possible to create custom geometry, either from scratch or from 3D models created in another
337346
program.
@@ -342,7 +351,7 @@ function draw(){
342351
<h2 id="conclusion">Conclusion</h2>
343352

344353
<p>
345-
By having basic control over a 3d coordinate space, transformations,
354+
By having basic control over a 3D coordinate space, transformations,
346355
and basic shapes, you should be able to begin creating basic scenes
347356
in 3D. The tutorials that follow this in the Getting Started in WebGL series
348357
will introduce custom geometries, allow you to tweak the appearance of
@@ -352,11 +361,10 @@ function draw(){
352361

353362
<h2 id="glossary">Glossary</h2>
354363

355-
{{!-- <h3>World Space</h3>
356-
<p>A coordinate space that is relative to the world origin (0,0,0)</p>
357-
358-
<h3>Screen Space</h3>
359-
<p>A coordinate space that is relative to the top left of the screen (0,0)</p> --}}
364+
<h3>GPU</h3>
365+
<p>The GPU (Graphics Processing Unit) is a piece of hardware that is particularly well
366+
suited for performing many calculations in parallel, making it powerful for 3D graphics.
367+
</p>
360368

361369
<h3>Model</h3>
362370
<p>A custom 3D geometry that can be saved and loaded from a file</p>
@@ -368,7 +376,7 @@ function draw(){
368376
<p>The viewpoint of a 3D scene</p>
369377

370378
<h3>Transform</h3>
371-
<p>The combined scale, rotation, and translation of a geometry.</p>
379+
<p>Also referred to as <em>transformation</em>, this refers to the combined scale, rotation, and translation of a geometry.</p>
372380

373381
<h3>Vertex</h3>
374382
<p>A point in space</p>

0 commit comments

Comments
 (0)