Application Center - Maplesoft

App Preview:

Classroom Tips and Techniques: Visualizing the Plane Determined by Two Vectors at a Point in Space

You can switch back to the summary page by clicking here.

Learn about Maple
Download Application



Classroom Tips and Techniques: Visualizing the
Plane Determined by Two Vectors at a Point in Space

Robert J. Lopez
Emeritus Professor of Mathematics and Maple Fellow



This month's article amplifies my response to a colleague who recently asked me how Maple might be used to help students visualize the plane determined by two given vectors emanating from a point in Typesetting:-mrow(Typesetting:-msup(Typesetting:-mi(.  For this, we use functionalities from the VectorCalculus, Student[LinearAlgebra], and Physics packages. As such, this makes for an interesting application of the lessons learned in last month's article where, in the article "Vectors in the LinearAlgebra, VectorCalculus, and Physics Packages," we contrasted Maple's different implementations of vectors. 




> Typesetting:-mrow(Typesetting:-mi(

> with(VectorCalculus); -1
BasisFormat(false); -1
with(plots); -1
with(Student[LinearAlgebra]); -1
`:=`(infolevel[Student[LinearAlgebra]], 1); -1
SetDefault(infodigits = 10); -1


Initial Data 


At the point  


> `:=`(P, `<,>`(1, 2, 3))

Vector[column](%id = 151585988)

determine the plane containing the span of the Vectors 


> `:=`(U, RootedVector(root = P, [1, 1, 1]))

Vector[column](%id = 164378420)

> `:=`(V, RootedVector(root = P, [VectorCalculus:-`-`(1), `/`(1, 2), `/`(1, 3)]))

Vector[column](%id = 152525500)

Note our use of the
RootedVector construct from the VectorCalculus package.  This command accepts the root point as a Vector or as a list.  In ensuing graphs, we will need the position vector to point Typesetting:-mrow(Typesetting:-mi(so we anticipated this by entering the point as a Vector. 


Tools from the VectorCalculus Package 


Figure 1 provides a preliminary sketch of the Vectors U, V, Typesetting:-mrow(Typesetting:-mi(, and P.  The resultant Typesetting:-mrow(Typesetting:-mi( is included as a prelude to conceptualizing the span of U and V. 


> PlotVector([P, U, V, VectorCalculus:-`+`(U, V)], scaling = constrained, axes = box, labels = [x, y, z], orientation = [VectorCalculus:-`-`(70), 70], color = black)
PlotVector([P, U, V, VectorCalculus:-`+`(U, V)], scaling = constrained, axes = box, labels = [x, y, z], orientation = [VectorCalculus:-`-`(70), 70], color = black)


Figure 1   Preliminary sketch of the vectors Typesetting:-mrow(Typesetting:-mi(and P 

In Maple 11, the
PlotVector command does not permit mapping different colors to the members of the list of Vectors being plotted.  This shortcoming has been addressed in the forthcoming Maple 12. 


In the typical multivariate calculus course, determining the equation of the plane containing U, V, and Typesetting:-mrow(Typesetting:-mi( is a standard exercise, which starts with computing Typesetting:-mrow(Typesetting:-mi(a normal to the plane. 


> `:=`(N, Typesetting:-delayCrossProduct(U, V))

Vector[column](%id = 163701048)

The vector 


> `:=`(R, VectorCalculus:-`+`(`<,>`(x, y, z), VectorCalculus:-`-`(P)))

Vector[column](%id = 166050080)

lies in the required plane, and hence must be orthogonal to N.  This condition gives the equation of the plane as 


> Typesetting:-delayDotProduct(N, R) = 0

`+`(`-`(`*`(`/`(1, 6), `*`(x))), `-`(`/`(5, 3)), `-`(`*`(`/`(4, 3), `*`(y))), `*`(`/`(3, 2), `*`(z))) = 0 (4.1)

or as  


> VectorCalculus:-`*`(6, `+`(`-`(`*`(`/`(1, 6), `*`(x))), `-`(`/`(5, 3)), `-`(`*`(`/`(4, 3), `*`(y))), `*`(`/`(3, 2), `*`(z))) = 0)

`+`(`-`(x), `-`(10), `-`(`*`(8, `*`(y))), `*`(9, `*`(z))) = 0 (4.2)



> sort(VectorCalculus:-`-`(`+`(`-`(x), `-`(10), `-`(`*`(8, `*`(y))), `*`(9, `*`(z))) = 0), R)

`+`(x, 10, `*`(8, `*`(y)), `-`(`*`(9, `*`(z)))) = 0 (4.3)

or even as 


> VectorCalculus:-`+`(`+`(x, 10, `*`(8, `*`(y)), `-`(`*`(9, `*`(z)))) = 0, VectorCalculus:-`-`(10))

`+`(x, `*`(8, `*`(y)), `-`(`*`(9, `*`(z)))) = -10

Alternatively, the equation of the plane can be given parametrically, via the equations in 


> `:=`(LEFTSIDE, `<,>`(x, y, z)); -1
`:=`(RIGHTSIDE, VectorCalculus:-`+`(VectorCalculus:-`+`(P, Typesetting:-delayDotProduct(s, U, true)), Typesetting:-delayDotProduct(t, V, true))); -1

Vector[column](%id = 152767324) = Vector[column](%id = 164540920)

The parameters Typesetting:-mrow(Typesetting:-mi( and Typesetting:-mrow(Typesetting:-mi( can be eliminated from the equations Typesetting:-mrow(Typesetting:-mi(that is, from 



[x = `+`(1, s, `-`(t)), y = `+`(2, s, `*`(`/`(1, 2), `*`(t))), z = `+`(3, s, `*`(`/`(1, 3), `*`(t)))] (4.4)

either by solving the first two for Typesetting:-mrow(Typesetting:-mi( and Typesetting:-mrow(Typesetting:-mi(, then substituting into the third, or more directly by 


> eliminate(convert([x = `+`(1, s, `-`(t)), y = `+`(2, s, `*`(`/`(1, 2), `*`(t))), z = `+`(3, s, `*`(`/`(1, 3), `*`(t)))], set), {s, t})

[{t = `+`(`*`(`/`(2, 3), `*`(y)), `-`(`/`(2, 3)), `-`(`*`(`/`(2, 3), `*`(x)))), s = `+`(`*`(`/`(1, 3), `*`(x)), `-`(`/`(5, 3)), `*`(`/`(2, 3), `*`(y)))}, {`+`(`-`(x), `-`(10), `-`(`*`(8, `*`(y))), `*`...

Figure 2 provides a graph of this plane, along with the
Vectors Typesetting:-mrow(Typesetting:-mi(and P.  By graphing each Vector separately as an arrow data structure, we are able to color-code the Vectors, with U in black, V in red, Typesetting:-mrow(Typesetting:-mi( in green, and P in blue. Note, however, that the arrow command requires an explicit declaration of the location of any root point that is not the origin.  The arrows obtained by Typesetting:-mrow(Typesetting:-msub(Typesetting:-mi( could be replaced by the simpler PlotVector command used for Figure 1.  In Maple 12, this simplicity will be accompanied with color coordination. 


> `:=`(g[1], implicitplot3d(`+`(x, 10, `*`(8, `*`(y)), `-`(`*`(9, `*`(z)))) = 0, x = VectorCalculus:-`-`(1) .. 3, y = 0 .. 5, z = 0 .. 5, style = patchnogrid, axes = box, labels = [x, y, z], orientation...
`:=`(g[1], implicitplot3d(`+`(x, 10, `*`(8, `*`(y)), `-`(`*`(9, `*`(z)))) = 0, x = VectorCalculus:-`-`(1) .. 3, y = 0 .. 5, z = 0 .. 5, style = patchnogrid, axes = box, labels = [x, y, z], orientation...
`:=`(g[1], implicitplot3d(`+`(x, 10, `*`(8, `*`(y)), `-`(`*`(9, `*`(z)))) = 0, x = VectorCalculus:-`-`(1) .. 3, y = 0 .. 5, z = 0 .. 5, style = patchnogrid, axes = box, labels = [x, y, z], orientation...
`:=`(g[1], implicitplot3d(`+`(x, 10, `*`(8, `*`(y)), `-`(`*`(9, `*`(z)))) = 0, x = VectorCalculus:-`-`(1) .. 3, y = 0 .. 5, z = 0 .. 5, style = patchnogrid, axes = box, labels = [x, y, z], orientation...
`:=`(g[1], implicitplot3d(`+`(x, 10, `*`(8, `*`(y)), `-`(`*`(9, `*`(z)))) = 0, x = VectorCalculus:-`-`(1) .. 3, y = 0 .. 5, z = 0 .. 5, style = patchnogrid, axes = box, labels = [x, y, z], orientation...
`:=`(g[1], implicitplot3d(`+`(x, 10, `*`(8, `*`(y)), `-`(`*`(9, `*`(z)))) = 0, x = VectorCalculus:-`-`(1) .. 3, y = 0 .. 5, z = 0 .. 5, style = patchnogrid, axes = box, labels = [x, y, z], orientation...
`:=`(g[1], implicitplot3d(`+`(x, 10, `*`(8, `*`(y)), `-`(`*`(9, `*`(z)))) = 0, x = VectorCalculus:-`-`(1) .. 3, y = 0 .. 5, z = 0 .. 5, style = patchnogrid, axes = box, labels = [x, y, z], orientation...`:=`(g[2], arrow(P, U, color = black)); -1
`:=`(g[3], arrow(P, V, color = red)); -1
`:=`(g[4], arrow(P, VectorCalculus:-`+`(U, V), color = green)); -1
`:=`(g[5], arrow(P, color = blue)); -1
display([`$`(g[k], k = 1 .. 5)])


Figure 2   Graph of the plane Typesetting:-mrow(Typesetting:-mi(and the vectors U, V, Typesetting:-mrow(Typesetting:-mi(, and P, in black, red, green, and blue, respectively 

Tools from the Student[LinearAlgebra] Package 


Figure 3, drawn by the VectorSumPlot command in the Student[LinearAlgebra] package, contains a graph of the parallelogram of addition, with U in cyan, V in red, and the resultant, Typesetting:-mrow(Typesetting:-mi(in black. 


> `:=`(g[6], VectorSumPlot(U, V, labels = [x, y, z], orientation = [VectorCalculus:-`-`(30), 60])); -1
plottools[translate](g[6], 1, 2, 3)


sum = <0, 3/2, 4/3>

Figure 3   Parallelogram of vector addition showing U, V, and Typesetting:-mrow(Typesetting:-mi(  

By default, the root point for the
VectorSumPlot command is the origin.  We have use the translate command from the plottools package to move the root point to Typesetting:-mrow(Typesetting:-mi(.  We did not load the whole package because it also contains an arrow command that would conflict with the newer arrow command in the plots package. 


Note, finally, that the VectorSumPlot command actually provides the expression for the resultant. 


Figure 4 is drawn with the PlanePlot command from the Student[LinearAlgebra] package.  The input to this command can be any data that determines a plane uniquely.  Thus, it can be the equation of a plane, a normal vector, a point and normal, a point and two vectors parallel to the plane, or a parametric representation in the form of a vector.  If just a normal vector is given, the plane passes through the origin.  To determine the plane through three given points, two vectors parallel to the plane must first be obtained since the three-point form of the plane is not supported by PlanePlot.  Below, we illustrate the syntax for the parametric representation of a plane. 


In Figure 4, we made the plane transparent through planeoptions .  


> PlanePlot([U, V], P, orientation = [VectorCalculus:-`-`(80), 95], labels = [x, y, z], planeoptions = [transparency = .5])


normal vector: <-.9622504485e-1, -.7698003585, .8660254035>

equation of plane: <-.9622504485e-1*x-.7698003585*y+.8660254035*z = .962250448698988459>
point on plane nearest origin: <-.6849315078e-1, -.5479452060, .6164383569>
basis vectors: <1., 1., 1.>, <-1., .5000000000, .3333333333>

Figure 4   Plane containing the vectors U and V and passing through point Typesetting:-mrow(Typesetting:-mi( 

The ancillary information provided by the
PlanePlot command defaults to four digits.  We raised that to ten with the SetDefault command in the Initializations section.  Because of the mechanisms used to display this information, the only way to access it is via a copy/paste operation, which we apply to the equation of the plane. 


> VectorCalculus:-`+`(VectorCalculus:-`+`(VectorCalculus:-`-`(VectorCalculus:-`*`(0.9622504485e-1, x)), VectorCalculus:-`-`(VectorCalculus:-`*`(.7698003585, y))), VectorCalculus:-`*`(.8660254035, z)) = ...

`+`(`-`(`*`(0.9622504485e-1, `*`(x))), `-`(`*`(.7698003585, `*`(y))), `*`(.8660254035, `*`(z))) = .962250448698988459 (5.1)

Dividing through by the coefficient of Typesetting:-mrow(Typesetting:-mi( leads to


> fnormal(VectorCalculus:-`*`(`+`(`-`(`*`(0.9622504485e-1, `*`(x))), `-`(`*`(.7698003585, `*`(y))), `*`(.8660254035, `*`(z))) = .962250448698988459, `/`(1, `*`(coeff(lhs(`+`(`-`(`*`(0.9622504485e-1, `*`...

`+`(`*`(1.0, `*`(x)), `*`(8.0, `*`(y)), `-`(`*`(9.0, `*`(z)))) = -10.

a form that compares favorably with our analytical results from a previous section.


Figure 5 provides a graph of this same plane generated from the parametric representation Typesetting:-mrow(Typesetting:-mi(where Typesetting:-mrow(Typesetting:-mi(  This representation suggests the plane contains the span of U and V translated to the point Typesetting:-mrow(Typesetting:-mi(. 


> PlanePlot(proc (s, t) options operator, arrow; `+`(P, Typesetting:-delayDotProduct(s, U, true), Typesetting:-delayDotProduct(t, V, true)) end proc, showbasis, orientation = [VectorCalculus:-`-`(80), 7...


normal vector: <-.3086067005, -2.468853598, 2.777460299>
equation of plane: <-.3086067005*x-2.468853598*y+2.777460299*z = 3.08606699923948114>
point on plane nearest origin: <-.6849315083e-1, -.5479452055, .6164383563>
basis vectors: <2.160246899, 2.160246899, 2.160246899>, <-3.207134902, 1.603567451, 1.069044966>

Figure 5   Plane given by its parametric representation graphed with PlanePlot command.  Transparency applied interactively. 

The orientation of the normal vector can be arbitrary for this representation of the plane.  As we did earlier, we copy and paste the equation of the plane, obtaining


> VectorCalculus:-`+`(VectorCalculus:-`+`(VectorCalculus:-`*`(.3086067005, x), VectorCalculus:-`*`(2.468853598, y)), VectorCalculus:-`-`(VectorCalculus:-`*`(2.777460299, z))) = VectorCalculus:-`-`(3.086...

`+`(`*`(.3086067005, `*`(x)), `*`(2.468853598, `*`(y)), `-`(`*`(2.777460299, `*`(z)))) = -3.08606699923948114 (5.2)

which we cast into the form 


> fnormal(VectorCalculus:-`*`(`+`(`*`(.3086067005, `*`(x)), `*`(2.468853598, `*`(y)), `-`(`*`(2.777460299, `*`(z)))) = -3.08606699923948114, `/`(1, `*`(coeff(lhs(`+`(`*`(.3086067005, `*`(x)), `*`(2.4688...

`+`(`*`(1.0, `*`(x)), `*`(8.0, `*`(y)), `-`(`*`(9.0, `*`(z)))) = -10.

The basis vectors are actually multiples of U and V, as we discover after first copying and pasting, then normalizing. 


> `:=`(u, `<,>`(2.160246899, 2.160246899, 2.160246899)); -1
map(fnormal, VectorCalculus:-`*`(u, `/`(1, `*`(u[1]))), 2)

Vector[column](%id = 151776660)

> `:=`(v, `<,>`(VectorCalculus:-`-`(3.207134902), 1.603567451, 1.069044966)); -1
map(fnormal, VectorCalculus:-`-`(VectorCalculus:-`*`(v, `/`(1, `*`(v[1])))), 8)

Vector[column](%id = 167412004)

Tools from the Physics Package 



> with(Physics:-Vectors):

As detailed in last month's column article, "Vectors in the LinearAlgebra, VectorCalculus, and Physics Packages," the Physics package provides for three types of vectors, summarized in Table 1. 



Input (Text Mode) 

Math Mode Representation 

Basis Vector 

_i, _j, _k 


Non-Projected Vector 



Projected Vector 

2 *_i + 3 *_j + 5 *_k 


Table 1   Vector types supported by the Physics package 


If we let r be the generic position vector for any point on the plane, and P be the position vector for the point Typesetting:-mrow(Typesetting:-mi(, the vector equation for the plane passing through point Typesetting:-mrow(Typesetting:-mi( and containing the directions U and V can be written as 


> q := (r_ - P_).(U_ &x V_) = 0;

Typesetting:-mprintslash([`:=`(q, `.`(U_, `&x`(V_, `+`(r_, `-`(P_)))) = 0)], [Physics:-Vectors:-`.`(U_, `&x`(V_, `+`(r_, `-`(P_)))) = 0])

The input expression can be converted to math mode by invoking the
Context Menu for it, and selecting Convert To2-D Math Input.  The result is something like 




depending on how Maple normalizes the expression.  (Our equation for the plane is nothing more than the statement that the triple-scalar (box) product between the coplanar vectors U, V, and Typesetting:-mrow(Typesetting:-mi( must vanish.  The Physics package converts such expressions to a normal form, so the output, equivalent to the input, is not necessarily in the exact same form.) 


It is tedious to enter this directly in math mode.  The trailing underscore must be preceded by the escape character: (\).  The dot product can be entered as the alphabetic period or as the bold centered dot from the Common Symbols palette.  The cross-product symbol Typesetting:-mrow(Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mo( can also be entered from the Common Symbols palette, or can be typed as &x, in which case it is not replaced with the cross-product symbol. 


Having written a vector equation for the plane, one must now make substitutions into this formula.  Again, typing in math mode is more tedious than typing in the text mode we use below, where we enter the vectors r, P, U, and V from the Initial Data section, above.  The restart command we executed upon entering this present section erased from Maple's memory the previous values assigned to these symbols.  However, there is no conversion routines to change a Vector to an object the Physics package recognizes as a projected vector, so this data would have to be re-entered anyway. 


> eval(q, [r_ = Physics:-Vectors:-`+`(Physics:-Vectors:-`+`(VectorCalculus:-`*`(x, _i), VectorCalculus:-`*`(y, _j)), VectorCalculus:-`*`(z, _k)), P_ = Physics:-Vectors:-`+`(Physics:-Vectors:-`+`(_i, Vec...

`+`(`*`(`/`(3, 2), `*`(z)), `-`(`/`(5, 3)), `-`(`*`(`/`(4, 3), `*`(y))), `-`(`*`(`/`(1, 6), `*`(x)))) = 0 (6.1)

Of course, this equation compares favorably with our earlier results, especially if we modify it as per 


> sort(VectorCalculus:-`*`(6, `+`(`*`(`/`(3, 2), `*`(z)), `-`(`/`(5, 3)), `-`(`*`(`/`(4, 3), `*`(y))), `-`(`*`(`/`(1, 6), `*`(x)))) = 0), [x, y, z])

`+`(`-`(x), `-`(`*`(8, `*`(y))), `*`(9, `*`(z)), `-`(10)) = 0

In working with non-projected vectors, the issue of substitution of the projected representations generally arises.  The following stratagem is an attempt to make the substitution process a bit less tedious. 


First, define the vectors 


> `:=`(T, Physics:-Vectors:-`+`(Physics:-Vectors:-`+`(VectorCalculus:-`*`(A, _i), VectorCalculus:-`*`(B, _j)), VectorCalculus:-`*`(C, _k)))
`:=`(X, `<,>`(A, B, C))


Typesetting:-mprintslash([`:=`(T, `+`(`*`(A, `*`(_i)), `*`(B, `*`(_j)), `*`(C, `*`(_k))))], [`+`(`*`(A, `*`(_i)), `*`(B, `*`(_j)), `*`(C, `*`(_k)))])
Typesetting:-mprintslash([`:=`(X, Vector[column]([[A], [B], [C]]))], [Vector[column](%id = 164632664)])

Notice that T is a generic projected vector, and X is a "top-level" Vector not specific to the Physics package.  Ordinarily, T would have a trailing underscore, but we are using T as just a symbol, a place-holder, so we can dispense with the additional notation. 


> eval(q, [r_ = eval(T, Equate(X, `<,>`(x, y, z))), P_ = eval(T, Equate(X, P)), U_ = eval(T, Equate(X, U)), V_ = eval(T, Equate(X, V))])

`+`(`*`(`/`(3, 2), `*`(z)), `-`(`/`(5, 3)), `-`(`*`(`/`(4, 3), `*`(y))), `-`(`*`(`/`(1, 6), `*`(x)))) = 0

The Equate command forms the equations arising from equating corresponding components.  These equations are then used as substitution rules in T, which has the correct structure for a projected Physics vector, at which point substitutions can be made for the non-projected Physics vectors. 


Legal Notice: The copyright for this application is owned by the author(s). Neither Maplesoft nor the author are responsible for any errors contained within and are not liable for any damages resulting from the use of this material. This application is intended for non-commercial, non-profit use only. Contact the author for permission if you wish to use this application in for-profit activities.