# How-to cast a set of random points on the surface of a cuboid?

I have been able to implement point picking for cylinders and spheres. However, I struggle to implement a solution for a cuboid.

Please see code for point generation on cylinders and spheres below:

Cylinder:

 Point[Table[{radius*Cos[#1], radius*Sin[#1], #2} &[
RandomReal[{0, 2 Pi}], RandomReal[{p1[[3]], p2[[3]]}]], {expNo}]];


Sphere:

 Point[Table[{Cos[#1] Sqrt[1 - #2^2], Sin[#1] Sqrt[1 - #2^2], #2} &[


In both cases {expNo} denotes a number of points;

How could I do the same for a Cube?

I consulted MathWorld on how to do this, but I was unsuccessful in implementation.

• By your two examples, I infer that you want a uniform distribution, yes? You know how to generate random points on a rectangle, don't you? – J. M. will be back soon Oct 24 '15 at 23:07
• @J.M. Yes, I would be interested in a uniformly distributed set of points. However, I fail at implementation. For rectangle, I would simply generate a set {x,y} in a necessary range? – e.doroskevic Oct 24 '15 at 23:17
• That's correct; I will assume you know how to do this in 3D. Now, you need to generate on the faces of a cuboid, so: use RandomChoice[] for picking any of the six faces, using the area of each face as the weight (thus, RandomChoice[{area1, area2, …} -> {1, 2, …}]). Having picked a face in this manner, use your method of picking points in a rectangle. – J. M. will be back soon Oct 24 '15 at 23:30
• I have struggled to implement this in 3d, thank you for giving me some pointers. I will try again! @J.M. – e.doroskevic Oct 24 '15 at 23:36
• As for efficiently generating points on cylinders and spheres: Append[Normalize[RandomVariate[NormalDistribution[], 2]], RandomReal[]] and Normalize[RandomVariate[NormalDistribution[], 3]]. – J. M. will be back soon Oct 25 '15 at 14:31

Using RandomPoint (available in Mathematica 10.2 or later):

c = Cuboid[];
pts = RandomPoint[RegionBoundary[c], 5000];
Graphics3D[Point[pts], Boxed -> False]


Check the average distance to the centroid

Mean[Map[Norm[# - RegionCentroid[c]] &, pts]]

(* 0.640991 *)

• nice use of new functionality ! – Vitaliy Kaurov Oct 25 '15 at 0:36
• Should be noted -- this requires V10.2 or later. – m_goldberg Oct 25 '15 at 3:06
• I'm pretty sure that you once showed me how to do this with the gcc driver (not the generic one, which uses a Windows-specific library syntax). But I cannot find it anywhere. Do you remember? – Szabolcs Oct 26 '15 at 21:21
• @Szabolcs Probably this? – ilian Oct 26 '15 at 21:37
• @E.Doroskevic Cuboid requires pmin and pmax to be true minimum and maximum bounding box coordinates for it, not just opposing corner coordinates. For arbitrary corner coordinates, one can construct the bounding box coodinates and apply them as arguments of Cuboid with Cuboid @@ CoordinateBoundingBox[{pmin, pmax}], or with any list of coordinates spanning the bounding box instead of {pmin, pmax}. – kirma Nov 16 '15 at 8:25

For people on older versions who cannot use RandomPoint[], here is the method I was alluding to in the comments:

BlockRandom[SeedRandom[42, Method -> "Rule30CA"]; (* for reproducibility *)
n = 1*^4; (* number of points *)
pmin = {3, 2, 1}; pmax = {7, 5, 3}; (* cuboid corners *)
rif = Riffle[#, #] &; (* utility function *)
areas = Times @@@ Table[Delete[pmax - pmin, k], {k, 3}];
facs = Table[Drop[{pmin, pmax}, None, {k}], {k, 3}];
pts = With[{zl = (#1 + I #2) & @@@ #1},
Insert[Through[{Re, Im}[RandomComplex[zl]]], #2, #3]] & @@@
RandomChoice[rif[areas] -> Transpose[{
rif[facs], Flatten[Transpose[{pmin, pmax}]],
rif[Range[3]]}], n];
Graphics3D[{{Directive[FaceForm[],
EdgeForm[Directive[AbsoluteThickness[3], Red]]],
Cuboid[pmin, pmax]},
{Directive[AbsolutePointSize[4], Blue], Point[pts]}},
Boxed -> False]]