As @MichaelE2 noted in the comments, the lines produced by StreamPlot
are just "a sample from all the stream lines" and the number of them and the extent of each depend on the option settings as well as finer implementation details. Yet, OP seems to be interested in the intersection of lines in a particular instance of StreamPlot
output with specific option settings. The following is an attempt to get the intersection points of the lines shown in a graph produced by StreamPlot
by
- getting the coordinates of
Line
primitives,
- producing an interpolating function for each line taking into account the range of its
x
coordinates,
- solving for the first intersection point for each pair of lines from two different stream plots, and
- adding the points thus obtained to the original stream plots using
Epilog
.
First, the final result (using StreamPoints -> 10
):

Some preps:
(* options to be used later *)
strmPltOpts = {Frame -> True,
FrameLabel -> {Row[{Subscript["x", 2], " - Capacitor Voltage "}],
Row[{Subscript["x", 1], " - Inductor Voltage "}]},
GridLines -> Automatic, GridLinesStyle -> Directive[Gray, Dashed],
BaseStyle -> {"Times", 24}, ImageSize -> 500};
pltOpts = {PlotRange -> {0, 10}, Frame -> True,
FrameLabel -> {Row[{Subscript["x", 2], " - Capacitor Voltage "}],
Row[{Subscript["x", 1], " - Inductor Voltage "}]},
GridLines -> Automatic, PlotStyle -> Thick,
GridLinesStyle -> Directive[Gray, Dashed],
BaseStyle -> {"Times", 24}, ImageSize -> 500, AspectRatio -> 1};
Few helper functions to get the lines, roots, and intersections:
ClearAll[getRootsF, getStrmPltLinesF, getIntrsctnsF];
getStrmPltLinesF[plt_, x_] := Cases[Normal[plt[[1]]],
Line[z_] :> ConditionalExpression[Interpolation[z][x],
Min[First@Transpose[z]] <= x <= Max[First@Transpose[z]]], Infinity];
getRootsF := Quiet[If[# === Undefined, {},
(soln = FindRoot[ First@#,
{x, Sequence @@ {First@#, First@#, Last@#} &@Last[#]}];
{{x /. soln, Last[First[#]] /. soln}, {x /. soln, First[First[#]] /. soln}})]] &;
getIntrsctnsF := First[Flatten[Quiet[getRootsF /@ #] /. {} -> Sequence[] /.
{{x_, y_}, {x_, z_}} /; Chop[y + z] != 0 :>
Sequence[] /. {_, _?Negative} :> Sequence[], {2}]] &;
Step 0: StreamPlot
both original plots with the option setting StreamScale->None
:
plt0B = StreamPlot[Flatten[{f1, f2} /. u -> 0], {x2, 0, 30}, {x1, 0, 10},
StreamPoints -> 10, StreamScale -> None,
StreamStyle -> {Blue, Thickness[0.001], Dotted}, Evaluate@strmPltOpts];
plt1B = StreamPlot[Flatten[{f1, f2} /. u -> 1], {x2, 0, 30}, {x1, 0, 10},
StreamPoints -> 10, StreamScale -> None,
StreamStyle -> {Red, Thickness[0.001], Dotted}, Evaluate@strmPltOpts];
Show[{plt0B, plt1B}]

Steps 1 and 2: Use the helper function getStrmPltLinesF[strmplt, x]
to get an interpolating function for each line in strmplt
. Here is how these interpolating functions look when used in Plot
:
plt0Ba = Quiet@ Plot[Evaluate@getStrmPltLinesF[plt0B, x], {x, 0, 30},
ColorFunction -> "LakeColors", Evaluate[pltOpts]];
plt1Bb = Quiet@ Plot[Evaluate@getStrmPltLinesF[plt1B, x], {x, 0, 30},
ColorFunction -> "SolarColors", Evaluate[pltOpts]];
Show[{plt0Ba, plt1Bb}]

Step 3: get the points of intersection for every pair of lines using the helper function getIntrsctnsF
:
pairwiseDiffs = Join @@ Outer[Subtract, getStrmPltLinesF[plt0B, x],
getStrmPltLinesF[plt1B, x]];
intrsctnPoints = getIntrsctnsF@pairwiseDiffs;
Last step: change the options settings back to the original and add the intersection points using Epilog to one of the two original stream plots:
plt0Bfinal = StreamPlot[Flatten[{f1, f2} /. u -> 0], {x2, 0, 30}, {x1, 0, 10},
StreamPoints -> 10, StreamScale -> Large,
StreamStyle -> {Blue, Thickness[0.001], Dotted}, Evaluate@strmPltOpts,
Epilog -> {Green, PointSize[.02], Point[intrsctnPoints]}];
plt1Bfinal = StreamPlot[Flatten[{f1, f2} /. u -> 1], {x2, 0, 30}, {x1, 0, 10},
StreamPoints -> 10, StreamScale -> Large,
StreamStyle -> {Red, Thickness[0.001], Dotted}, Evaluate@strmPltOpts];
Show[{plt0Bfinal, plt1Bfinal}]
to get the first picture above.