Consider a set of trajectories in 3D space, that possibly converge. By visualizing trajectories as arrows the result will look crowded as each arrowhead will be placed where the attractor is. In 2D, the issue can be resolved by using StreamPlot
, which places arrows neatly so that no arrows cross and no arrowheads/tails are placed at the same position. A Stream[...]
object implementing these restrictions seems to be a natural extension to Point
, Line
and Arrow
primitives. Unfortunately, nothing like this exists out of the black box of StreamPlot
. Example image with 3D Arrow
s:
Note, that the result is not a vectorfield in 3D but a set of trajectories (of a 4D ODE on a 3D simplex). Accordingly, I look for solutions which comply to/deal with the following issues:
- Trajectories are specified as lists of points rather than individual vectors of a given position in space.
- A trajectory should be divisible to multiple arrows (streamlines), arranged neatly without any overlap.
- No streamlines should cross.
- A set of streamlines forming a trajectory should have its individual color.
- Arrows shouldn't start or end at the very same position.
- Interpolation of trajectories would be nice.
I have asked this question on Mathgroup (here and answers here), but as I haven't really dealt with the problem since (and did not develop it myself), it is still open. Heike already provided some useful stuff, but I think there is a lot of opportunity for improvement. (Heike, would you care to post your answers here as a solution please?)
Here is an updated toy example (posted without linebreaks not to flood page):
data = {{{0., 0., 1.}, {0.01, 0.01, 0.97}, {0.02, 0.02, 0.95}, {0.03, 0.02, 0.94}, {0.03, 0.02, 0.94}}, {{0., 0.17, 0.83}, {0.01, 0.08, 0.9}, {0.02, 0.04, 0.92}, {0.03, 0.03, 0.93}, {0.03, 0.02, 0.93}}, {{0., 0.33, 0.67}, {0.02, 0.17, 0.81}, {0.03, 0.09, 0.87}, {0.04, 0.05, 0.9}, {0.04, 0.03, 0.91}}, {{0., 0.5, 0.5}, {0.02, 0.28, 0.69}, {0.04, 0.15, 0.8}, {0.05, 0.08, 0.86}, {0.05, 0.05, 0.88}}, {{0., 0.67, 0.33}, {0.02, 0.43, 0.53}, {0.05, 0.26, 0.67}, {0.07, 0.16, 0.75}, {0.08, 0.11, 0.8}}, {{0., 0.83, 0.17}, {0.03, 0.64, 0.31}, {0.09, 0.48, 0.41}, {0.15, 0.4, 0.42}, {0.22, 0.39, 0.36}}, {{0.17, 0., 0.83}, {0.15, 0.01, 0.82}, {0.14, 0.02, 0.82}, {0.13, 0.03, 0.82}, {0.13, 0.04, 0.83}}, {{0.17, 0.17, 0.67}, {0.19, 0.16, 0.64}, {0.22, 0.16, 0.6}, {0.26, 0.19, 0.53}, {0.32, 0.25, 0.41}}, {{0.17, 0.33, 0.5}, {0.22, 0.33, 0.44}, {0.29, 0.38, 0.32}, {0.33, 0.48, 0.17}, {0.3, 0.63, 0.06}}, {{0.17, 0.5, 0.33}, {0.23, 0.52, 0.24}, {0.27, 0.6, 0.12}, {0.23, 0.71, 0.04}, {0.16, 0.81, 0.02}}, {{0.17, 0.67, 0.17}, {0.19, 0.71, 0.08}, {0.17, 0.79, 0.03}, {0.13, 0.85, 0.02}, {0.1, 0.88, 0.01}}, {{0.17, 0.83, 0.}, {0.09, 0.89, 0.01}, {0.07, 0.9, 0.01}, {0.07, 0.91, 0.01}, {0.07, 0.9, 0.01}}, {{0.33, 0., 0.67}, {0.37, 0.02, 0.59}, {0.45, 0.06, 0.48}, {0.53, 0.14, 0.31}, {0.56, 0.29, 0.13}}, {{0.33, 0.17, 0.5}, {0.39, 0.26, 0.34}, {0.42, 0.4, 0.17}, {0.35, 0.57, 0.06}, {0.24, 0.73, 0.02}}, {{0.33, 0.33, 0.33}, {0.36, 0.46, 0.17}, {0.31, 0.62, 0.06}, {0.21, 0.75, 0.02}, {0.14, 0.84, 0.01}}, {{0.33, 0.5, 0.17}, {0.29, 0.65, 0.06}, {0.2, 0.77, 0.02}, {0.13, 0.85, 0.01}, {0.09, 0.88, 0.01}}, {{0.33, 0.67, 0.}, {0.18, 0.81, 0.01}, {0.11, 0.87, 0.01}, {0.08, 0.9, 0.01}, {0.07, 0.9, 0.01}}, {{0.5, 0., 0.5}, {0.62, 0.03, 0.34}, {0.73, 0.1, 0.16}, {0.69, 0.23, 0.06}, {0.53, 0.44, 0.02}}, {{0.5, 0.17, 0.33}, {0.52, 0.32, 0.15}, {0.42, 0.52, 0.05}, {0.27, 0.70, 0.02}, {0.17, 0.81, 0.01}}, {{0.5, 0.33, 0.17}, {0.41, 0.53, 0.05}, {0.27, 0.70, 0.02}, {0.16, 0.82, 0.01}, {0.11, 0.87, 0.01}}};
Graphics3D[{Hue@RandomReal[], Arrow@#} & /@ data]
VectorPlot3D
? $\endgroup$VectorPlot3D
would not be able to arrange arrows likeStreamPlot
does. $\endgroup$ParametericPlot3D
? It would help if you gave us some sample data. $\endgroup$