diff --git a/src/webgl/3d_primitives.js b/src/webgl/3d_primitives.js index 8d574e52a3..63bc4213de 100644 --- a/src/webgl/3d_primitives.js +++ b/src/webgl/3d_primitives.js @@ -11,210 +11,959 @@ import './p5.Geometry'; import * as constants from '../core/constants'; /** - * Starts creating a new p5.Geometry. Subsequent shapes drawn will be added - * to the geometry and then returned when - * endGeometry() is called. One can also use - * buildGeometry() to pass a function that - * draws shapes. + * Begins adding shapes to a new + * p5.Geometry object. * - * If you need to draw complex shapes every frame which don't change over time, - * combining them upfront with `beginGeometry()` and `endGeometry()` and then - * drawing that will run faster than repeatedly drawing the individual pieces. + * The `beginGeometry()` and endGeometry() + * functions help with creating complex 3D shapes from simpler ones such as + * sphere(). `beginGeometry()` begins adding shapes + * to a custom p5.Geometry object and + * endGeometry() stops adding them. + * + * `beginGeometry()` and endGeometry() can help + * to make sketches more performant. For example, if a complex 3D shape + * doesn’t change while a sketch runs, then it can be created with + * `beginGeometry()` and endGeometry(). + * Creating a p5.Geometry object once and then + * drawing it will run faster than repeatedly drawing the individual pieces. + * + * See buildGeometry() for another way to + * build 3D shapes. + * + * Note: `beginGeometry()` can only be used in WebGL mode. * * @method beginGeometry * * @example *
* - * let shapes; + * // Click and drag the mouse to view the scene from different angles. + * + * let shape; + * + * function setup() { + * createCanvas(100, 100, WEBGL); + * + * // Start building the p5.Geometry object. + * beginGeometry(); + * + * // Add a cone. + * cone(); + * + * // Stop building the p5.Geometry object. + * shape = endGeometry(); + * + * describe('A white cone drawn on a gray background.'); + * } + * + * function draw() { + * background(50); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Turn on the lights. + * lights(); + * + * // Style the p5.Geometry object. + * noStroke(); + * + * // Draw the p5.Geometry object. + * model(shape); + * } + * + *
+ * + *
+ * + * // Click and drag the mouse to view the scene from different angles. + * + * let shape; + * + * function setup() { + * createCanvas(100, 100, WEBGL); + * + * // Create the p5.Geometry object. + * createArrow(); + * + * describe('A white arrow drawn on a gray background.'); + * } + * + * function draw() { + * background(50); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Turn on the lights. + * lights(); + * + * // Style the p5.Geometry object. + * noStroke(); + * + * // Draw the p5.Geometry object. + * model(shape); + * } + * + * function createArrow() { + * // Start building the p5.Geometry object. + * beginGeometry(); + * + * // Add shapes. + * push(); + * rotateX(PI); + * cone(10); + * translate(0, -10, 0); + * cylinder(3, 20); + * pop(); + * + * // Stop building the p5.Geometry object. + * shape = endGeometry(); + * } + * + *
+ * + *
+ * + * // Click and drag the mouse to view the scene from different angles. + * + * let blueArrow; + * let redArrow; + * + * function setup() { + * createCanvas(100, 100, WEBGL); + * + * // Create the arrows. + * redArrow = createArrow('red'); + * blueArrow = createArrow('blue'); + * + * describe('A red arrow and a blue arrow drawn on a gray background. The blue arrow rotates slowly.'); + * } + * + * function draw() { + * background(200); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Turn on the lights. + * lights(); + * + * // Style the arrows. + * noStroke(); + * + * // Draw the red arrow. + * model(redArrow); + * + * // Translate and rotate the coordinate system. + * translate(30, 0, 0); + * rotateZ(frameCount * 0.01); + * + * // Draw the blue arrow. + * model(blueArrow); + * } + * + * function createArrow(fillColor) { + * // Start building the p5.Geometry object. + * beginGeometry(); + * + * fill(fillColor); + * + * // Add shapes to the p5.Geometry object. + * push(); + * rotateX(PI); + * cone(10); + * translate(0, -10, 0); + * cylinder(3, 20); + * pop(); + * + * // Stop building the p5.Geometry object. + * let shape = endGeometry(); + * + * return shape; + * } + * + *
+ * + *
+ * + * // Click and drag the mouse to view the scene from different angles. + * + * let button; + * let particles; + * + * function setup() { + * createCanvas(100, 100, WEBGL); + * + * // Create a button to reset the particle system. + * button = createButton('Reset'); + * + * // Call resetModel() when the user presses the button. + * button.mousePressed(resetModel); + * + * // Add the original set of particles. + * resetModel(); + * } + * + * function draw() { + * background(50); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Turn on the lights. + * lights(); + * + * // Style the particles. + * noStroke(); + * + * // Draw the particles. + * model(particles); + * } + * + * function resetModel() { + * // If the p5.Geometry object has already been created, + * // free those resources. + * if (particles) { + * freeGeometry(particles); + * } + * + * // Create a new p5.Geometry object with random spheres. + * particles = createParticles(); + * } + * + * function createParticles() { + * // Start building the p5.Geometry object. + * beginGeometry(); + * + * // Add shapes. + * for (let i = 0; i < 60; i += 1) { + * // Calculate random coordinates. + * let x = randomGaussian(0, 20); + * let y = randomGaussian(0, 20); + * let z = randomGaussian(0, 20); + * + * push(); + * // Translate to the particle's coordinates. + * translate(x, y, z); + * // Draw the particle. + * sphere(5); + * pop(); + * } + * + * // Stop building the p5.Geometry object. + * let shape = endGeometry(); + * + * return shape; + * } + * + *
+ */ +p5.prototype.beginGeometry = function() { + return this._renderer.beginGeometry(); +}; + +/** + * Stops adding shapes to a new + * p5.Geometry object and returns the object. + * + * The `beginGeometry()` and endGeometry() + * functions help with creating complex 3D shapes from simpler ones such as + * sphere(). `beginGeometry()` begins adding shapes + * to a custom p5.Geometry object and + * endGeometry() stops adding them. + * + * `beginGeometry()` and endGeometry() can help + * to make sketches more performant. For example, if a complex 3D shape + * doesn’t change while a sketch runs, then it can be created with + * `beginGeometry()` and endGeometry(). + * Creating a p5.Geometry object once and then + * drawing it will run faster than repeatedly drawing the individual pieces. + * + * See buildGeometry() for another way to + * build 3D shapes. + * + * Note: `endGeometry()` can only be used in WebGL mode. + * + * @method endGeometry + * @returns {p5.Geometry} new 3D shape. + * + * @example + *
+ * + * // Click and drag the mouse to view the scene from different angles. + * + * let shape; * * function setup() { * createCanvas(100, 100, WEBGL); - * makeShapes(); + * + * // Start building the p5.Geometry object. + * beginGeometry(); + * + * // Add a cone. + * cone(); + * + * // Stop building the p5.Geometry object. + * shape = endGeometry(); + * + * describe('A white cone drawn on a gray background.'); + * } + * + * function draw() { + * background(50); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Turn on the lights. + * lights(); + * + * // Style the p5.Geometry object. + * noStroke(); + * + * // Draw the p5.Geometry object. + * model(shape); * } + * + *
* - * function makeShapes() { + *
+ * + * // Click and drag the mouse to view the scene from different angles. + * + * let shape; + * + * function setup() { + * createCanvas(100, 100, WEBGL); + * + * // Create the p5.Geometry object. + * createArrow(); + * + * describe('A white arrow drawn on a gray background.'); + * } + * + * function draw() { + * background(50); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Turn on the lights. + * lights(); + * + * // Style the p5.Geometry object. + * noStroke(); + * + * // Draw the p5.Geometry object. + * model(shape); + * } + * + * function createArrow() { + * // Start building the p5.Geometry object. * beginGeometry(); - * scale(0.18); * + * // Add shapes. + * push(); + * rotateX(PI); + * cone(10); + * translate(0, -10, 0); + * cylinder(3, 20); + * pop(); + * + * // Stop building the p5.Geometry object. + * shape = endGeometry(); + * } + * + *
+ * + *
+ * + * // Click and drag the mouse to view the scene from different angles. + * + * let blueArrow; + * let redArrow; + * + * function setup() { + * createCanvas(100, 100, WEBGL); + * + * // Create the arrows. + * redArrow = createArrow('red'); + * blueArrow = createArrow('blue'); + * + * describe('A red arrow and a blue arrow drawn on a gray background. The blue arrow rotates slowly.'); + * } + * + * function draw() { + * background(200); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Turn on the lights. + * lights(); + * + * // Style the arrows. + * noStroke(); + * + * // Draw the red arrow. + * model(redArrow); + * + * // Translate and rotate the coordinate system. + * translate(30, 0, 0); + * rotateZ(frameCount * 0.01); + * + * // Draw the blue arrow. + * model(blueArrow); + * } + * + * function createArrow(fillColor) { + * // Start building the p5.Geometry object. + * beginGeometry(); + * + * fill(fillColor); + * + * // Add shapes to the p5.Geometry object. * push(); - * translate(100, -50); - * scale(0.5); - * rotateX(PI/4); + * rotateX(PI); + * cone(10); + * translate(0, -10, 0); + * cylinder(3, 20); + * pop(); + * + * // Stop building the p5.Geometry object. + * let shape = endGeometry(); + * + * return shape; + * } + * + *
+ * + *
+ * + * // Click and drag the mouse to view the scene from different angles. + * + * let button; + * let particles; + * + * function setup() { + * createCanvas(100, 100, WEBGL); + * + * // Create a button to reset the particle system. + * button = createButton('Reset'); + * + * // Call resetModel() when the user presses the button. + * button.mousePressed(resetModel); + * + * // Add the original set of particles. + * resetModel(); + * } + * + * function draw() { + * background(50); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Turn on the lights. + * lights(); + * + * // Style the particles. + * noStroke(); + * + * // Draw the particles. + * model(particles); + * } + * + * function resetModel() { + * // If the p5.Geometry object has already been created, + * // free those resources. + * if (particles) { + * freeGeometry(particles); + * } + * + * // Create a new p5.Geometry object with random spheres. + * particles = createParticles(); + * } + * + * function createParticles() { + * // Start building the p5.Geometry object. + * beginGeometry(); + * + * // Add shapes. + * for (let i = 0; i < 60; i += 1) { + * // Calculate random coordinates. + * let x = randomGaussian(0, 20); + * let y = randomGaussian(0, 20); + * let z = randomGaussian(0, 20); + * + * push(); + * // Translate to the particle's coordinates. + * translate(x, y, z); + * // Draw the particle. + * sphere(5); + * pop(); + * } + * + * // Stop building the p5.Geometry object. + * let shape = endGeometry(); + * + * return shape; + * } + * + *
+ */ +p5.prototype.endGeometry = function() { + return this._renderer.endGeometry(); +}; + +/** + * Creates a custom p5.Geometry object from + * simpler 3D shapes. + * + * `buildGeometry()` helps with creating complex 3D shapes from simpler ones + * such as sphere(). It can help to make sketches + * more performant. For example, if a complex 3D shape doesn’t change while a + * sketch runs, then it can be created with `buildGeometry()`. Creating a + * p5.Geometry object once and then drawing it + * will run faster than repeatedly drawing the individual pieces. + * + * The parameter, `callback`, is a function with the drawing instructions for + * the new p5.Geometry object. It will be called + * once to create the new 3D shape. + * + * See beginGeometry() and + * endGeometry() for another way to build 3D + * shapes. + * + * Note: `buildGeometry()` can only be used in WebGL mode. + * + * @method buildGeometry + * @param {Function} callback function that draws the shape. + * @returns {p5.Geometry} new 3D shape. + * + * @example + *
+ * + * // Click and drag the mouse to view the scene from different angles. + * + * let shape; + * + * function setup() { + * createCanvas(100, 100, WEBGL); + * + * // Create the p5.Geometry object. + * shape = buildGeometry(createShape); + * + * describe('A white cone drawn on a gray background.'); + * } + * + * function draw() { + * background(50); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Turn on the lights. + * lights(); + * + * // Style the p5.Geometry object. + * noStroke(); + * + * // Draw the p5.Geometry object. + * model(shape); + * } + * + * // Create p5.Geometry object from a single cone. + * function createShape() { * cone(); + * } + * + *
+ * + *
+ * + * // Click and drag the mouse to view the scene from different angles. + * + * let shape; + * + * function setup() { + * createCanvas(100, 100, WEBGL); + * + * // Create the arrow. + * shape = buildGeometry(createArrow); + * + * describe('A white arrow drawn on a gray background.'); + * } + * + * function draw() { + * background(50); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Turn on the lights. + * lights(); + * + * // Style the arrow. + * noStroke(); + * + * // Draw the arrow. + * model(shape); + * } + * + * function createArrow() { + * // Add shapes to the p5.Geometry object. + * push(); + * rotateX(PI); + * cone(10); + * translate(0, -10, 0); + * cylinder(3, 20); + * pop(); + * } + * + *
+ * + *
+ * + * // Click and drag the mouse to view the scene from different angles. + * + * let shape; + * + * function setup() { + * createCanvas(100, 100, WEBGL); + * + * // Create the p5.Geometry object. + * shape = buildGeometry(createArrow); + * + * describe('Two white arrows drawn on a gray background. The arrow on the right rotates slowly.'); + * } + * + * function draw() { + * background(50); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Turn on the lights. + * lights(); + * + * // Style the arrows. + * noStroke(); + * + * // Draw the p5.Geometry object. + * model(shape); + * + * // Translate and rotate the coordinate system. + * translate(30, 0, 0); + * rotateZ(frameCount * 0.01); + * + * // Draw the p5.Geometry object again. + * model(shape); + * } + * + * function createArrow() { + * // Add shapes to the p5.Geometry object. + * push(); + * rotateX(PI); + * cone(10); + * translate(0, -10, 0); + * cylinder(3, 20); * pop(); + * } + * + *
+ * + *
+ * + * // Click and drag the mouse to view the scene from different angles. + * + * let button; + * let particles; + * + * function setup() { + * createCanvas(100, 100, WEBGL); + * + * // Create a button to reset the particle system. + * button = createButton('Reset'); + * + * // Call resetModel() when the user presses the button. + * button.mousePressed(resetModel); + * + * // Add the original set of particles. + * resetModel(); + * + * describe('A set of white spheres on a gray background. The spheres are positioned randomly. Their positions reset when the user presses the Reset button.'); + * } + * + * function draw() { + * background(50); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Turn on the lights. + * lights(); + * + * // Style the particles. + * noStroke(); + * + * // Draw the particles. + * model(particles); + * } + * + * function resetModel() { + * // If the p5.Geometry object has already been created, + * // free those resources. + * if (particles) { + * freeGeometry(particles); + * } + * + * // Create a new p5.Geometry object with random spheres. + * particles = buildGeometry(createParticles); + * } + * + * function createParticles() { + * for (let i = 0; i < 60; i += 1) { + * // Calculate random coordinates. + * let x = randomGaussian(0, 20); + * let y = randomGaussian(0, 20); + * let z = randomGaussian(0, 20); + * + * push(); + * // Translate to the particle's coordinates. + * translate(x, y, z); + * // Draw the particle. + * sphere(5); + * pop(); + * } + * } + * + *
+ */ +p5.prototype.buildGeometry = function(callback) { + return this._renderer.buildGeometry(callback); +}; + +/** + * Clears a p5.Geometry object from the graphics + * processing unit (GPU) memory. + * + * p5.Geometry objects can contain lots of data + * about their vertices, surface normals, colors, and so on. Complex 3D shapes + * can use lots of memory which is a limited resource in many GPUs. Calling + * `freeGeometry()` can improve performance by freeing a + * p5.Geometry object’s resources from GPU memory. + * `freeGeometry()` works with p5.Geometry objects + * created with beginGeometry() and + * endGeometry(), + * buildGeometry(), and + * loadModel(). + * + * The parameter, `geometry`, is the p5.Geometry + * object to be freed. + * + * Note: A p5.Geometry object can still be drawn + * after its resources are cleared from GPU memory. It may take longer to draw + * the first time it’s redrawn. + * + * Note: `freeGeometry()` can only be used in WebGL mode. + * + * @method freeGeometry + * @param {p5.Geometry} geometry 3D shape whose resources should be freed. + * + * @example + *
+ * + * function setup() { + * createCanvas(100, 100, WEBGL); + * + * background(200); + * + * // Create a p5.Geometry object. + * beginGeometry(); * cone(); + * let shape = endGeometry(); + * + * // Draw the shape. + * model(shape); + * + * // Free the shape's resources. + * freeGeometry(shape); + * } + * + *
+ * + *
+ * + * // Click and drag the mouse to view the scene from different angles. + * + * let button; + * let particles; + * + * function setup() { + * createCanvas(100, 100, WEBGL); + * + * // Create a button to reset the particle system. + * button = createButton('Reset'); + * + * // Call resetModel() when the user presses the button. + * button.mousePressed(resetModel); + * + * // Add the original set of particles. + * resetModel(); + * } + * + * function draw() { + * background(50); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Turn on the lights. + * lights(); * - * beginShape(); - * vertex(-20, -50); - * quadraticVertex( - * -40, -70, - * 0, -60 - * ); - * endShape(); - * - * beginShape(TRIANGLE_STRIP); - * for (let y = 20; y <= 60; y += 10) { - * for (let x of [20, 60]) { - * vertex(x, y); - * } - * } - * endShape(); + * // Style the particles. + * noStroke(); + * + * // Draw the particles. + * model(particles); + * } * - * beginShape(); - * vertex(-100, -120); - * vertex(-120, -110); - * vertex(-105, -100); - * endShape(); + * function resetModel() { + * // If the p5.Geometry object has already been created, + * // free those resources. + * if (particles) { + * freeGeometry(particles); + * } * - * shapes = endGeometry(); + * // Create a new p5.Geometry object with random spheres. + * particles = buildGeometry(createParticles); * } * - * function draw() { - * background(255); - * lights(); - * orbitControl(); - * model(shapes); + * function createParticles() { + * for (let i = 0; i < 60; i += 1) { + * // Calculate random coordinates. + * let x = randomGaussian(0, 20); + * let y = randomGaussian(0, 20); + * let z = randomGaussian(0, 20); + * + * push(); + * // Translate to the particle's coordinates. + * translate(x, y, z); + * // Draw the particle. + * sphere(5); + * pop(); + * } * } * *
- * - * @alt - * A series of different flat, curved, and 3D shapes floating in space. */ -p5.prototype.beginGeometry = function() { - return this._renderer.beginGeometry(); +p5.prototype.freeGeometry = function(geometry) { + this._renderer._freeBuffers(geometry.gid); }; /** - * Finishes creating a new p5.Geometry that was - * started using beginGeometry(). One can also - * use buildGeometry() to pass a function that - * draws shapes. + * Draws a plane. * - * @method endGeometry - * @returns {p5.Geometry} The model that was built. - */ -p5.prototype.endGeometry = function() { - return this._renderer.endGeometry(); -}; - -/** - * Creates a new p5.Geometry that contains all - * the shapes drawn in a provided callback function. The returned combined shape - * can then be drawn all at once using model(). + * A plane is a four-sided, flat shape with every angle measuring 90˚. It’s + * similar to a rectangle and offers advanced drawing features in WebGL mode. * - * If you need to draw complex shapes every frame which don't change over time, - * combining them with `buildGeometry()` once and then drawing that will run - * faster than repeatedly drawing the individual pieces. + * The first parameter, `width`, is optional. If a `Number` is passed, as in + * `plane(20)`, it sets the plane’s width and height. By default, `width` is + * 50. * - * One can also draw shapes directly between - * beginGeometry() and - * endGeometry() instead of using a callback - * function. + * The second parameter, `height`, is also optional. If a `Number` is passed, + * as in `plane(20, 30)`, it sets the plane’s height. By default, `height` is + * set to the plane’s `width`. * - * @method buildGeometry - * @param {Function} callback A function that draws shapes. - * @returns {p5.Geometry} The model that was built from the callback function. + * The third parameter, `detailX`, is also optional. If a `Number` is passed, + * as in `plane(20, 30, 5)` it sets the number of triangle subdivisions to use + * along the x-axis. All 3D shapes are made by connecting triangles to form + * their surfaces. By default, `detailX` is 1. + * + * The fourth parameter, `detailY`, is also optional. If a `Number` is passed, + * as in `plane(20, 30, 5, 7)` it sets the number of triangle subdivisions to + * use along the y-axis. All 3D shapes are made by connecting triangles to + * form their surfaces. By default, `detailY` is 1. + * + * Note: `plane()` can only be used in WebGL mode. + * + * @method plane + * @param {Number} [width] width of the plane. + * @param {Number} [height] height of the plane. + * @param {Integer} [detailX] number of triangle subdivisions along the x-axis. + * @param {Integer} [detailY] number of triangle subdivisions along the y-axis. + * @chainable * * @example *
* - * let particles; - * let button; + * // Click and drag the mouse to view the scene from different angles. * * function setup() { * createCanvas(100, 100, WEBGL); - * button = createButton('New'); - * button.mousePressed(makeParticles); - * makeParticles(); - * } * - * function makeParticles() { - * if (particles) freeGeometry(particles); - * - * particles = buildGeometry(() => { - * for (let i = 0; i < 60; i++) { - * push(); - * translate( - * randomGaussian(0, 20), - * randomGaussian(0, 20), - * randomGaussian(0, 20) - * ); - * sphere(5); - * pop(); - * } - * }); + * describe('A white plane on a gray background.'); * } * * function draw() { - * background(255); - * noStroke(); - * lights(); + * background(200); + * + * // Enable orbiting with the mouse. * orbitControl(); - * model(particles); + * + * // Draw the plane. + * plane(); * } * *
* - * @alt - * A cluster of spheres. - */ -p5.prototype.buildGeometry = function(callback) { - return this._renderer.buildGeometry(callback); -}; - -/** - * Clears the resources of a model to free up browser memory. A model whose - * resources have been cleared can still be drawn, but the first time it is - * drawn again, it might take longer. + *
+ * + * // Click and drag the mouse to view the scene from different angles. + * + * function setup() { + * createCanvas(100, 100, WEBGL); * - * This method works on models generated with - * buildGeometry() as well as those loaded - * from loadModel(). + * describe('A white plane on a gray background.'); + * } + * + * function draw() { + * background(200); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Draw the plane. + * // Set its width and height to 30. + * plane(30); + * } + * + *
* - * @method freeGeometry - * @param {p5.Geometry} geometry The geometry whose resources should be freed - */ -p5.prototype.freeGeometry = function(geometry) { - this._renderer._freeBuffers(geometry.gid); -}; - -/** - * Draw a plane with given a width and height - * @method plane - * @param {Number} [width] width of the plane - * @param {Number} [height] height of the plane - * @param {Integer} [detailX] Optional number of triangle - * subdivisions in x-dimension - * @param {Integer} [detailY] Optional number of triangle - * subdivisions in y-dimension - * @chainable - * @example *
* - * // draw a plane - * // with width 50 and height 50 + * // Click and drag the mouse to view the scene from different angles. + * * function setup() { * createCanvas(100, 100, WEBGL); - * describe('a white plane with black wireframe lines'); + * + * describe('A white plane on a gray background.'); * } * * function draw() { * background(200); - * plane(50, 50); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Draw the plane. + * // Set its width to 30 and height to 50. + * plane(30, 50); * } * *
- * - * @alt - * Nothing displayed on canvas - * Rotating interior view of a box with sides that change color. - * 3d red and green gradient. - * Rotating interior view of a cylinder with sides that change color. - * Rotating view of a cylinder with sides that change color. - * 3d red and green gradient. - * rotating view of a multi-colored cylinder with concave sides. */ p5.prototype.plane = function( width = 50, @@ -258,33 +1007,130 @@ p5.prototype.plane = function( }; /** - * Draw a box with given width, height and depth + * Draws a box (rectangular prism). + * + * A box is a 3D shape with six faces. Each face makes a 90˚ with four + * neighboring faces. + * + * The first parameter, `width`, is optional. If a `Number` is passed, as in + * `box(20)`, it sets the box’s width and height. By default, `width` is 50. + * + * The second parameter, `height`, is also optional. If a `Number` is passed, + * as in `box(20, 30)`, it sets the box’s height. By default, `height` is set + * to the box’s `width`. + * + * The third parameter, `depth`, is also optional. If a `Number` is passed, as + * in `box(20, 30, 40)`, it sets the box’s depth. By default, `depth` is set + * to the box’s `height`. + * + * The fourth parameter, `detailX`, is also optional. If a `Number` is passed, + * as in `box(20, 30, 40, 5)`, it sets the number of triangle subdivisions to + * use along the x-axis. All 3D shapes are made by connecting triangles to + * form their surfaces. By default, `detailX` is 1. + * + * The fifth parameter, `detailY`, is also optional. If a number is passed, as + * in `box(20, 30, 40, 5, 7)`, it sets the number of triangle subdivisions to + * use along the y-axis. All 3D shapes are made by connecting triangles to + * form their surfaces. By default, `detailY` is 1. + * + * Note: `box()` can only be used in WebGL mode. + * * @method box - * @param {Number} [width] width of the box - * @param {Number} [height] height of the box - * @param {Number} [depth] depth of the box - * @param {Integer} [detailX] Optional number of triangle - * subdivisions in x-dimension - * @param {Integer} [detailY] Optional number of triangle - * subdivisions in y-dimension + * @param {Number} [width] width of the box. + * @param {Number} [height] height of the box. + * @param {Number} [depth] depth of the box. + * @param {Integer} [detailX] number of triangle subdivisions along the x-axis. + * @param {Integer} [detailY] number of triangle subdivisions along the y-axis. * @chainable + * * @example *
* - * // draw a spinning box - * // with width, height and depth of 50 + * // Click and drag the mouse to view the scene from different angles. + * * function setup() { * createCanvas(100, 100, WEBGL); - * camera(0, 0, 50*sqrt(3), 0, 0, 0, 0, 1, 0); - * perspective(PI/3, 1, 5*sqrt(3), 500*sqrt(3)); - * describe('a white box rotating in 3D space'); + * + * describe('A white box on a gray background.'); * } * * function draw() { * background(200); - * rotateX(frameCount * 0.01); - * rotateY(frameCount * 0.01); - * box(50); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Draw the box. + * box(); + * } + * + *
+ * + *
+ * + * // Click and drag the mouse to view the scene from different angles. + * + * function setup() { + * createCanvas(100, 100, WEBGL); + * + * describe('A white box on a gray background.'); + * } + * + * function draw() { + * background(200); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Draw the box. + * // Set its width and height to 30. + * box(30); + * } + * + *
+ * + *
+ * + * // Click and drag the mouse to view the scene from different angles. + * + * function setup() { + * createCanvas(100, 100, WEBGL); + * + * describe('A white box on a gray background.'); + * } + * + * function draw() { + * background(200); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Draw the box. + * // Set its width to 30 and height to 50. + * box(30, 50); + * } + * + *
+ * + *
+ * + * // Click and drag the mouse to view the scene from different angles. + * + * function setup() { + * createCanvas(100, 100, WEBGL); + * + * describe('A white box on a gray background.'); + * } + * + * function draw() { + * background(200); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Draw the box. + * // Set its width to 30, height to 50, and depth to 10. + * box(30, 50, 10); * } * *
@@ -379,76 +1225,124 @@ p5.prototype.box = function(width, height, depth, detailX, detailY) { }; /** - * Draw a sphere with given radius. + * Draws a sphere. + * + * A sphere is a 3D shape with triangular faces that connect to form a round + * surface. Spheres with few faces look like crystals. Spheres with many faces + * have smooth surfaces and look like balls. + * + * The first parameter, `radius`, is optional. If a `Number` is passed, as in + * `sphere(20)`, it sets the radius of the sphere. By default, `radius` is 50. + * + * The second parameter, `detailX`, is also optional. If a `Number` is passed, + * as in `sphere(20, 5)`, it sets the number of triangle subdivisions to use + * along the x-axis. All 3D shapes are made by connecting triangles to form + * their surfaces. By default, `detailX` is 24. + * + * The third parameter, `detailY`, is also optional. If a `Number` is passed, + * as in `sphere(20, 5, 2)`, it sets the number of triangle subdivisions to + * use along the y-axis. All 3D shapes are made by connecting triangles to + * form their surfaces. By default, `detailY` is 16. + * + * Note: `sphere()` can only be used in WebGL mode. * - * DetailX and detailY determines the number of subdivisions in the x-dimension - * and the y-dimension of a sphere. More subdivisions make the sphere seem - * smoother. The recommended maximum values are both 24. Using a value greater - * than 24 may cause a warning or slow down the browser. * @method sphere - * @param {Number} [radius] radius of circle - * @param {Integer} [detailX] optional number of subdivisions in x-dimension - * @param {Integer} [detailY] optional number of subdivisions in y-dimension + * @param {Number} [radius] radius of the sphere. Defaults to 50. + * @param {Integer} [detailX] number of triangle subdivisions along the x-axis. Defaults to 24. + * @param {Integer} [detailY] number of triangle subdivisions along the y-axis. Defaults to 16. * * @chainable * @example *
* - * // draw a sphere with radius 40 + * // Click and drag the mouse to view the scene from different angles. + * * function setup() { * createCanvas(100, 100, WEBGL); - * describe('a white sphere with black wireframe lines'); + * + * describe('A white sphere on a gray background.'); * } * * function draw() { - * background(205, 102, 94); - * sphere(40); + * background(200); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Draw the sphere. + * sphere(); + * } + * + *
+ * + *
+ * + * // Click and drag the mouse to view the scene from different angles. + * + * function setup() { + * createCanvas(100, 100, WEBGL); + * + * describe('A white sphere on a gray background.'); + * } + * + * function draw() { + * background(200); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Draw the sphere. + * // Set its radius to 30. + * sphere(30); * } * *
* - * @example *
* - * let detailX; - * // slide to see how detailX works + * // Click and drag the mouse to view the scene from different angles. + * * function setup() { * createCanvas(100, 100, WEBGL); - * detailX = createSlider(3, 24, 3); - * detailX.position(10, height + 5); - * detailX.style('width', '80px'); - * describe( - * 'a white sphere with low detail on the x-axis, including a slider to adjust detailX' - * ); + * + * describe('A white sphere on a gray background.'); * } * * function draw() { - * background(205, 105, 94); - * rotateY(millis() / 1000); - * sphere(40, detailX.value(), 16); + * background(200); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Draw the sphere. + * // Set its radius to 30. + * // Set its detailX to 6. + * sphere(30, 6); * } * *
* - * @example *
* - * let detailY; - * // slide to see how detailY works + * // Click and drag the mouse to view the scene from different angles. + * * function setup() { * createCanvas(100, 100, WEBGL); - * detailY = createSlider(3, 16, 3); - * detailY.position(10, height + 5); - * detailY.style('width', '80px'); - * describe( - * 'a white sphere with low detail on the y-axis, including a slider to adjust detailY' - * ); + * + * describe('A white sphere on a gray background.'); * } * * function draw() { - * background(205, 105, 94); - * rotateY(millis() / 1000); - * sphere(40, 16, detailY.value()); + * background(200); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Draw the sphere. + * // Set its radius to 30. + * // Set its detailX to 24. + * // Set its detailY to 4. + * sphere(30, 24, 4); * } * *
@@ -581,84 +1475,213 @@ const _truncatedCone = function( }; /** - * Draw a cylinder with given radius and height + * Draws a cylinder. + * + * A cylinder is a 3D shape with triangular faces that connect a flat bottom + * to a flat top. Cylinders with few faces look like boxes. Cylinders with + * many faces have smooth surfaces. + * + * The first parameter, `radius`, is optional. If a `Number` is passed, as in + * `cylinder(20)`, it sets the radius of the cylinder’s base. By default, + * `radius` is 50. + * + * The second parameter, `height`, is also optional. If a `Number` is passed, + * as in `cylinder(20, 30)`, it sets the cylinder’s height. By default, + * `height` is set to the cylinder’s `radius`. + * + * The third parameter, `detailX`, is also optional. If a `Number` is passed, + * as in `cylinder(20, 30, 5)`, it sets the number of edges used to form the + * cylinder's top and bottom. Using more edges makes the top and bottom look + * more like circles. By default, `detailX` is 24. + * + * The fourth parameter, `detailY`, is also optional. If a `Number` is passed, + * as in `cylinder(20, 30, 5, 2)`, it sets the number of triangle subdivisions + * to use along the y-axis, between cylinder's the top and bottom. All 3D + * shapes are made by connecting triangles to form their surfaces. By default, + * `detailY` is 1. + * + * The fifth parameter, `bottomCap`, is also optional. If a `false` is passed, + * as in `cylinder(20, 30, 5, 2, false)` the cylinder’s bottom won’t be drawn. + * By default, `bottomCap` is `true`. + * + * The sixth parameter, `topCap`, is also optional. If a `false` is passed, as + * in `cylinder(20, 30, 5, 2, false, false)` the cylinder’s top won’t be + * drawn. By default, `topCap` is `true`. + * + * Note: `cylinder()` can only be used in WebGL mode. + * + * @method cylinder + * @param {Number} [radius] radius of the cylinder. Defaults to 50. + * @param {Number} [height] height of the cylinder. Defaults to the value of `radius`. + * @param {Integer} [detailX] number of edges along the top and bottom. Defaults to 24. + * @param {Integer} [detailY] number of triangle subdivisions along the y-axis. Defaults to 1. + * @param {Boolean} [bottomCap] whether to draw the cylinder's bottom. Defaults to `true`. + * @param {Boolean} [topCap] whether to draw the cylinder's top. Defaults to `true`. + * @chainable + * + * @example + *
+ * + * // Click and drag the mouse to view the scene from different angles. + * + * function setup() { + * createCanvas(100, 100, WEBGL); + * + * describe('A white cylinder on a gray background.'); + * } + * + * function draw() { + * background(200); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Draw the cylinder. + * cylinder(); + * } + * + *
+ * + *
+ * + * // Click and drag the mouse to view the scene from different angles. + * + * function setup() { + * createCanvas(100, 100, WEBGL); + * + * describe('A white cylinder on a gray background.'); + * } + * + * function draw() { + * background(200); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Draw the cylinder. + * // Set its radius and height to 30. + * cylinder(30); + * } + * + *
+ * + *
+ * + * // Click and drag the mouse to view the scene from different angles. + * + * function setup() { + * createCanvas(100, 100, WEBGL); + * + * describe('A white cylinder on a gray background.'); + * } + * + * function draw() { + * background(200); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Draw the cylinder. + * // Set its radius to 30 and height to 50. + * cylinder(30, 50); + * } + * + *
+ * + *
+ * + * // Click and drag the mouse to view the scene from different angles. + * + * function setup() { + * createCanvas(100, 100, WEBGL); + * + * describe('A white box on a gray background.'); + * } * - * DetailX and detailY determines the number of subdivisions in the x-dimension - * and the y-dimension of a cylinder. More subdivisions make the cylinder seem smoother. - * The recommended maximum value for detailX is 24. Using a value greater than 24 - * may cause a warning or slow down the browser. + * function draw() { + * background(200); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Draw the cylinder. + * // Set its radius to 30 and height to 50. + * // Set its detailX to 5. + * cylinder(30, 50, 5); + * } + * + *
* - * @method cylinder - * @param {Number} [radius] radius of the surface - * @param {Number} [height] height of the cylinder - * @param {Integer} [detailX] number of subdivisions in x-dimension; - * default is 24 - * @param {Integer} [detailY] number of subdivisions in y-dimension; - * default is 1 - * @param {Boolean} [bottomCap] whether to draw the bottom of the cylinder - * @param {Boolean} [topCap] whether to draw the top of the cylinder - * @chainable - * @example *
* - * // draw a spinning cylinder - * // with radius 20 and height 50 + * // Click and drag the mouse to view the scene from different angles. + * * function setup() { * createCanvas(100, 100, WEBGL); - * describe('a rotating white cylinder'); + * + * describe('A white cylinder on a gray background.'); * } * * function draw() { - * background(205, 105, 94); - * rotateX(frameCount * 0.01); - * rotateZ(frameCount * 0.01); - * cylinder(20, 50); + * background(200); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Draw the cylinder. + * // Set its radius to 30 and height to 50. + * // Set its detailX to 24 and detailY to 2. + * cylinder(30, 50, 24, 2); * } * *
* - * @example *
* - * // slide to see how detailX works - * let detailX; + * // Click and drag the mouse to view the scene from different angles. + * * function setup() { * createCanvas(100, 100, WEBGL); - * detailX = createSlider(3, 24, 3); - * detailX.position(10, height + 5); - * detailX.style('width', '80px'); - * describe( - * 'a rotating white cylinder with limited X detail, with a slider that adjusts detailX' - * ); + * + * describe('A white cylinder on a gray background. Its top is missing.'); * } * * function draw() { - * background(205, 105, 94); - * rotateY(millis() / 1000); - * cylinder(20, 75, detailX.value(), 1); + * background(200); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Draw the cylinder. + * // Set its radius to 30 and height to 50. + * // Set its detailX to 24 and detailY to 1. + * // Don't draw its bottom. + * cylinder(30, 50, 24, 1, false); * } * *
* - * @example *
* - * // slide to see how detailY works - * let detailY; + * // Click and drag the mouse to view the scene from different angles. + * * function setup() { * createCanvas(100, 100, WEBGL); - * detailY = createSlider(1, 16, 1); - * detailY.position(10, height + 5); - * detailY.style('width', '80px'); - * describe( - * 'a rotating white cylinder with limited Y detail, with a slider that adjusts detailY' - * ); + * + * describe('A white cylinder on a gray background. Its top and bottom are missing.'); * } * * function draw() { - * background(205, 105, 94); - * rotateY(millis() / 1000); - * cylinder(20, 75, 16, detailY.value()); + * background(200); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Draw the cylinder. + * // Set its radius to 30 and height to 50. + * // Set its detailX to 24 and detailY to 1. + * // Don't draw its bottom or top. + * cylinder(30, 50, 24, 1, false, false); * } * *
@@ -705,84 +1728,206 @@ p5.prototype.cylinder = function( }; /** - * Draw a cone with given radius and height + * Draws a cone. + * + * A cone is a 3D shape with triangular faces that connect a flat bottom to a + * single point. Cones with few faces look like pyramids. Cones with many + * faces have smooth surfaces. + * + * The first parameter, `radius`, is optional. If a `Number` is passed, as in + * `cone(20)`, it sets the radius of the cone’s base. By default, `radius` is + * 50. + * + * The second parameter, `height`, is also optional. If a `Number` is passed, + * as in `cone(20, 30)`, it sets the cone’s height. By default, `height` is + * set to the cone’s `radius`. + * + * The third parameter, `detailX`, is also optional. If a `Number` is passed, + * as in `cone(20, 30, 5)`, it sets the number of edges used to form the + * cone's base. Using more edges makes the base look more like a circle. By + * default, `detailX` is 24. + * + * The fourth parameter, `detailY`, is also optional. If a `Number` is passed, + * as in `cone(20, 30, 5, 7)`, it sets the number of triangle subdivisions to + * use along the y-axis connecting the base to the tip. All 3D shapes are made + * by connecting triangles to form their surfaces. By default, `detailY` is 1. + * + * The fifth parameter, `cap`, is also optional. If a `false` is passed, as + * in `cone(20, 30, 5, 7, false)` the cone’s base won’t be drawn. By default, + * `cap` is `true`. + * + * Note: `cone()` can only be used in WebGL mode. * - * DetailX and detailY determine the number of subdivisions in the x-dimension and - * the y-dimension of a cone. More subdivisions make the cone seem smoother. The - * recommended maximum value for detailX is 24. Using a value greater than 24 - * may cause a warning or slow down the browser. * @method cone - * @param {Number} [radius] radius of the bottom surface - * @param {Number} [height] height of the cone - * @param {Integer} [detailX] number of segments, - * the more segments the smoother geometry - * default is 24 - * @param {Integer} [detailY] number of segments, - * the more segments the smoother geometry - * default is 1 - * @param {Boolean} [cap] whether to draw the base of the cone + * @param {Number} [radius] radius of the cone's base. Defaults to 50. + * @param {Number} [height] height of the cone. Defaults to the value of `radius`. + * @param {Integer} [detailX] number of edges used to draw the base. Defaults to 24. + * @param {Integer} [detailY] number of triangle subdivisions along the y-axis. Defaults to 1. + * @param {Boolean} [cap] whether to draw the cone's base. Defaults to `true`. * @chainable + * * @example *
* - * // draw a spinning cone - * // with radius 40 and height 70 + * // Click and drag the mouse to view the scene from different angles. + * * function setup() { * createCanvas(100, 100, WEBGL); - * describe('a rotating white cone'); + * + * describe('A white cone on a gray background.'); * } * * function draw() { * background(200); - * rotateX(frameCount * 0.01); - * rotateZ(frameCount * 0.01); - * cone(40, 70); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Draw the cone. + * cone(); * } * *
* - * @example *
* - * // slide to see how detailx works - * let detailX; + * // Click and drag the mouse to view the scene from different angles. + * * function setup() { * createCanvas(100, 100, WEBGL); - * detailX = createSlider(3, 16, 3); - * detailX.position(10, height + 5); - * detailX.style('width', '80px'); - * describe( - * 'a rotating white cone with limited X detail, with a slider that adjusts detailX' - * ); + * + * describe('A white cone on a gray background.'); * } * * function draw() { - * background(205, 102, 94); - * rotateY(millis() / 1000); - * cone(30, 65, detailX.value(), 16); + * background(200); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Draw the cone. + * // Set its radius and height to 30. + * cone(30); + * } + * + *
+ * + *
+ * + * // Click and drag the mouse to view the scene from different angles. + * + * function setup() { + * createCanvas(100, 100, WEBGL); + * + * describe('A white cone on a gray background.'); + * } + * + * function draw() { + * background(200); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Draw the cone. + * // Set its radius to 30 and height to 50. + * cone(30, 50); + * } + * + *
+ * + *
+ * + * // Click and drag the mouse to view the scene from different angles. + * + * function setup() { + * createCanvas(100, 100, WEBGL); + * + * describe('A white cone on a gray background.'); + * } + * + * function draw() { + * background(200); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Draw the cone. + * // Set its radius to 30 and height to 50. + * // Set its detailX to 5. + * cone(30, 50, 5); + * } + * + *
+ * + *
+ * + * // Click and drag the mouse to view the scene from different angles. + * + * function setup() { + * createCanvas(100, 100, WEBGL); + * + * describe('A white pyramid on a gray background.'); + * } + * + * function draw() { + * background(200); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Draw the cone. + * // Set its radius to 30 and height to 50. + * // Set its detailX to 5. + * cone(30, 50, 5); + * } + * + *
+ * + *
+ * + * // Click and drag the mouse to view the scene from different angles. + * + * function setup() { + * createCanvas(100, 100, WEBGL); + * + * describe('A white cone on a gray background.'); + * } + * + * function draw() { + * background(200); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Draw the cone. + * // Set its radius to 30 and height to 50. + * // Set its detailX to 24 and detailY to 2. + * cone(30, 50, 24, 2); * } * *
* - * @example *
* - * // slide to see how detailY works - * let detailY; + * // Click and drag the mouse to view the scene from different angles. + * * function setup() { * createCanvas(100, 100, WEBGL); - * detailY = createSlider(3, 16, 3); - * detailY.position(10, height + 5); - * detailY.style('width', '80px'); - * describe( - * 'a rotating white cone with limited Y detail, with a slider that adjusts detailY' - * ); + * + * describe('A white cone on a gray background. Its base is missing.'); * } * * function draw() { - * background(205, 102, 94); - * rotateY(millis() / 1000); - * cone(30, 65, 16, detailY.value()); + * background(200); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Draw the cone. + * // Set its radius to 30 and height to 50. + * // Set its detailX to 24 and detailY to 1. + * // Don't draw its base. + * cone(30, 50, 24, 1, false); * } * *
@@ -818,83 +1963,169 @@ p5.prototype.cone = function( }; /** - * Draw an ellipsoid with given radius + * Draws an ellipsoid. + * + * An ellipsoid is a 3D shape with triangular faces that connect to form a + * round surface. Ellipsoids with few faces look like crystals. Ellipsoids + * with many faces have smooth surfaces and look like eggs. `ellipsoid()` + * defines a shape by its radii. This is different from + * ellipse() which uses diameters + * (width and height). + * + * The first parameter, `radiusX`, is optional. If a `Number` is passed, as in + * `ellipsoid(20)`, it sets the radius of the ellipsoid along the x-axis. By + * default, `radiusX` is 50. + * + * The second parameter, `radiusY`, is also optional. If a `Number` is passed, + * as in `ellipsoid(20, 30)`, it sets the ellipsoid’s radius along the y-axis. + * By default, `radiusY` is set to the ellipsoid’s `radiusX`. + * + * The third parameter, `radiusZ`, is also optional. If a `Number` is passed, + * as in `ellipsoid(20, 30, 40)`, it sets the ellipsoid’s radius along the + * z-axis. By default, `radiusZ` is set to the ellipsoid’s `radiusY`. + * + * The fourth parameter, `detailX`, is also optional. If a `Number` is passed, + * as in `ellipsoid(20, 30, 40, 5)`, it sets the number of triangle + * subdivisions to use along the x-axis. All 3D shapes are made by connecting + * triangles to form their surfaces. By default, `detailX` is 24. + * + * The fifth parameter, `detailY`, is also optional. If a `Number` is passed, + * as in `ellipsoid(20, 30, 40, 5, 7)`, it sets the number of triangle + * subdivisions to use along the y-axis. All 3D shapes are made by connecting + * triangles to form their surfaces. By default, `detailY` is 16. + * + * Note: `ellipsoid()` can only be used in WebGL mode. * - * DetailX and detailY determine the number of subdivisions in the x-dimension and - * the y-dimension of a cone. More subdivisions make the ellipsoid appear to be smoother. - * Avoid detail number above 150, it may crash the browser. * @method ellipsoid - * @param {Number} [radiusx] x-radius of ellipsoid - * @param {Number} [radiusy] y-radius of ellipsoid - * @param {Number} [radiusz] z-radius of ellipsoid - * @param {Integer} [detailX] number of segments, - * the more segments the smoother geometry - * default is 24. Avoid detail number above - * 150, it may crash the browser. - * @param {Integer} [detailY] number of segments, - * the more segments the smoother geometry - * default is 16. Avoid detail number above - * 150, it may crash the browser. + * @param {Number} [radiusX] radius of the ellipsoid along the x-axis. Defaults to 50. + * @param {Number} [radiusY] radius of the ellipsoid along the y-axis. Defaults to `radiusX`. + * @param {Number} [radiusZ] radius of the ellipsoid along the z-axis. Defaults to `radiusY`. + * @param {Integer} [detailX] number of triangle subdivisions along the x-axis. Defaults to 24. + * @param {Integer} [detailY] number of triangle subdivisions along the y-axis. Defaults to 16. * @chainable + * * @example *
* - * // draw an ellipsoid - * // with radius 30, 40 and 40. + * // Click and drag the mouse to view the scene from different angles. + * * function setup() { * createCanvas(100, 100, WEBGL); - * describe('a white 3d ellipsoid'); + * + * describe('A white sphere on a gray background.'); * } * * function draw() { - * background(205, 105, 94); - * ellipsoid(30, 40, 40); + * background(200); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Draw the ellipsoid. + * // Set its radiusX to 30. + * ellipsoid(30); * } * *
* - * @example *
* - * // slide to see how detailX works - * let detailX; + * // Click and drag the mouse to view the scene from different angles. + * * function setup() { * createCanvas(100, 100, WEBGL); - * detailX = createSlider(2, 24, 12); - * detailX.position(10, height + 5); - * detailX.style('width', '80px'); - * describe( - * 'a rotating white ellipsoid with limited X detail, with a slider that adjusts detailX' - * ); + * + * describe('A white ellipsoid on a gray background.'); * } * * function draw() { - * background(205, 105, 94); - * rotateY(millis() / 1000); - * ellipsoid(30, 40, 40, detailX.value(), 8); + * background(200); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Draw the ellipsoid. + * // Set its radiusX to 30. + * // Set its radiusY to 40. + * ellipsoid(30, 40); + * } + * + *
+ * + *
+ * + * // Click and drag the mouse to view the scene from different angles. + * + * function setup() { + * createCanvas(100, 100, WEBGL); + * + * describe('A white ellipsoid on a gray background.'); + * } + * + * function draw() { + * background(200); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Draw the ellipsoid. + * // Set its radiusX to 30. + * // Set its radiusY to 40. + * // Set its radiusZ to 50. + * ellipsoid(30, 40, 50); + * } + * + *
+ * + *
+ * + * // Click and drag the mouse to view the scene from different angles. + * + * function setup() { + * createCanvas(100, 100, WEBGL); + * + * describe('A white ellipsoid on a gray background.'); + * } + * + * function draw() { + * background(200); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Draw the ellipsoid. + * // Set its radiusX to 30. + * // Set its radiusY to 40. + * // Set its radiusZ to 50. + * // Set its detailX to 4. + * ellipsoid(30, 40, 50, 4); * } * *
* - * @example *
* - * // slide to see how detailY works - * let detailY; + * // Click and drag the mouse to view the scene from different angles. + * * function setup() { * createCanvas(100, 100, WEBGL); - * detailY = createSlider(2, 24, 6); - * detailY.position(10, height + 5); - * detailY.style('width', '80px'); - * describe( - * 'a rotating white ellipsoid with limited Y detail, with a slider that adjusts detailY' - * ); + * + * describe('A white ellipsoid on a gray background.'); * } * * function draw() { - * background(205, 105, 9); - * rotateY(millis() / 1000); - * ellipsoid(30, 40, 40, 12, detailY.value()); + * background(200); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Draw the ellipsoid. + * // Set its radiusX to 30. + * // Set its radiusY to 40. + * // Set its radiusZ to 50. + * // Set its detailX to 4. + * // Set its detailY to 3. + * ellipsoid(30, 40, 50, 4, 3); * } * *
@@ -950,90 +2181,151 @@ p5.prototype.ellipsoid = function( }; /** - * Draw a torus with given radius and tube radius + * Draws a torus. + * + * A torus is a 3D shape with triangular faces that connect to form a ring. + * Toruses with few faces look flattened. Toruses with many faces have smooth + * surfaces. + * + * The first parameter, `radius`, is optional. If a `Number` is passed, as in + * `torus(30)`, it sets the radius of the ring. By default, `radius` is 50. + * + * The second parameter, `tubeRadius`, is also optional. If a `Number` is + * passed, as in `torus(30, 15)`, it sets the radius of the tube. By default, + * `tubeRadius` is 10. + * + * The third parameter, `detailX`, is also optional. If a `Number` is passed, + * as in `torus(30, 15, 5)`, it sets the number of edges used to draw the hole + * of the torus. Using more edges makes the hole look more like a circle. By + * default, `detailX` is 24. + * + * The fourth parameter, `detailY`, is also optional. If a `Number` is passed, + * as in `torus(30, 15, 5, 7)`, it sets the number of triangle subdivisions to + * use while filling in the torus’ height. By default, `detailY` is 16. + * + * Note: `torus()` can only be used in WebGL mode. * - * DetailX and detailY determine the number of subdivisions in the x-dimension and - * the y-dimension of a torus. More subdivisions make the torus appear to be smoother. - * The default and maximum values for detailX and detailY are 24 and 16, respectively. - * Setting them to relatively small values like 4 and 6 allows you to create new - * shapes other than a torus. * @method torus - * @param {Number} [radius] radius of the whole ring - * @param {Number} [tubeRadius] radius of the tube - * @param {Integer} [detailX] number of segments in x-dimension, - * the more segments the smoother geometry - * default is 24 - * @param {Integer} [detailY] number of segments in y-dimension, - * the more segments the smoother geometry - * default is 16 + * @param {Number} [radius] radius of the torus. Defaults to 50. + * @param {Number} [tubeRadius] radius of the tube. Defaults to 10. + * @param {Integer} [detailX] number of edges that form the hole. Defaults to 24. + * @param {Integer} [detailY] number of triangle subdivisions along the y-axis. Defaults to 16. * @chainable + * * @example *
* - * // draw a spinning torus - * // with ring radius 30 and tube radius 15 + * // Click and drag the mouse to view the scene from different angles. + * * function setup() { * createCanvas(100, 100, WEBGL); - * camera(0, 0, 50*sqrt(3), 0, 0, 0, 0, 1, 0); - * perspective(PI/3, 1, 5*sqrt(3), 500*sqrt(3)); - * describe('a rotating white torus'); + * + * describe('A white torus on a gray background.'); * } * * function draw() { - * background(205, 102, 94); - * rotateX(frameCount * 0.01); - * rotateY(frameCount * 0.01); + * background(200); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Draw the torus. + * torus(); + * } + * + *
+ * + *
+ * + * // Click and drag the mouse to view the scene from different angles. + * + * function setup() { + * createCanvas(100, 100, WEBGL); + * + * describe('A white torus on a gray background.'); + * } + * + * function draw() { + * background(200); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Draw the torus. + * // Set its radius to 30. + * torus(30); + * } + * + *
+ * + *
+ * + * // Click and drag the mouse to view the scene from different angles. + * + * function setup() { + * createCanvas(100, 100, WEBGL); + * + * describe('A white torus on a gray background.'); + * } + * + * function draw() { + * background(200); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Draw the torus. + * // Set its radius to 30 and tubeRadius to 15. * torus(30, 15); * } * *
* - * @example *
* - * // slide to see how detailX works - * let detailX; + * // Click and drag the mouse to view the scene from different angles. + * * function setup() { * createCanvas(100, 100, WEBGL); - * camera(0, 0, 50*sqrt(3), 0, 0, 0, 0, 1, 0); - * perspective(PI/3, 1, 5*sqrt(3), 500*sqrt(3)); - * detailX = createSlider(3, 24, 3); - * detailX.position(10, height + 5); - * detailX.style('width', '80px'); - * describe( - * 'a rotating white torus with limited X detail, with a slider that adjusts detailX' - * ); + * + * describe('A white torus on a gray background.'); * } * * function draw() { - * background(205, 102, 94); - * rotateY(millis() / 1000); - * torus(30, 15, detailX.value(), 12); + * background(200); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Draw the torus. + * // Set its radius to 30 and tubeRadius to 15. + * // Set its detailX to 5. + * torus(30, 15, 5); * } * *
* - * @example *
* - * // slide to see how detailY works - * let detailY; + * // Click and drag the mouse to view the scene from different angles. + * * function setup() { * createCanvas(100, 100, WEBGL); - * camera(0, 0, 50*sqrt(3), 0, 0, 0, 0, 1, 0); - * perspective(PI/3, 1, 5*sqrt(3), 500*sqrt(3)); - * detailY = createSlider(3, 16, 3); - * detailY.position(10, height + 5); - * detailY.style('width', '80px'); - * describe( - * 'a rotating white torus with limited Y detail, with a slider that adjusts detailY' - * ); + * + * describe('A white torus on a gray background.'); * } * * function draw() { - * background(205, 102, 94); - * rotateY(millis() / 1000); - * torus(30, 15, 16, detailY.value()); + * background(200); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Draw the torus. + * // Set its radius to 30 and tubeRadius to 15. + * // Set its detailX to 5. + * // Set its detailY to 3. + * torus(30, 15, 5, 3); * } * *