# How to convert a list of 3D points to a list of distances?

How do I apply a function (this case EuclideanDistance) between element i and i+1 on a list with points?

It should return a new list that is one element shorter than the input list.

• EuclideanDistance @@@ Partition[list, 2, 1]? Alternatively, Norm /@ Differences[list]? May 31, 2015 at 7:39
• Thank you! I guess it was so basic so it was not easy to find in documentation. :-) May 31, 2015 at 7:45
• Possible duplicate: 4061
– shrx
May 31, 2015 at 14:43

## 2 Answers

nPoints = 9;
lst = RandomReal[{-1, 1}, {nPoints, 3}];
lst = Partition[lst, {2}, 1]
EuclideanDistance[First[#], Last[#]] & /@ lst


ps. after posting saw Guesswhoitis above. I think using @@@ is nicer there. I used simple Mapping to do the job. So for completion, a less typing solution is as shown above by Guesswhoitis which is

 EuclideanDistance @@@ Partition[list, 2, 1]  (*not my code, see comment above*)

• Why not edit your answer to include it? :) May 31, 2015 at 8:11
• @Guesswhoitis. ok, for completion, I also added your solution. thanks May 31, 2015 at 8:18
f0 = EuclideanDistance @@@ Partition[#, 2, 1] &; (* Nasser's post*)
f1 = Norm /@ Differences@# &; (* Guesswhoitis's comment *)
f2 = Compose[EuclideanDistance @@@ # &, Partition[#, 2, 1] &, #] &;
f3 = Composition[EuclideanDistance @@@ # &, Partition[#, 2, 1] &];
f4 = DeveloperPartitionMap[EuclideanDistance @@ # &, #, 2, 1] &;
f5 = Table[EuclideanDistance @@ #[[{i, i + 1}]], {i, Length[#] - 1}] &;
f6 = EuclideanDistance @@@ Transpose[{Most@#, Rest@#}] &;
f7 = Thread[foo[Most@#, Rest@#]] /. foo -> EuclideanDistance & ;
f8 = MapThread[EuclideanDistance, {Most@#, Rest@#}] &;
f9 = MapThread[EuclideanDistance, Transpose@Partition[#, 2, 1]] &;
funcs = {f0, f1, f2, f3, f4, f5, f6, f7, f8, f9};
labels = {"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9"};

SeedRandom[3210]
lst = RandomReal[{-1, 1}, {10, 3}];
Equal @@ (Through@funcs@lst)
(* True *)


Timings:

SeedRandom[3210]
testlst1 = RandomReal[{-1, 1}, {100000, 3}];
res = ConstantArray[0, 10];
i = 1;
timings1 = First[AbsoluteTiming[res[[i++]] = #@testlst1]] & /@ funcs;
Equal @@ res


True

testlst2 = RandomReal[{-1, 1}, {1000000, 3}];
res = ConstantArray[0, 10];
i = 1;
timings2 = First[AbsoluteTiming[res[[i++]] = #@testlst2]] & /@ funcs;
Equal @@ res


True

Grid[Join[{{"",  "Function", Column[{"Timings", "Sample size"}, Alignment -> Center],
SpanFromLeft}}, {{SpanFromAbove, SpanFromAbove, "100 000", "1 000 000"}},
Transpose[{labels, funcs, timings1, timings2}]],
Dividers -> All, ItemStyle -> {Automatic, {Automatic, Automatic, Directive[Bold, Red]}}]


Variations:

legendF = With[{pairs = DeveloperPartitionMap[{#, EuclideanDistance@@#} &@# &, #, 2, 1]},
Grid[Join[{{"pair", "points", "distance"}},
MapIndexed[{First@#2, #[[1]], #[[2]]} &, {Column[#1], #2} & @@@ pairs]],
Dividers -> All]] &;

g3dF = With[{ed = EuclideanDistance @@ #}, {Hue[RandomReal[]],
Arrowheads[{(1/25) ed}] , Arrow[Tube[#, (1/50) ed]]}] &;

g3d = Graphics3D[{Sphere[#, .05] & /@ lst,
DeveloperPartitionMap[g3dF, lst, 2, 1]}, ImageSize -> 400];
legend = legendF@lst // Style[#, 16] &;

Legended[g3d, legend]
`