![]() |
The C++ AffVector Class |
Instances of class AffVector encapsulate the notion of 3D geometric vectors. Such geometric vectors are an example of the more general mathematical notion of vector spaces:
Definition: An n-dimensional vector space consists of a set of vectors and two operations: addition and scalar multiplication. The vector space is closed under these two operations: addition of two vectors yields a vector in the vector space; multiplication of a vector by a scalar also produces a vector in the vector space. Finally, there exists a distinguished member of the set called the zero vector 0 with the properties that a* 0 = 0 for all scalars a, and 0 + v = v + 0 = v for all vectors v. |
The methods specified here provide an implementation of these and other operations (cross products, dot products, etc.). Also included are methods involving instances of class AffPoint. This class encapsulates the notion of points in an n-dimensional affine space.
While every attempt is made to keep these html pages current as new releases of the utilities are made available, there is no guarantee that all operations in a given release will be documented here. While all the fundamental operations are, look around the header files for additional methods that may have been added but not yet documented here.
In the following, assume that instances of AffVector called u, v, w, and n have been declared and initialized.
if (u == v) op1(u); else op2(u,v); |
if (u != v) op2(u,v); else op1(u); |
As is the case with AffPoint, indexing like this is read-only, however the fields (dx, dy, and dz) are public and can be manipulated directly. However, as stated in the AffPoint documentation, direct access to the fields should be rarely used. The overloaded arithmetic operators defined in the various cryph classes usually provide adequate functionality in a more compact and less error-prone fashion.
In the following, assume we also have two instances of class AffPoint called R and Q.
then we are guaranteed that (i) u will be unchanged, (ii) v will be a zero vector if and only if u is a zero vector, and (iii) the dot product of u and v will be zero. (That is, they will be perpendicular to each other.)
(See also the class method cross.)
AffVector vPar, vPerp; n.decompose(v, vPar, vPerp);
(See also the class method dot.)
AffVector u(-13.1, 22.8, -47.2); int index = -1; double val = u.maxAbsComponent(index); // on return, val==-47.2 and index==2 (i.e., index==DZ)
AffVector u(-13.1, 22.8, -47.2); int index = -1; double val = u.minAbsComponent(index); // on return, val==-13.1 and index==0 (i.e., index==DX)
AffVector u(-1.0, 1.0, 2.0); double originalLength = u.normalize(); // on return: u==(-1.0/sqrt(6), 1.0/sqrt(6.0), 2.0/sqrt(6)) // originalLength==sqrt(6)
AffVector u(-1.0, 1.0, 2.0); AffVector n; double originalLength = u.normalizeToCopy(n); // on return: u==(-1.0, 1.0, 2.0) i.e., it is unchanged // n==(-1.0/sqrt(6), 1.0/sqrt(6.0), 2.0/sqrt(6)) // originalLength==sqrt(6)
if (u.parallelTo(v)) // it is ... else // it isn't ...
The following constants are AffVector class variables that can be used in your programs.
For example:
AffVector tryThisVec = 3.2*AffVector::xu + AffVector::yu.cross(u); if (tryThisVec == AffVector::zeroVector) cout << "Uh-oh\n";
See the description of the class methods ioFormat, inputFormat, and outputFormat below for an example of the use of these public constants.
The following class methods are available. Notice that cross and dot methods are defined both as instance methods (see above) and as class methods here. Being available as a class method in addition to an instance method provides flexibility to the programmer. Class methods can be passed as parameters, for example to be used as callback functions in an ANSI C program. Alternatively, if a product involving arithmetic combinations of vectors is desired, the class method can be used instead of creating a new vector. For example:
AffVector myVec = AffVector::cross( u , w+n ); // computes u x (w+n)
double val = AffVector::dot( u , w+n ); // computes u . (w+n)
cin >> myVec; cout << "myVec = " << myVec << '\n';
Assuming the default conditions specified, if the input is:
13.2 -1.2 -0.334
then the output will be:
myVec = (13.2, -1.2, -0.334)
The methods inputFormat and outputFormat allow you to change these assumptions for the input and output operators, respectively. The ioFormat method is equivalent to invoking both inputFormat and outputFormat with the given parameters.
The two valid values for "ioAspect" are AffVector::openDelimiter and AffVector::separator. The former allows you to specify which, if any, opening and closing symbols are used. The latter allows you to specify what separator is to appear between the x, y, and z components. Consider the following code:
// On input, assume a comma between components of a vector: AffVector::inputFormat(AffVector::separator, ','); // On output, use braces around the components AffVector::outputFormat(AffVector::openDelimiter, '{'); AffVector myVec; cin >> myVec; cout << "myVec = " << myVec << '\n';
If the input is:
13.2, -1.2, -0.334
then the output will be:
myVec = {13.2, -1.2, -0.334}
Any character string can be specified for any of these formatting options (subject to a maximum length). For the "open" strings, a matching closing character string will be generated by matching each input character with an "inverse". If, for example, the string "(*\n" is specified as the openDelimiter, then "\n*)" is generated as the closing delimiter.
The input operator does not actually check for an exact match on delimiters and separators. Instead it knows the number of nonblank characters in each, and it simply skips that many nonblank characters on input. While it is not recommended that you exploit this, the implication is that, given the code in the first column of the table below, the input as indicated in the second column, the output will be as shown in the third column.
AffVector::ioFormat( AffVector::separator,", "); AffVector::ioFormat( AffVector::openDelimiter, "(** "); AffVector v; cin >> v; cout << v; |
x yz 1.1 r -2.1 # 3.7 @ $ % |
(** 1.1, -2.1, 3.7 **) |
As with the open delimiter, more general character strings can be specified such as " ,\n".