Function:
path[points_List, directions_List] :=
Block[{disksPurple, pseudoCross, v, h, ints, dirs},
If[Length@directions != Length@points - 1, Print["incorrect input"]; Abort[]];
disksPurple = {Purple, Disk[#, 2] & /@ points};
pseudoCross[p1_, p2_] := {{p1[[1]], p2[[2]]}, {p2[[1]], p1[[2]]}};
dirs = directions /. {v -> {1, 0}, h -> {0, 1}};
ints = Flatten[#, 1] & @ Pick[pseudoCross @@@ Partition[points, 2, 1], dirs, 1];
Graphics[{disksPurple, {Red, Dashed, Line @ Riffle[points, ints]}}]
]
Usage: list of points is the first argument; the second is a list of directions (only first directions) between the consecutive points. E.g., to go from p1
to p2
first vertically, and then horizontally, type v
; to go first horizontally, then vertically - type h
. The reason is that if you go vertically from p1
, you have to go horizontally next to reach p2
, and vice versa.
Examples:
Clear[p1, p2, p3, p4, pts]
p1 = {40, 48}; p2 = {50, 116}; p3 = {63, 160}; p4 = {80, 100};
pts = {p1, p2, p3, p4};
path[pts, {v, v, v}]

path[pts, {h, h, h}]

path[pts, {v, h, h}]

path[pts, {v, h, v}] (* this is correct, just the choice of direction is poor *)

n = 10;
pts = RandomInteger[{0, 100}, {n, 2}];
dir = RandomChoice[{v, h}, Length@pts - 1];
path[pts, dir]

Works also when three consecutive points have their $x$ or $y$ coordinates the same:
path[{{100, 0}, {200, 0}, {300, 0}}, {h, h}]

The same image is obtained with {v, v}
, {v, h}
and {h, v}
; similarly for the vertical alignment.
Incorrect input:
path[{{100, 0}, {200, 0}, {300, 0}}, {h, h, v}]
incorrect input
$Aborted
And finally, there's this funny behaviour when you make a typo in the directions
:
Clear[p1, p2, p3, p4, pts, path]
p1 = {40, 48}; p2 = {50, 116}; p3 = {63, 160}; p4 = {80, 100};
pts = {p1, p2, p3, p4};
path[pts, {v, v, hv}]

AnglePath
, but after playing with it in combination withProjection
,UnitVector
s etc., it turned out to be to cumbersome. $\endgroup$