5
$\begingroup$

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} &[
    RandomReal[{0, 2 Pi}], RandomReal[{-radius, radius}]], {expNo}]];

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.

$\endgroup$
5
  • $\begingroup$ 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? $\endgroup$ Oct 24, 2015 at 23:07
  • $\begingroup$ @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? $\endgroup$ Oct 24, 2015 at 23:17
  • 2
    $\begingroup$ 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. $\endgroup$ Oct 24, 2015 at 23:30
  • $\begingroup$ I have struggled to implement this in 3d, thank you for giving me some pointers. I will try again! @J.M. $\endgroup$ Oct 24, 2015 at 23:36
  • $\begingroup$ As for efficiently generating points on cylinders and spheres: Append[Normalize[RandomVariate[NormalDistribution[], 2]], RandomReal[]] and Normalize[RandomVariate[NormalDistribution[], 3]]. $\endgroup$ Oct 25, 2015 at 14:31

2 Answers 2

24
$\begingroup$

Using RandomPoint (available in Mathematica 10.2 or later):

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

Mathematica graphics

Check the average distance to the centroid

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

(* 0.640991 *) 
$\endgroup$
8
  • 1
    $\begingroup$ nice use of new functionality ! $\endgroup$ Oct 25, 2015 at 0:36
  • 5
    $\begingroup$ Should be noted -- this requires V10.2 or later. $\endgroup$
    – m_goldberg
    Oct 25, 2015 at 3:06
  • $\begingroup$ 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? $\endgroup$
    – Szabolcs
    Oct 26, 2015 at 21:21
  • $\begingroup$ @Szabolcs Probably this? $\endgroup$
    – ilian
    Oct 26, 2015 at 21:37
  • 1
    $\begingroup$ @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}. $\endgroup$
    – kirma
    Nov 16, 2015 at 8:25
4
$\begingroup$

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]]

random points on cuboid surface

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.