Tutorials (back to the list of tutorials)

## 3D Vector Math

### Accessing X, Y and Z of Vector

After you create a 3 dimensional vector, you can get each value of x, y and z with the method x(), y() and z().

```import processing.opengl.*;
import igeo.*;

size( 480, 360, IG.GL );

IVec vec = new IVec(20, 10, 0);

double xvalue = vec.x();

IG.p("x value is "+xvalue);

double yvalue = vec.y();

IG.p("y value is "+yvalue);

double zvalue = vec.z();

IG.p("z value is "+zvalue);
```

### Duplicate Vectors

To duplicate a vector variable to another variable, you use dup() method or new IVec() with the existing vector in the argument. You can also use cp() method, which is just an alias of dup().

```import processing.opengl.*;
import igeo.*;

size( 480, 360, IG.GL );

IVec v1 = new IVec(0, 10, 20);

IVec v2 = v1.dup();

IVec v3 = new IVec(v1);

IG.p("vector1 = "+v1);
IG.p("vector2 = "+v2);
IG.p("vector3 = "+v3);
```

You can add 2 vectors by add() method. Note that because add() change the value of the variable itself instead creating a new added value, you have to duplicate beforehand the vector you add another into, to keep the original value.

```import processing.opengl.*;
import igeo.*;

size( 480, 360, IG.GL );

IVec v1 = new IVec(20, 10, 0);
IVec v2 = new IVec(10, 10, 10);
IVec v3 = v2.dup();

// visualizing vectors as arrows
v1.show().clr(1.,0,0);  // red
v2.show().clr(0,0,1.);  // blue
v3.show().clr(1.,0,1.); // magenta

IG.p("v1 = "+v1);
IG.p("v2 = "+v2);
IG.p("v3 = "+v3);
```

Mathematical meaning of vector addition is like the following diagram.

Subtracting vectors is done in the same way with adding. Please use sub() method.

```import processing.opengl.*;
import igeo.*;

size( 480, 360, IG.GL );

IVec v1 = new IVec(20, 10, 0);
IVec v2 = new IVec(10, 10, 10);
IVec v3 = v2.dup();

v3.sub(v1);

// visualizing vectors as arrows
v1.show().clr(1.,0,0);  // red
v2.show().clr(0,0,1.);  // blue
v3.show().clr(1.,0,1.); // magenta

IG.p("v1 = "+v1);
IG.p("v2 = "+v2);
IG.p("v3 = "+v3);
```

Vector subtraction can be diagrammed like the below.

### Multiply/Divide Vectors

To multiply a vector with double, please use mul() method.
To divide a vector with double, please use div() method.

```import processing.opengl.*;
import igeo.*;

size( 480, 360, IG.GL );

IVec v1 = new IVec(10, 20, 30);
IVec v2 = v1.dup();

v2.mul(1.5);

IVec v3 = new IVec(30, -10, -10);
IVec v4 = v3.dup();

v4.div(2.0);

v1.show().clr(1.,0,0); // red
v2.show().clr(1.,1.,0); // yellow
v3.show().clr(0,0,1.); // blue
v4.show().clr(0,1.,1.); // cyan

IG.p("v1 = " + v1);
IG.p("v2 = " + v2);
IG.p("v3 = " + v3);
IG.p("v4 = " + v4);
```

Vector multiplication can be described like the below. Vector division can be seen as multiplication of inverted scalar number.

### Flip Vectors

Use flip() method (it also has aliases of neg() and rev()) to reverse the direction of the vector keeping the same length. You can also get the same result with mul(-1).

```import processing.opengl.*;
import igeo.*;

size( 480, 360, IG.GL );

IVec v1 = new IVec(30, 20, 10);
IVec v2 = v1.dup();

v2.flip();

v1.show().clr(1.,0,0); // red
v2.show().clr(1.,1.,0); // yellow

IG.p("v1 = " + v1);
IG.p("v2 = " + v2);
```

### Length, Distance and Unitization

You can measure the length of the vector by len() method. You can also measure the distance between two vectors by dist() method. To unitize the vector making the length into 1 keeping the same direction, please use unit(). To set the length of a vector, you can use len(double) method putting a double value as length at the argument .

```import processing.opengl.*;
import igeo.*;

size( 480, 360, IG.GL );

IVec v1 = new IVec(10,10,0);

double length = v1.len();

IVec v2 = new IVec(10,-10,0);

double distance = v1.dist(v2);

IVec v3 = v1.dup();

v3.unit();

IVec v4 = v1.dup();

v4.len(10);

v1.show().clr(1.,0,0); //red
v2.show().clr(0,0,1.); //blue
v3.show().clr(1.,1.,0).size(0.5); //yellow w head size 0.5
v4.show().clr(1.,.5,0); //orange

IG.p("length of v1 = " + length);
IG.p("distance between v1 and v2 = " + distance);
IG.p("v3 = " + v3);
IG.p("v4 = " + v4);
```

Those operations can also be described as the following.

### Dot Product

Dot product is an operation to generate one scalar value out of two vectors. Please see the diagram below for the definition. The value of the dot product is related to projection of a vector to another vector and the angle between two vectors.

In IVec class, you can use dot() method with another vector put in the argument. Please note that dot() method is returning a value in double, not a vector.

```import processing.opengl.*;
import igeo.*;

size( 480, 360, IG.GL );

IVec v1 = new IVec(10,20,30);

IVec v2 = new IVec(10,10,10);

double dotValue = v1.dot(v2);

IG.p("dot product = "+dotValue);
```

### Cross Product

Cross product is another product of 2 vectors and in this one, it generates a new vector, not a scalar value. This vector generated by cross product of two vectors is called a cross vector. The most important property of a cross vector is that it is always perpendicular to both of two input vectors. Because of this property, cross product is usually used to produce normal vector of various geometries. See below for the definition and properties.

In iGeo, you can calculate a cross product by cross() with another vector put in the argument. Please note that cross() generates a new vector, without changing the contents of itself. which is different behavior from add/sub/mul/div where the result of the method is contained inside the one of input vectors changing its contents.

```import processing.opengl.*;
import igeo.*;

size( 480, 360, IG.GL );

IVec v1 = new IVec(10, 20, 30);

IVec v2 = new IVec(5, 20, 10);

IVec v3 = v1.cross(v2);

v1.show().clr(1.,0,0);
v2.show().clr(0,0,1.);
v3.show().clr(1.,1.,0);
```

### Angle and Rotation

Angle of two vectors can be measured by angle() method. There are two different way to put arguments in angle() method. The first is just putting one vector to which the angle is measured and this method returns a value from 0 to Pi (unit is radian). The second type of arguments is one vector to which the angle is measured and another vector just to check direction of angle and this returns a value from -Pi to Pi. The second argument doesn't need to be perpendicular to two input vectors but usually it's some vector close to be perpendicular to the two.

```import processing.opengl.*;
import igeo.*;

size( 480, 360, IG.GL );

IVec v1 = new IVec(0, 10, 10);

IVec v2 = new IVec(0, -5, 5);

IVec axisVec = new IVec(1, 0, 0);

double angle1 = v1.angle(v2);

double angle2 = v1.angle(v2, axisVec);

double angle3 = v2.angle(v1, axisVec);

IG.p("angle1 = "+angle1);
IG.p("angle2 = "+angle2);
IG.p("angle3 = "+angle3);
```

To rotate a vector, you use rot() method. There are two different types of arguments. In the first one, you put an axis vector in the first argument and angle in the second argument as a double value (the unit is in radian). The second type of the argument is that you put a center point of rotation as IVec in the first argument and the second is an axis vector and the third is rotation angle.

```import processing.opengl.*;
import igeo.*;

size( 480, 360, IG.GL );

IVec v1 = new IVec(10, 10, 10);

IVec axis = new IVec(0, 0, 10);

IVec v2 = v1.dup();

v2.rot(axis, PI/2);

IVec center = new IVec(10,0,0);

IVec v3 = v1.dup();

v3.rot(center, axis, -PI/2);

v1.show().clr(1.,0,0);
axis.show().clr(0,0,1.);
v2.show().clr(1.,1.,0);
IPoint centerPt = new IPoint(center);
axis.show(center).clr(0,0,1.);
v3.show().clr(1.,.5,0);
```

### Reflect Vectors

To reflect a vector on 3 dimensional plane, you use ref() method. To use this method, you put a vector which specify a plane in space. If you put one vector in the argument, it's read as a normal vector of a plane and the plane is going through the origin. If you put two vectors in the arguments, the first vector is read as a center and the second is normal of a plane and the plane is going through the center.

```import processing.opengl.*;
import igeo.*;

size( 480, 360, IG.GL );

IVec v1 = new IVec(10,10,10);

IVec planeNormal = new IVec(10,0,0);

IVec v2 = v1.dup();

v2.ref(planeNormal);

IVec planeCenter = new IVec(20,0,0);

IVec v3 = v1.dup();

v3.ref(planeCenter, planeNormal);

v1.show().clr(1.,0,0);
planeNormal.show().clr(0,0,1.);
v2.show().clr(1.,1.,0);
new IPoint(planeCenter);
planeNormal.show(planeCenter).clr(0,0,1.);
v3.show().clr(1.,.5,0);
```

### Compare Vectors

To compare two vectors to check if they are pointing the same location (having same x, y and z values), use eq() method with one argument of another vector. This method returns Boolean value and you can use this inside if condition. eq() can take another set of arguments adding a double value at the second argument as resolution of comparison. In this case, eq() returns true when the distance between two vector is smaller than the resolution.

```import processing.opengl.*;
import igeo.*;

size( 480, 360, IG.GL );

IVec v1 = new IVec(70, 20, 90);
IVec v2 = new IVec(50, 50, 40);

for(int i=0; i < 10; i++){
for(int j=0; j < 10; j++){
for(int k=0; k < 10; k++){

IVec v = new IVec(i*10, j*10, k*10);

if( v.eq(v1) ){
new IPoint(v).clr(1.,.8,1.);
}
else if( v.eq(v2, 30) ){
new IPoint(v).clr(1.,0,0);
}
else{
new IPoint(v);
}
}
}
}
```

### Create Difference Vectors

Sometimes when you are using vectors as point locations you would need a difference of two location. In this case, you can get difference vector by dif() method (or its alias diff()) putting a root location vector in the argument. You can do same thing with sub() method. The difference between dif() and sub() is that sub() change the content of the vector itself but dif() creates a new vector without changing the content of the vectors. So, if you use dup() method (or cp() method) with sub(), it's exactly same with dif() as the following two lines are exactly same.

IVec v3 = v2.dif(v1);
IVec v3 = v2.dup().sub(v1);

```import processing.opengl.*;
import igeo.*;

size( 480, 360, IG.GL );

IVec v1 = new IVec(30,-20,-10);

IVec v2 = new IVec(20,0,20);

IVec v3 = v2.dif(v1);

v1.show().clr(1.,0,0);
v2.show().clr(0,0,1.);
v3.show(v1).clr(1.,1.,0);
```

### Create Midpoint/Bisector Vectors

Similarly to dif() method, there are methods to create new vectors out of two vectors. One of those method is mid() to create a new vector of mid point of two vectors. Another method is bisect() to create a new vector of bisector of two vectors. Each of mid() method and bisect() method is equivalent to the following statements with dup() method.

IVec v3 = v1.mid(v2);

IVec v4 = v1.bisect(v2);

```import processing.opengl.*;
import igeo.*;

size( 480, 360, IG.GL );

IVec v1 = new IVec(10,0,0);

IVec v2 = new IVec(10,10,10);

IVec v3 = v1.mid(v2);

IVec v4 = v1.bisect(v2);

v1.show().clr(1.,0,0);
v2.show().clr(0,0,1.);
v3.show().clr(1.,1.,0);
v4.show().clr(1.,.5,0).size(1); // making a head small
```

### Create Summation Vectors

Another method to create a new vector without changing the content of original vectors is summation method sum(). You can put one or more vectors in the argument.

```import processing.opengl.*;
import igeo.*;

size( 480, 360, IG.GL );

IVec v1 = new IVec(20,0,-10);
IVec v2 = new IVec(10,20,30);

IVec total1 = v1.sum(v2); // sum of two vectors

IVec v3 = new IVec(-20,30,-20);
IVec v4 = new IVec(-30,-10,30);
IVec v5 = new IVec(-10,-40,-10);

IVec total2 = v1.sum(v2,v3,v4,v5); // sum of five vectors

v1.show();
v2.show();
v3.show();
v4.show();
v5.show();
total1.show().clr(1.,0,0);
total2.show().clr(0,0,1.);
```

### Create Weighted Summation Vectors

Weighted sum operation is useful when you want to put series of points between two points. There are two different ways to use weighted sum. The method name is still sum() and you can put either one vector and one double value in the argument or one vector and two double values in the argument. These two variations are equivalent to the following methods using dup().

IVec v3 = v1.sum(v2, 0.2, 0.8);

IVec v4 = v1.sum(v2, 0.8);

```import processing.opengl.*;
import igeo.*;

size( 480, 360, IG.GL );

IVec v1 = new IVec(50,0,-10);
IVec v2 = new IVec(30,10,40);

IVec u1 = v1.sum(v2, 0.75, 0.25);
IVec u2 = v1.sum(v2, 0.5, 0.5);
IVec u3 = v1.sum(v2, 0.25, 0.75);

IVec v3 = new IVec(-20,10,-10);
IVec v4 = new IVec(-20,10,30);

IVec u4 = v3.sum(v4, 0.25);
IVec u5 = v3.sum(v4, 0.5);
IVec u6 = v3.sum(v4, 0.75);

v1.show().clr(1.,0,0);
v2.show().clr(0,0,1.);
v3.show().clr(1.,1.,0);
v4.show().clr(1.,.5,0);
u1.show();
u2.show();
u3.show();
u4.show();
u5.show();
u6.show();
```

(back to the list of tutorials)