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.
const
function: real dot_product (Point p)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
![]()
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
![]()
Fig. 87.
const
function: Point cross_product (Point p)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
![]()
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)
![]()
Fig. 89.
const
function: real magnitude (void)Returns the magnitude of the
Point
. This is its distance fromorigin
and is equal to sqrt(x^2 + y^2 + z^2).Point P(13, 15.7, 22); cout << P.magnitude(); -| 29.9915
const
function: real angle (Point p)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)
![]()
Fig. 90.
const
function: Point unit_vector (void)These functions return a
Point
with the x, y, and z-coordinates ofworld_coordinates
divided by the magnitude of thePoint
. The magnitude of the resultingPoint
is thus 1. The first version assigns the result to*this
and should only ever be called with assign =true
. Calling it with the argumentfalse
is equivalent to calling theconst
version, with no assignment. Ifunit_vector()
is called with assign and silent bothfalse
, it issues a warning message is issued and theconst
version is called. If silent istrue
, 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