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$
  • $\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$ – J. M. is away Oct 24 '15 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$ – e.doroskevic Oct 24 '15 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$ – J. M. is away Oct 24 '15 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$ – e.doroskevic Oct 24 '15 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$ – J. M. is away Oct 25 '15 at 14:31
23
$\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$
  • 1
    $\begingroup$ nice use of new functionality ! $\endgroup$ – Vitaliy Kaurov Oct 25 '15 at 0:36
  • 5
    $\begingroup$ Should be noted -- this requires V10.2 or later. $\endgroup$ – m_goldberg Oct 25 '15 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 '15 at 21:21
  • $\begingroup$ @Szabolcs Probably this? $\endgroup$ – ilian Oct 26 '15 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 '15 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, privacy policy and cookie policy

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