MathGroup Archive 1998

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: How draw 3D Arrows?


  • To: mathgroup@smc.vnet.net
  • Subject: [mg11306] Re: How draw 3D Arrows?
  • From: SChandler <SChandler@uh.edu>
  • Date: Wed, 4 Mar 1998 01:40:10 -0500
  • Organization: University of Houston
  • References: <6dg8gm$2u3@smc.vnet.net>

Terry Harter wrote:

> Hi All;
>     While I realize that the 'Arrow' package of Mathematica can draw
> *two-dimensional" arrows, the package fails at giving a 3D arrow.
> Anyone  have any ideas or suggestions?   Say I have  2, distinct 3-dim
> points {a,b,c} and {x,y,z}, how do I then draw a 3-dim arrow from
> {a,b,c} to {x,y,z} with the "head" of the arrow at {x,y,z}?   I could
> find nothing on this in MathSource.  Many thanks in advance! .....Terry


>

This issue has come up before.

Here are snippets from prior postings on this newsgroup.

Seth J. Chandler
Associate Professor of Law
University of Houston Law Center

Snippet 1


Martin Kraus :)


(*-------------begin of package, cut
here------------------------------------*)

(* :Title:  Three-Dimensional Arrow Graphics *)

(* :Context: Arrow3D` *)

(* :Author: Martin Kraus (fn141@fen.baynet.de) *)

(* :Summary:
This package introduces the functions Arrow3D[start, finish] and
ArcArrow3D[center, axis1, axis2] to create three-dimensional (curved)
arrows with flat arrowheads. *)

(* :Package Version: 1.0.0 (December 97) *)

(* :Mathematica Version: 3.0 *)

(* :Copyright: Copyright 1997, Martin Kraus*)

(* :History:
   V 0.0 November 1997
*)

(* :Keywords:
        Arrow, Vector, Graphics
*)

(* :Sources:
        Arrow.m
*)

(* :Limitations: *)

(* :Discussion: *)

BeginPackage["Arrow3D`"]

Arrow3D::usage=
"Arrow3D[start, finish, (opts)] generates several graphics primitives
representing an arrow starting at start and ending at finish.  By
default there is a arrowhead of length 0, i.e. no arrowhead.";

ArcArrow3D::usage=
"ArcArrow3D[center, axis1, axis2, (opts)] generates several graphics
primitives representing an arc with arrowhead starting at center+axis1
and ending in the direction of center+axis2. By default there is a
arrowhead of length 0, i.e. no arrow head.";

HeadLength::usage=
"HeadLength is an option to Arrow3D and ArcArrow3D. It describes the
length of the arrowhead.";

HeadWidth::usage=
"HeadWidth is an option to Arrow3D and ArcArrow3D. It describes the
width of the arrowhead, relative to the length of the arrowhead
(specified by HeadLength).";

HeadCenter::usage=
"HeadCenter is an option to Arrow3D and ArcArrow3D. It describes the
location of the center of the base of the arrowhead along the length of
the arrow, as a factor of the length of the arrowhead. That is, if
HeadCenter -> 0, the arrow will be two lines; if HeadCenter -> 1, the
arrowhead will be a perfect triangle; otherwise, the arrowhead will be
four-sided.";

HeadTop::usage=
"HeadTop is an option to Arrow3D and ArcArrow3D. It describes the
location of the top of the arrowhead along the length of the arrow. It
may be used to leave some space at the top for a point, specified by
HeadPointSize.";

HeadPointSize::usage=
"HeadPointSize is an option to Arrow3D and ArcArrow3D. It describes the
size of a point at the top of the arrow, relative to the width of the
whole plot.";

HeadBlockWidth::usage=
"HeadBlockWidth is an option to Arrow3D and ArcArrow3D. It describes the
width of a line at the top of the arrowhead, perpendicular to the
arrow.";

HeadNormal::usage=
"HeadNormal is an option to Arrow3D and ArcArrow3D. It describes the
normal direction of the arrowhead.";

TailLength::usage=
"TailLength is an option to Arrow3D and ArcArrow3D. It works exactly
like HeadLength, but for the tail of the arrow";

TailWidth::usage=
"TailWidth is an option to Arrow3D and ArcArrow3D. It works exactly like
HeadWidth, but for the tail of the arrow";

TailCenter::usage=
"TailCenter is an option to Arrow3D and ArcArrow3D. It works exactly
like HeadCenter, but for the tail of the arrow";

TailTop::usage=
"TailTop is an option to Arrow3D It works exactly like HeadTop, but for
the tail of the arrow";

TailPointSize::usage=
"TailPointSize is an option to Arrow3D and ArcArrow3D. It works exactly
like HeadPointSize, but for the tail of the arrow";

TailBlockWidth::usage=
"TailBlockWidth is an option to Arrow3D and ArcArrow3D. It works exactly
like HeadBlockWidth, but for the tail of the arrow";


Snippet 2

Appended below is some code written by John Novak from Wolfram Research
which does what you want.  This has not yet been included in
StandardPackages.

Cheers,
        Paul

____________________________________________________________________
Paul Abbott                                   Phone: +61-8-9380-2734
Department of Physics                           Fax: +61-8-9380-1014
The University of Western Australia            Nedlands WA  6907
mailto:paul@physics.uwa.edu.au  AUSTRALIA
http://www.pd.uwa.edu.au/~paul

            God IS a weakly left-handed dice player
____________________________________________________________________

(* :Title: Arrow 3D *)

(* :Context: Graphics`Arrow3D` *)

(* :Author: John M. Novak *)

(* :Summary: crude 3D arrow primitive *)

(* :Copyright: Copyright 1996 Wolfram Research, Inc. *)

(* :Package Version: 1.0 *)

(* :Mathematica Version: 3.0 *)

(* :History:
        V1.0 -- March 1996 by John M. Novak *)

(* :Keywords:
        arrow, Graphics3D
*)

(* :Sources:
        Tom Wickham-Jones, "Mathematica Graphics" *)

(* :Discussion:
        This is a package to add crude 3D arrows by using 3D graphics
primitives.
        The main problem with this approach is that arrows don't have an
optimal
        appearance, and distinction between (e.g.) arrows point toward
vs. away
        from the user is difficult to make. On the other hand, it is
readily
        implementable, which is far superior to any other approach
available at
        this time. (The PostScript used in 2D arrows won't layer
correctly in
        3D, nor would 2D primitives; placing 3D planar primitives with
the
        correct orientation has problems with perspective transforms as
well as
        design problems with things like arrows with a small angle
w.r.t. the
        user.) Because of the essentially different approach from 2D
arrows,
the
        package is being made independent of the 2D package for the time
being.
*)

BeginPackage["Graphics`Arrow3D`"]

Arrow3D::usage =
"Arrow3D[start, end] is a 3D graphics primitive representing an arrow in
space. The start point and the end point are given as {x, y, z}
triplets.
Options controlling the length and width of the arrowhead are
available."

Begin["`Private`"]

(* The following routine is based on OrthogonalVectors from Tom
Wickham-Jones' Mathematica Graphics book. *)

anOrthogonalVector[ norm:{_,_,_}] :=
        Block[{pos, a, b, v1},
                pos = If[ VectorQ[ norm, NumberQ],
                                Abs[N[ norm]], norm] ;
                pos = Sort[ Transpose[ {pos, Range[ 3]}]] ;
                {pos, a,b} = Map[ Last, pos] ;
                v1 = ReplacePart[ {0,0,0}, -Part[ norm, a], b] ;
                ReplacePart[ v1, Part[ norm, b], a]
        ]

normalize[vec_] := vec/Sqrt[vec . vec]

(* The following routine 'rotationmatrix' was borrowed from the standard
   package Graphics`SurfaceOfRevolution`. *)

rotationmatrix[axis_,theta_] :=
        Module[{n1,n2,n3},
                {n1,n2,n3} = normalize[axis]//N;
                {{n1^2 + (1 - n1^2) Cos[theta],
                        n1 n2 (1 - Cos[theta]) + n3 Sin[theta],
                        n1 n3 (1 - Cos[theta]) - n2 Sin[theta]},
                {n1 n2 (1 - Cos[theta]) - n3 Sin[theta],
                        n2^2 + (1 - n2^2) Cos[theta],
                        n2 n3 (1 - Cos[theta]) + n1 Sin[theta]},
                {n1 n3 (1 - Cos[theta]) + n2 Sin[theta],
                        n2 n3 (1 - Cos[theta]) - n1 Sin[theta],
                        n3^2 + (1 - n3^2) Cos[theta]}}//N
        ]

Arrow3D[base:{_,_,_},tip:{_,_,_}, polys_:10, len_:0.8] :=
    {Line[{base, tip}],
        mycone[tip - base, base, tip, polys, len]}

Arrow3D[base:{_,_,_}, tip:{_, _, _}, ___] :=
    Point[base]/;base == tip

mycone[vec_, base_, tip_, polys_, len_] :=
    Block[{norm = anOrthogonalVector[vec], theta},
         Map[Polygon[Append[#, tip]]&,
               Partition[Table[base + len vec +
                         (1 - len)/2 norm . rotationmatrix[vec, theta],
                {theta, 0, 2 Pi, 2 Pi/polys}]//N, 2, 1]
         ]
    ]

End[]

EndPackage[]

>





  • Prev by Date: Re: combine two vectors to form matrix
  • Next by Date: Re: Compiling
  • Prev by thread: RE: How draw 3D Arrows?
  • Next by thread: Re: How draw 3D Arrows?