Skip to content

2. Arithmetic ​

With its vertices set, probe computes with them: an edge, the centroid, and three copies of the body, moved, scaled and stretched. The operators are the ones of the maths.

f90
program probe
!< Tutorial, chapter 2: edges, centroid, a moved, a scaled and a stretched copy of the tetrahedron.
use penf, only : R8P
use vecfor, only : ex, ey, ez, vector
implicit none
type(vector) :: o     ! the origin
type(vector) :: p(4)  ! the vertices
type(vector) :: edge  ! an edge
type(vector) :: c     ! the centroid
type(vector) :: s(4)  ! the vertices of a copy
integer      :: i     ! counter

p(1) = o ; p(2) = ex ; p(3) = ey ; p(4) = ez
edge = p(4) - p(2)                    ! from p2 to p4
call edge%printf(prefix='edge p2->p4  = ')
edge = -edge                          ! the opposite edge
call edge%printf(prefix='edge p4->p2  = ')
c = o
do i = 1, 4
   c = c + p(i)
enddo
c = c / 4                             ! a vector divided by an integer
call c%printf(prefix='centroid     = ')
s = p + (2 * ex - 0.5_R8P * ez)       ! every vertex at once: + works on arrays of vectors
call s(4)%printf(prefix='moved p4     = ')
s = c + 2 * (p - c)                   ! twice as large, about the centroid
call s(4)%printf(prefix='scaled p4    = ')
s = p * (3 * ex + ey + ez)            ! vector * vector: component by component
call s(2)%printf(prefix='stretched p2 = ')
s(1) = p(1) + 1                       ! vector + number: the number is added to every component
call s(1)%printf(prefix='p1 + 1       = ')
endprogram probe
console
$ probe
edge p2->p4  = -1.0, +0.0, +1.0
edge p4->p2  = +1.0, -0.0, -1.0
centroid     = +0.25, +0.25, +0.25
moved p4     = +2.0, +0.0, +0.5
scaled p4    = -0.25, -0.25, +1.75
stretched p2 = +3.0, +0.0, +0.0
p1 + 1       = +1.0, +1.0, +1.0

Between vectors ​

p(4) - p(2) is the edge from p2 to p4, -edge the opposite one: + and - add and subtract the components, and - alone changes their sign. Negating a zero gives -0.0, the negative zero of IEEE arithmetic: it compares equal to +0.0 and does no harm.

* and / between two vectors work component by component: p * (3 * ex + ey + ez) multiplies the x of every vertex by 3 and leaves y and z alone, a stretch along x. They are not the dot product: that is .dot..

With numbers ​

A number multiplies or divides every component: 2 * (p - c), c / 4. It can be an integer or a real of any kind (I1P to I8P, R4P, R8P, R16P), on either side of * and on the right of /; it is converted to the kind of the vector first.

A number added to or subtracted from a vector acts on every component too: p(1) + 1 is (1, 1, 1). This is not a translation along any axis: to move a point, add a vector, as p + (2 * ex - 0.5_R8P * ez) does.

On arrays of vectors ​

p + (2 * ex - 0.5_R8P * ez) and c + 2 * (p - c) act on all four vertices at once: every operator of VecFor is elemental, so it applies to arrays element by element, as the intrinsic operators do on arrays of numbers. A later chapter does the same with the functions.

Fortran has no sum of an array of a derived type, so the centroid is summed in a loop, or component by component (sum(p%x), see Whole arrays of vectors at once).

What you learned

+, -, *, / between vectors (component by component) and with numbers of any kind; a number added to every component; the operators on whole arrays. Reference: Operators.

Next: 3. Lengths and angles.

Released under the GPL v3, BSD 2-Clause, BSD 3-Clause or MIT License.