Node:Vector Operations, Next:, Previous:Projecting Points, Up:Point Reference



Vector Operations

Mathematically speaking, vectors and points are not the same. However, they can both be represented as triples of real numbers (in a three-dimensional Cartesian space). It is sometimes convenient to treat points as though they were vectors, and vice versa. In particular, it is convenient to use the same data type, namely class Point, to represent both points and vectors in 3DLDF.

real dot_product (Point p) const function
Returns the dot or scalar product of *this and p.

If P and Q are Points,

          P \dot Q = x_P * x_Q + y_P * y_Q + z_P * z_Q = |P||Q| * cos(\theta)
          
where |P| and |Q| are the magnitudes of P and Q, respectively, and \theta is the angle between P and Q.

Since

          \theta = arccos(P \dot Q / |P||Q|),
          
the dot product can be used for finding the angle between two vectors.
          Point P(1, -1, -1);
          Point Q(3, 2, 5);
          cout << P.angle(Q);
          -| 112.002
          cout << P.dot_product(Q);
          -| -4
          real P_Q_angle = (180.0 / PI)
                           * acos(P.dot_product(Q)
                           / (P.magnitude() * Q.magnitude()));
          cout << P_Q_angle;
          -| 112.002
          


[Figure 86. Not displayed.]

Fig. 86.

If the angle \theta between two vectors P and Q is 90 degrees , then \cos(\theta) is 0, so P \dot Q will also be 0. Therefore, dot_product() can be used as a test for the orthogonality of vectors.

          Point P(2);
          Point Q(P);
          Point Q0(P0);
          Q0 *= Q.rotate(0, 0, 90);
          P *= Q.rotate(0, 45, 45);
          P *= Q.rotate(45);
          cout << P.angle(Q);
          -| 90
          cout << P.dot_product(Q);
          -| 0
          


[Figure 87. Not displayed.]

Fig. 87.

Point cross_product (Point p) const function
Returns the cross or vector product of *this and p.

If P and Q are Points,

          P * Q = ((y_P * z_Q - z_P * y_Q), (z_P * x_Q - x_P * z_Q),
          (x_P * y_Q - y_P * x_Q)) = |P||Q| * sin(\theta) * n,
          

where |P| and |Q| are the magnitudes of P and Q, respectively, \theta is the angle between P and Q, and n is a unit vector perpendicular to both P and Q in the direction of a right-hand screw from P towards Q. Therefore, cross_product() can be used to find the normals to planes.

          Point P(2, 2, 2);
          Point Q(-2, 2, 2);
          Point n = P.cross_product(Q);
          n.show("n:");
          -| n: (0, -8, 8)
          real theta = (PI / 180.0) * P.angle(Q);
          cout << theta;
          -| 1.23096
          real n_mag = P.magnitude() * Q.magnitude() * sin(theta);
          cout << n_mag;
          -| 11.3137
          n /= n_mag;
          cout << n.magnitude();
          -| 1
          


[Figure 88. Not displayed.]

Fig. 88.

If \theta = 0 degrees or 180 degrees, \sin(\theta) will be 0, and P * Q will be (0, 0, 0). The cross product thus provides a test for parallel vectors.

          Point P(1, 2, 1);
          Point Q(P);
          Point R;
          R *= Q.shift(-3, -1, 1);
          Point s(Q - R);
          Point n = P.cross_product(s);
          n.show("n:");
          -| n: (0, 0, 0)
          


[Figure 89. Not displayed.]

Fig. 89.

real magnitude (void) const function
Returns the magnitude of the Point. This is its distance from origin and is equal to sqrt(x^2 + y^2 + z^2).
          Point P(13, 15.7, 22);
          cout << P.magnitude();
          -| 29.9915
          

real angle (Point p) const function
Returns the angle in degrees between two Points.
          Point P(3.75, -1.25, 6.25);
          Point Q(-5, 2.5, 6.25);
          real angle = P.angle(Q);
          cout << angle;
          -| 73.9084
          Point n = origin.get_normal(P, Q);
          n.show("n:");
          -| n: (0.393377, 0.91788, -0.0524503)
          


[Figure 90. Not displayed.]

Fig. 90.

Point unit_vector (const bool assign, [const bool silent = false]) Function
Point unit_vector (void) const function
These functions return a Point with the x, y, and z-coordinates of world_coordinates divided by the magnitude of the Point. The magnitude of the resulting Point is thus 1. The first version assigns the result to *this and should only ever be called with assign = true. Calling it with the argument false is equivalent to calling the const version, with no assignment. If unit_vector() is called with assign and silent both false, it issues a warning message is issued and the const version is called. If silent is true, the message is suppressed.
          Point P(21, 45.677, 91);
          Point Q = P.unit_vector();
          Q.show("Q:");
          -| Q: (0.201994, 0.439357, 0.875308)
          P.rotate(30, 25, 10);
          P.show("P:");
          P: (-19.3213, 82.9627, 59.6009)
          cout << P.magnitude();
          -| 103.963
          P.unit_vector(true);
          P.show("P:");
          -| P: (-0.185847, 0.797999, 0.573287)
          cout << P.magnitude();
          -| 1