Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Given two arbitrary vectors $\textbf{v}_1$ and $\textbf{v}_2$, how can I draw the plane which they span?

share|improve this question
3  
To give a mathematical viewpoint: both Mark's and David S.'s approaches use the Hessian normal form of a plane. I would say that if you're trying to do anything mathematical in Mathematica, MathWorld is one of those places you should try looking for formulae in... –  J. M. Feb 7 '12 at 23:06

7 Answers 7

up vote 17 down vote accepted
SeedRandom[3];
{v1, v2} = RandomReal[{-2, 2}, {2, 3}];
n = Cross[v1, v2];
Show[{
  ContourPlot3D[n.{x, y, z} == 0, {x, -2, 2}, {y, -2, 2}, {z, -2, 2},
    ContourStyle -> Opacity[0.5], Mesh -> False],
  Graphics3D[{Arrow[{{0, 0, 0}, v1}], Arrow[{{0, 0, 0}, v2}]}]
}]

Mathematica graphics

share|improve this answer

Here's an example of how you could do it:

v1 = {1, -1/2, -1.9}; (* pick something *)
v2 = {0, 1, -1}; (* pick something *)
r0 = {-1/2, 1/2, 3/4}; (* point in the plane; pick something *)

nn = Normalize[Cross[v1-r0, v2-r0]];
r = {rx, ry, rz};
sol = Solve[Dot[nn, (r - r0)] == 0, {rz}] // Simplify
Plot3D[rz /. sol, {rx, -10, 10}, {ry, -10, 10}]

enter image description here

share|improve this answer
    
Yeah, this is definitely much better than my idea. –  David Z Feb 7 '12 at 22:53
1  
It seems you've misapplied the formula for the Hessian normal form here. (rz - Last[v1] /. First[Solve[Dot[nn, (r - r0)] == 0, {rz}]]) /. Thread[{rx, ry} -> Take[v1, 2]] ought to be yielding 0, but it doesn't, and similarly for the version where v1 is replaced by v2. There is a simple fix: use nn = Normalize[Cross[v1 - r0, v2 - r0]]; instead for computing the normal vector. –  J. M. Feb 8 '12 at 5:28
    
@J.M. You are, of course, correct--thanks for the correction! I am fixing my answer accordingly. –  David Skulsky Feb 8 '12 at 15:30

If your vectors are three-element lists, here's one way (though I really feel like a hack for suggesting this):

ParametricPlot3D[u v1 + v v2, {u,-1,1},{v,-1,1},
  PlotRange->{{-1,1},{-1,1},Automatic}]

You may have to adjust the limits of -1 and 1 depending on how much of the plane you want to plot.

share|improve this answer

Another option is to use Graphics3D primitives

Graphics3D[Polygon[{{0,0,0},v1,v1+v2,v2}]]

Edit

J.M. already gave one way to produce a square spanned by the two vectors as a Polygon. Another way would be to use Rotate:

{v1, v2} = RandomReal[{-1, 1}, {2, 3}]

Graphics3D[{
  Rotate[Polygon[{{-1, -1, 0}, {1, -1, 0}, {1, 1, 0}, {-1, 1, 0}}],
    {{0, 0, 1}, Cross[v1, v2]}],
  Arrow[{{0, 0, 0}, v1}],
  Arrow[{{0, 0, 0}, v2}]}]

Mathematica graphics

share|improve this answer
    
just ahead of me again! serves me right for trying to put a nice texture on it... –  acl Feb 7 '12 at 22:55
    
@acl Blame David Zaslavsky. I was busy typing a ParametricPlot3D solution but had to switch tactics when his solution popped up. –  Heike Feb 7 '12 at 23:02
    
I think this is the most elegant –  acl Feb 7 '12 at 23:04
1  
The problem with this method (and mine as well) is that you don't get the whole plane, only the piece of it that is directly bounded by the given vectors. So while it is elegant, I think you're answering something a little different from what the question is actually looking for. –  David Z Feb 7 '12 at 23:04
    
@acl at least it's the shortest. –  Heike Feb 7 '12 at 23:05

Interactive - drag orange dots around.

Manipulate[ Graphics3D[{{Blue, Opacity[.5], Polygon[{{-1, -1, 0}, {1, -1, 0}, 
{1, 1, 0}, {-1, 1, 0}}]}, {Red, Thick, Arrow[{{0, 0, 0}, Flatten@{p, 0}}]}, 
{Black, Thick, Arrow[{{0, 0, 0}, Flatten@{q, 0}}]}}, SphericalRegion -> True, 
Boxed -> False, ViewAngle -> .37],{{p, {1, 0}}, {-1, -1},{1, 1}},{{q, {0, 1}}, 
{-1, -1}, {1, 1}}, ControlPlacement -> Left]

enter image description here

share|improve this answer

I present here a modification of Heike's approach that might be attractive for some applications; it produces a square with side length c as a Polygon[] object, representing the plane spanned by v1 and v2, with origin at r0:

v1 = {1, -1/2, -19/10}; v2 = {0, 1, -1}; (* spanning vectors *)
r0 = {-1/2, 1/2, 3/4}; (* origin *)
{o1, o2, o3} = Orthogonalize[Append[#, Cross @@ #]] &[{v1 - r0, v2 - r0}];
With[{c = 6}, (* generate a c×c square *)
   Graphics3D[{{Directive[EdgeForm[], Gray], 
      Polygon[{r0 + c (o1 + o2)/2, r0 - c (o1 - o2)/2, 
               r0 - c (o1 + o2)/2, r0 + c (o1 - o2)/2}]},
              {Red, Arrow[{r0, v1}], Arrow[{r0, v2}]},
              {Blue, Arrow[{r0, r0 + Cross[v1 - r0, v2 - r0]}]}},
              Boxed -> False, Lighting -> "Neutral", PlotRange -> All]]

square spanned by vectors

As can be seen from the code, the trick is in producing mutually orthogonal unit vectors via Orthogonalize[] (for older versions, use QRDecomposition[] instead and take the $\mathbf Q$ factor) that can be nicely scaled/combined afterwards.

Here's how to verify that a square is indeed produced as claimed:

FullSimplify[Map[Norm, Differences[Append[#, First[#]]]]&[{r0 + c (o1 + o2)/2, 
             r0 - c (o1 - o2)/2, r0 - c (o1 + o2)/2, r0 + c (o1 - o2)/2}], c > 0]
{c, c, c, c}
share|improve this answer

Using

v1 = {1, -1/2, -19/10}; v2 = {0, 1, -1}; (* spanning vectors *)
r0 = {-1/2, 1/2, 3/4}; (* origin *)

as a concrete example, I present here, for giggles, variations of Mark's and David Skulsky's answers, based on formula 18 here.

Mark:

Show[ContourPlot3D[
  Det[PadRight[{{x, y, z}, r0, v1, v2}, {4, 4}, 1]] == 0, {x, -3, 
   3}, {y, -3, 3}, {z, -3, 3}, BoxRatios -> Automatic, 
  ContourStyle -> Opacity[0.5], Mesh -> False], 
 Graphics3D[{{Red, Arrow[{r0, v1}], Arrow[{r0, v2}]}, {Blue, 
    Arrow[{r0, r0 + Cross[v1 - r0, v2 - r0]}]}}]]

plane spanned by vectors, ContourPlot3D[] version.

David (plus Heike's suggestion):

Show[Plot3D[
  Evaluate[z /. 
    First[Solve[
      Det[PadRight[{{x, y, z}, r0, v1, v2}, {4, 4}, 1]] == 0, 
      z]]], {x, -2, 2}, {y, -2, 2}, BoxRatios -> Automatic, 
  MaxRecursion -> 1, Mesh -> 0, PlotPoints -> 2], 
 Graphics3D[{{Red, Arrow[{r0, v1}], Arrow[{r0, v2}]}, {Blue, 
    Arrow[{r0, r0 + Cross[v1 - r0, v2 - r0]}]}}]]

plane spanned by vectors, Plot3D[] version.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.