# Interesting Processing Programming Guidance for Designer - 3D Graphic

23

Three dimension is the progress of two dimension. Before learning new knowledge points, I hope you have been adept to two dimensional graphic drawing.

Compared with three-dimension software's like 3dMax, Maya, drawing graphics with code in three-dimension space has a totally different experience. Because there is no intuitive interface inside to control and adjust the position of objects, so it will be comparatively abstract when writing code. One of the difficulties is you have to familiar with space coordinate system and relative transformation operations.

Drawing in the flat interface, you only have to consider two dimensions: x axle and y axle. But in three dimensional space, there will be an extra z axle.

## Step 1: Coordinate System in Three-dimension Space

Let's take a look at the coordinate system in three-dimension space.

Compared with the original flat coordinate system, you can find x axle and y axle are still the same. The positive direction of the newly increased z axle points to the observer. It represents depth. Also, the distances of the objects depend on their values on z axle.

The position of the origin in three-dimension space is consistent with two-dimension coordinate system. They are both located on the upper left corner. In order to display the directions of each axle, the above picture has moved the origin horizontally. Picture below is the defaulted status of the coordinate system.

Note: We have added spinning dynamic effect to show depth.

When drawing, we must have a very clear idea of this coordinate, including its positive direction and negative direction of each axle. To deepen your impression and convenient understanding, we have made some examples about specific coordinate point in the following.

Suppose the distance between grids is 50 and a certain space coordinate value is (300,0,0), then it will be at the position showed below.

Note:

The origin has been horizontally moved. When space coordinate value is (－300,0,0), it will move left.

Coordinate value: (0,300,0)

Coordinate value: (0,0,300)

Coordinate value: (300,300,300)

## Step 2: Draw Cube

We have used many chapters in the previous to talk about coordinate system. This is the foundation of 3D graphic design. Only by mastering it, can we draw points, lines and shapes in the space at will according to our idea.

Next, we will enter into drawing part formally. Starting from the simplest graphic, let's draw a cube in the window.

Code Example(13-1):

[cceN_cpp theme="dawn"] Boolean showWire;

void setup() {

size(700, 700, P3D);

}

void draw() {

background(0);

if (showWire) {

// Close fill, display line frames only.

fill(255);

} else {

// Open fill.

noFill();

stroke(255);

}

translate(width/2, height/2, mouseX);

strokeWeight(3);

box(100);

}

void mousePressed() {

showWire = !showWire;

} [/cceN_cpp]

Operate Effect:

Code Explain:

Processing default to use two-dimension drawing mode. Before drawing a 3D graphic, we need to do some settings. Function size is able to be overlapped. The last parameter can be set to P3D or OPENGL mode. Different mode responds to different renderer. P3D is the simplest. It has the most powerful compatibility. OPENGL has higher efficiency. It is able to accelerate by using graphics card. Here we choose P3D to display.

In the example, we set a Boolean variable showWire to shift display mode. When clicking mouse, it will grab the opposite value of showWire, which has influenced the judgement statements in function draw and finally realized shifting effect.

The usage of function translate is to move coordinate system horizontally. This is not a new knowledge point for most of you. At the same time, function translate allows overlapping. When the quantity of parameter input is 3, the third parameter will influence z axle. The former two parameters are set to be width/2 and height/2. So the origin is right at the center of the screen. The last parameter is controlled by mouseX . So when you move mouse to the left or right, you can see the distance of your patterns is changing.

It seems the object is moving. But in reality, it is just about the position change of the coordinate system. Actually the coordinate of the object is still at the origin.

## Step 3: Rotate Cube

In the former, because of the angle of the camera is fixed, the object doesn't rotate. So it looks more like a two-dimension graphic instead of three-dimension graphic. Function rotate() described below can make the cube rotate.

Function rotate has several variants. They are rotateX, rotateY, rotateZ. They will rotate around different coordinate axle.

Among it, the rotate function category always rotates centering on the origin. So if you want to center on the object itself, you need to use translate to shift the origin to the coordinate of the object.

Code Example (13-2):

[cceN_cpp theme="dawn"] int rotateMode;

void setup() {

size(700, 700, P3D);

}

void draw() {

background(0);

translate(width/2, height/2);

if (rotateMode == 0) {

rotateX(millis() * 0.002);

} else if (rotateMode == 1) {

rotateY(millis() * 0.002);

} else {

rotateZ(millis() * 0.002);

}

noFill();

strokeWeight(3);

stroke(255);

box(300);

}

void mousePressed() {

rotateMode++;

if (rotateMode == 3) {

rotateMode = 0;

}

} [/cceN_cpp]

Operate Effect:

Code Explain:

Click mouse, then you can shift different rotation mode: rotate around x axle, y axle, and z axle. The integer variable rotateMode works as a media.

When drawing three-dimension graphics, translate() allows to import two parameters only. At this time, the defaulted z coordinate is 0.

## Step 4: Direction of Rotate

The rotating direction of function rotate has fixed rules. When the imported parameters are increasing, the coordinate system will rotate to the positive direction of the axle and rotate anti-clockwise. On the contrary, it will rotate in clockwise direction when they are decreasing.

The followings are rotations when parameters are increasing.

rotateX(millis() * 0.001);

rotateY(millis() * 0.001);

rotateZ(millis() * 0.001);

In addition to keep in mind with the usual method, you can also refer to the right-handed spiral rule (also known as amperometry) learned from the physic class in middle school.

The so-called right-handed spiral rule is a method to determine the direction of current and magnetic line of its magnetic filed. Use your right hand to hold the conductor cable. Point your thumb to the direction of the current. The rest four fingers will point to the direction of the magnetic line.

In the program, there is no current and magnetic field. However, you can describe direction in similar ways. For example, when parameters in rotateX are increasing, then you can adopt "left-handed spiral rule". Hold the rotating x axle with your left hand, point your thumb to the positive direction of the axle, then the rest four fingers will point to the relative rotating direction. When the values are decreasing, then use "right-handed spiral rule" with the same determination method. Hold the rotating axle with your right hand, point your thumb to the positive direction of the axle, then the rest four fingers will point to the relative rotating direction. (You can understand this rule according to the dynamic graphics above.)

## Step 5: Relative Functions Related to 3D Drawing

In the above, we have introduce a drawing function -box. Below we have listed some built-in 3D drawing functions in Processing and its relative overlapping formats.

Function box has two overlapping formats. When parameter quantity is 1, the value stands for the length of the cube line. When the quantity is 3, it separately controls the length, width, and height of the cuboid. Function sphere can draw sphere. Combined with sphereDetail, it can set the precision of the sphere. The above are the only two built-in 3D functions in Processing.

For 3D drawing, these two functions are far enough to use. If you want to draw some more complicated graphics, you can realize through custom function. Because of 3D graphic is assembled by several planes in reality, we can group a new stereo graphic only if we have well defined the position of climax on each place. The following will provide a function related to cylinder drawing. We just have to copy it into the program so that we can invoke directly.

## Step 6: Draw a Cylinder

Code Example(13-3):

[cceN_cpp theme="dawn"] void setup() {

size(700, 700, P3D);

}

void draw() {

background(0);

translate(width/2, height/2);

rotateX(millis() * 0.001);

rotateY(millis() * 0.001);

stroke(255);

strokeWeight(3);

noFill();

drawCylinder(int(mouseX * 0.05), 120, 350);

}

void drawCylinder(int sides, float r, float h) {

float angle = 2 * PI / sides;

float halfHeight = h / 2;

// Draw top plane.

beginShape();

for (int i = 0; i < sides; i++) {

float x = cos( i * angle ) * r;

float y = sin( i * angle ) * r;

vertex( x, y, -halfHeight );

}

endShape(CLOSE);

// Draw bottom plane.

beginShape();

for (int i = 0; i < sides; i++) {

float x = cos( i * angle ) * r;

float y = sin( i * angle ) * r;

vertex( x, y, halfHeight );

}

endShape(CLOSE);

// Draw side plane.

beginShape(TRIANGLE_STRIP);

for (int i = 0; i < sides + 1; i++) {

float x = cos( i * angle ) * r;

float y = sin( i * angle ) * r;

vertex( x, y, halfHeight);

vertex( x, y, -halfHeight);

}

endShape(CLOSE);

} [/cceN_cpp]

Operate Effect:

Code Explain:

Function drawCylinder allows to input 3 parameters. Among it, side represents the accuracy of the cylinder bottom plane, r stands for radius, and h is the height of the cylinder.

To draw a cylinder, the first step is to think about which blocks it can be divided into. Under ideal status, the cylinder's top plane and bottom plane are two round shapes, while the side is a curved face with arc in space. However, there is no "round shapes" nor "curved face" in computer. They are structured by some more basic units. For example, a circle, only displaying its line in the program, is assembled by several line segments. When their quantity are much enough, it will become more smooth and close to a circle. While a circle, displaying fill only, is consisted by triangle faces. Same rule towards curved face. The elements are triangles too. The larger face quantity, the smoother your graphic will be.

Therefore, in order to draw a graphic carrying with volume, the most important is to think about how to draw triangle face in the space. We have mentioned triangle function in the before. But it can only draw triangle in two dimensional plane. If we want to show it in the space, we have to use function beginShape, endShape and vertex. Vertex is a function, which is available for overlapping. When the quantity of the input parameter is 3, it indicates the space coordinate. The two code sections of "draw top face" and "draw bottom face" may not be strange to you, I believe. We calculate the climax of the circle with trigonometric function first. Then wrap it with beginShape in the front and endShape in the back. Thus it will display a circle.

In "drawing side face" code, there is a command "beginShape(TRIANGLE_STRIP)". TRIANGLE_STRIP is used to set the connection mode of the climax. It will decide which points to form a triangle. When no parameters filled, the defaulted mode is to link according to the sequence of the points and form a polygon.

After using TRIANGLE_STRIP , it will form a triangle with the former three coordinates. Latter, every coordinate increased will form a new triangle with the former two coordinates. Through this mutual replace mode, connecting the climax of the bottom face and then the climax of the top face, it will form a curved face.

You don't need to fully understand this section of code related to cylinder. As with your study becomes deeper, you will find lots of functions and libraries are sealed already. It is not a necessary for designers to over study these fundamental knowledge. After all, creation is your final goal. You just have to know how to invoke.

In addition to these drawing functions that contains volume, we have mentioned functions like line, triangle, rect, ellipse under two dimensional view can be displayed in three dimensionla space properly. However, these functions have x, y axle only. To show depth, you have to move the coordinate system horizontally combing with function translate. Among it, function line is very special. It allows overlapping. You can write an extra z coordinate into code of coordinate.

3D Drawing Function - Comprehensive Example 01

Because graphic drawing is more or less the same, here we do not list the usage of each function separately. The following is an integrated example.

Code Example (13-4):

[cceN_cpp theme="dawn"] int index;

void setup() {

size(700,700,P3D);

}

void draw() {

background(0);

translate(width/2, height/2);

rotateX(millis() * 0.001);

rotateY(millis() * 0.0015);

noFill();

stroke(255);

strokeWeight(3);

switch (index) {

case 0:

box(300);

break;

case 1:

sphereDetail(12);

sphere(180);

break;

case 2:

line(-200, 0, 200, 0);

break;

case 3:

triangle(150, -200, 0, 150, -150, -200);

break;

case 4:

rectMode(CENTER);

rect(0, 0, 300, 300);

break;

case 5:

ellipse(0, 0, 400, 400);

break;

default:

break;

}

}

void keyPressed() {

if (keyCode == LEFT) {

index--;

if (index < 0) {

index = 5;

}

}

if (keyCode == RIGHT) {

index++;

if (index > 5) {

index = 0;

}

}

} [/cceN_cpp]

Operate Effect:

Code Explain:

In order to gain a richer visual angle change, there is a little difference for the rotating speed between rotateX and rotateY.which is

To observe the volume of the space, we have used function noFill to display frame only.

LEFT, RIGHT as special key value separately represents the left key and right key of the direction key. Variable index stands for different mode. The left key and right key can shift different graphics.

## Step 7: Camera Control

In the following, we will introduce the usage of camera, with which you can control the window angle more flexibly. To use camera, we have to use a library called "PeasyCam". This is not built in the Processing. So you have to download from Libraries and install it.

After installation completed, you can use the following code.

Code Example(13-5):

[cceN_cpp theme="dawn"] import peasy.*;

PeasyCam cam;

void setup() {

size(700,700,P3D);

cam = new PeasyCam(this, 600);

}

void draw() {

background(0);

stroke(255);

noFill();

strokeWeight(3);

box(300);

} [/cceN_cpp]

Operate Effect:

Code Explain:

When initializing the object of PeasyCam, the defaulted camera is point to the origin of the coordinate. The second parameter within indicates the distance between camera and the object.

PeasyCam has integrated multiple functions that are very convenient to use. Below is the operation method.

Operation Method:

Drag the left key of your mouse (or move three fingers on your laptop touch board ), it will center on the origin to rotate camera angle.

Drag the right key of your mouse ups and downs (or move two fingers on your laptop touch board), it will pull or push the camera to generate the change of near and far.

Drag the left key of your mouse, together with pressing Command key: to move camera horizontally.

Double click the left key of your mouse: restore the initial angle of the camera.

An advantage to use PeasyCam is the coordinate origin will be defaulted to centralize on the screen center. Thus you don't have to use translate(width/2,height/2) every time.

## Step 8: Light System

Talking about three dimensional drawing, we have to refer to light. To make the object obtains a three dimensional feeling, light is necessary. Processing has provided multiple types of light. If you have ever used three dimensional softwears like 3dMax, Maya before, you won't feel strange towards it.

Here's light types available to be used in Processing.

Ambient Light: light has been fully dispensed in the environment with balanced intensity, no light source position and direction.

Directional Light: When a light source located have an unlimited farness towards the object, it will generate Directional Light. In the program, you don't have to set the position but the direction. It is often used to analog sunshine.

Point Light: The light source of point light usually emit out from a certain point. It has same light intensity in each direction and decay along with the direction. It is often used to simulate lamp light.

Spot Light: Spot light is a stage light. The light emitted is close to a cone. It has multiple parameters like angle, concentration ratio, etc..

Take point light as an example.

Code Example (13-6):

[cceN_cpp theme="dawn"] import peasy.*;

PeasyCam cam;

void setup() {

size(700, 700, P3D);

cam = new PeasyCam(this, 500);

}

void draw() {

background(0);

// Startup light.

pushMatrix();

pointLight(255, 255, 255, -150, -150, 150);

rotateX(millis() * 0.0005);

rotateY(millis() * 0.0005);

noStroke();

box(250);

popMatrix();

// Draw light position.

noLights();

translate(-150, -150, 150);

fill(255);

sphere(10);

} [/cceN_cpp]

Operate Effect:

Code Explain:

Function pointLight is used to startup point light in the scenario. When using, it

must be placed in the function draw, then functions behind will be influence by point light so as to produce light effect. The former three parameters stand for the color of the light source, while the latter three parameters stand for the coordinate of the light source in space.

Because light itself can not be drawn by the program, in order to make it more intuitive, we can draw it by manual. For example, we use sphere to show the light coordinate. The effect of function noLights() is to close light. Thus the sphere will not be influenced by the light. Then we color it with the method of flat coated. If we don't use noLights(), the outer surface will not be illuminated due to the position of point light in the program is just located at the center of the sphere. Below is the effect without using noLights().

A point worthwhile to be noted is the position of light source will be affected by functions like rotate, translate. In the example, to fix the position of light source at (-150, -150, 150), we write it before rotateX and rotateY.

## Step 9: More About Light System

In the below, we use a comprehensive case to understand the usage of each type of light.

Code Example (13-7):

[cceN_cpp theme="dawn"] import peasy.*;

PeasyCam cam;

int index, lightMode;

void setup() {

cam = new PeasyCam(this, 600);

size(700, 700, P3D);

}

void draw() {

background(50);

if (lightMode == 0) {

ambientLight(255, 0, 0);

} else if (lightMode == 1) {

directionalLight(0, 255, 0, mouseX, mouseY, 0);

} else if (lightMode == 2) {

// Draw point light position.

pushMatrix();

translate(-200, -200, 200);

fill(255);

sphere(10);

popMatrix();

// Startup point light.

pointLight(0, 0, 255, -200, -200, 200);

} else if (lightMode == 3) {

// Draw spot light position.

pushMatrix();

translate(0, 0, 300);

fill(255);

sphere(10);

popMatrix();

// Startup spot light.

spotLight(255, 255, 255, 0, 0, 300, 0, 0, -1, mouseX/float(width), mouseY/float(height) * 1000);

}

pushMatrix();

rotateX(millis() * 0.001 * 0.3);

rotateY(millis() * 0.0015 * 0.3);

noStroke();

switch (index) {

case 0:

box(300);

break;

case 1:

sphereDetail(200);

sphere(180);

break;

case 2:

stroke(255);

strokeWeight(3);

line(-200, 0, 200, 0);

break;

case 3:

triangle(150, -200, 0, 150, -150, -200);

break;

case 4:

rectMode(CENTER);

rect(0, 0, 300, 300);

break;

case 5:

ellipse(0, 0, 400, 400);

break;

default:

break;

}

popMatrix();

}

void keyPressed() {

if (keyCode == LEFT) {

index--;

if (index < 0) {

index = 5;

}

}

if (keyCode == RIGHT) {

index++;

if (index > 5) {

index = 0;

}

}

if (keyCode == UP) {

lightMode--;

if (lightMode < 0) {

lightMode = 3;

}

}

if (keyCode == DOWN) {

lightMode++;

if (lightMode > 3) {

lightMode = 0;

}

}

} [/cceN_cpp]

Operate Effect:

Ambient Light:

Directional Light:

Point Light:

Spot Light:

Code Explain:

On the keyboard, the left key and right key can shift graphics, while the upward and downward key can shift light mode.

Same with point light, Ambient Light, Directional Light, spot light have to be written into function draw.

Function ambientLight() can create Ambient Light. The 3 parameters inside stand for the color of light source, separately corresponding to R,G,B. Ambient light emits uniform light beam from all directions. So once the ambient light is set to red in the example, the color on the surface of the object is uniform.

Function directionalLight() creates Directional Light. The former 3 parameters stand for the color of light source, separately corresponding to R, G, B. The latter 3 parameters stand for the light direction, spearately corresponding to x, y, z axle. Here we have used mouseX and mouseY as parameter. Therefore, we can change the direction of light source by moving the mouse.

Point light and spot light have specific positions. In order to display it more visually, we use sphere in its front to draw light.

Function spotLight() creates spot light. It has the most complex parameters with the quantity up to 11. The former 3 parameters stand for the color of light source, separately corresponding to R, G, B. The latter 3 parameters stand for the position of spot light. And the 3 parameters followed stand for the direction of spot light, separately corresponding to x, y, z axle. The second parameter in the last means the angle of light cone. The last parameter means concentration (fuzzy degree of the light edge).

Except for function line, other drawing functions will be influenced by the light.

## Step 10: Light Comprehensive Example 01

Code Example (13-8):

[cceN_cpp theme="dawn"] void setup() {

size(700, 700, P3D);

}

void draw() {

background(0,50,71);

translate(width/2, height/2);

pointLight(255, 0, 255, 200, -200, 200);

pointLight(0, 255, 255, -200, 200, 200);

int num = 5;

float interval = 120;

float w = (num - 1)* interval;

for (int i = 0; i < num; i++) {

for (int j = 0; j < num; j++) {

pushMatrix();

translate(-w/2 + i * interval,-w/2 + j * interval);

rotateX(millis()/1000.0 + i * 0.1);

rotateY(millis()/1000.0 + j * 0.1);

noStroke();

box(65);

popMatrix();

}

}

} [/cceN_cpp]

Operate Effect:

Code Explain:

Like the actual light, light effect in the program can be overlapped. Here we have set two point light with different color and position so as to make the object become more layered.

Local variable w stands for the width of the whole matrix, which we can calculated through the space and the quantity of cube. After we have obtained the value of w, then we can count offset value and make the whole matrix centralized to the screen center.

Light Comprehensive Example 02

Code Example (13-9):

[cceN_cpp theme="dawn"] int num;

float []x,y,z;

void setup() {

size(700, 700, P3D);

num = 50;

x = new float[num];

y = new float[num];

z = new float[num];

for (int i = 0; i < num; i++) {

x[i] = random(-200, 200);

y[i] = random(-200, 200);

z[i] = random(-200, 200);

}

}

void draw() {

colorMode(RGB);

background(79, 50, 127);

translate(width/2, height/2);

pointLight(255, 0, 0, 200, -200, 200);

pointLight(255, 0, 255, -200, 200, 200);

rotateX(millis() / 1000.0);

rotateY(millis() / 1000.0);

for (int i = 0; i < num; i++) {

pushMatrix();

translate(x[i], y[i], z[i]);

rotateX(i * 0.2 + millis() * 0.004);

rotateY(i * 0.3 + millis() * 0.004);

noStroke();

box(30,10,90);

popMatrix();

}

for (int i = 0; i < num - 1; i++) {

if (random(1) < 0.08) {

colorMode(HSB);

stroke(random(255),255,255);

strokeWeight(4);

line(x[i], y[i], z[i], x[i + 1], y[i + 1], z[i+1]);

}

}

} [/cceN_cpp]

Operate Effect:

Code Explain:

The effect of colorMode(HSB) is to set HSB color mode. Thus it can control the hue of line and make it generate random change. Because the background parameter adopts RGB mode, so we need to use colorMode(RGB) in the beginning to shift mode back to RGB.

The second for loop is to link lines randomly to the other object.

## Step 11: Conclusion of Light System

The light system in Processing has two features. One is no shadow, the other is no mutual influence between objects and no light reflection nor refraction. So its sense of reality is not better than game engines like Unity, and the exquisite degree of the screen is hardly reach the effect created by softwares like C4D, Maya.

Despite this, as a light that is not so highly simulated and completed, only if we adjust the parameters right, it can also have a good three dimensional expression. If you feel that's still not enough for your creation, you can try some more senior contents- Shader Programming, with which you will not have the above limitation any more. You can dig out the performance of your graphics thoroughly with GPU.

If you want to know more about Shader, I would like to recommend the entry tutorial of Patricio(http://thebookofshaders.com/) to you.

There are more splendid artworks on the website of shadertoy. You can know the glamour of shader from https://www.shadertoy.com/ .

END

Till now, the fundamental part is over. Looking back to the writing of the previous half part, the whole process is not easy. As a fundamental course, we must illustrate the core conceptions clear under the limited conditions. We have to make it easy to be understand, meanwhile attaching some funny concise examples. As an initial draft, I personally think it is ok.

In the way to improving programming skills, we have to abide by a certain "Eighteen Laws". We only have to grasp 20% core conceptions only, then we can solve 80% problems. Although the knowledge points referred in the previous half part has not reached 20 % from afar, only if we have laid a solid foundation, we can better dive deeper into the programming world at will.

## Step 13: Source

If you have any questions, you can contact： louise@elecfreaks.com.

## Recommendations

• ### FeatureCAM for Lathes Class

937 Enrolled