3
$\begingroup$

I am posting the same code found at an earlier question, although the concept here is totally different.

The following code corresponds to a building-shaped structure.

w = 100;
l = 200;
h = 30;
m = 70;
backwall = {{0, l, 0}, {w, l, 0}, {w, l, h}, {0, l, h}};
side1 = {{0, 0, 0}, {0, 0, h}, {0, l, h}, {0, l, 0}};
side2 = {{w, 0, 0}, {w, 0, h}, {w, l, h}, {w, l, 0}};
floor = {{0, 0, 0}, {w, 0, 0}, {w, l, 0}, {0, l, 0}};
top = {{0, 0, h}, {w, 0, h}, {w, l, h}, {0, l, h}};
front = {{0, 0, 0}, {w, 0, 0}, {w, 0, h}, {0, 0, h}};
leftRoof = {{0, 0, h}, {w/2, 0, m}, {w/2, l, m}, {0, l, h}};
rightRoof = {{w, 0, h}, {w/2, 0, m}, {w/2, l, m}, {w, l, h}};
roofBack = {{w, l, h}, {w/2, l, m}, {0, l, h}};
roofFront = {{w, 0, h}, {w/2, 0, m}, {0, 0, h}};
building = {backwall, side1, side2, floor, front, leftRoof, rightRoof,roofBack, roofFront};
figure =Graphics3D[{Opacity[0.5],Style[Polygon[building,VertexColors -> Map[0.5 + #[[3]]/80 &, building, {2}]],Lighting -> {{"Ambient", White}}]}, Boxed -> False,RotationAction -> "Clip"];
data = RandomReal[60, {100, 3}];
data1 = RandomReal[60, {100, 3}];
redPoints = Graphics3D[{Opacity[0.4], PointSize -> Large,Style[Point[#], Blue]} & /@ data, Boxed -> False,RotationAction -> "Clip"];
bluePoints =Graphics3D[{Opacity[0.4], PointSize -> Large,Style[Point[#], Red]} & /@ data1, Boxed -> False,RotationAction -> "Clip"];
Show[{figure, redPoints, bluePoints}]

and upon evaluation it produces:

house with transparent points

I have 10000 points that need placing, some with coordinates inside the building while the remaining are outside (like the ones circled above).

I have the following two questions:

  1. How can I omit the points that are not within the building?

  2. How do I fill the entire building with points?

Having tried a few things this morning, I still couldn't get it to work as I want so any help is appreciated.

$\endgroup$
4
  • 1
    $\begingroup$ you can use voxelation ... in order to generate random points or alternative methods as in this paper gggj.ujaen.es/vrr/files/P5_final_B&W_3024.pdf you can also check the demo demonstrations.wolfram.com/VoxelDistortion $\endgroup$
    – s.s.o
    Feb 28, 2013 at 12:45
  • 1
    $\begingroup$ What happened to the gas? Did it all escape? Must be a memory leak in your code... $\endgroup$
    – cormullion
    Feb 28, 2013 at 16:19
  • $\begingroup$ @cormullion memory leak in the seance ? $\endgroup$
    – subbu
    Mar 1, 2013 at 5:06
  • $\begingroup$ The 3d lighting looks really good. Thanks for sharing. $\endgroup$ May 20, 2014 at 0:09

2 Answers 2

9
$\begingroup$

The building is contained in the $w \times l \times m$ cuboid. You can generate points inside this and then keep only those in the building.

side[{P_, Q_, R_, ___}, X_] := Det@Differences[{X, P, Q, R}];
getInsidePolyTest[poly_, knownPointInside_] := 
  Module[{known = Positive[side[#, knownPointInside] & /@ poly]}, 
   Function[pt, (known == Positive[side[#, pt] & /@ poly])]];
inBuildingQ = getInsidePolyTest[building, {1, 1, 1}];

pts = Select[
   RandomVariate[UniformDistribution[{{0, w}, {0, l}, {0, m}}], 1000],
    inBuildingQ];
Graphics3D[{FaceForm[Opacity[0.2]], Polygon@building, Point[pts]}]

building

Test adapted from this answer to handle polyhedra with non-consistent orientation of the faces.

$\endgroup$
3
$\begingroup$

If your building is just as simple as the one you posted above, then use RandomReal for several times will be simple and fast.

Use these definitions of data and data1 instead:

f[x_] := If[x < w/2, (m - h)/w 2 x + h, (m - h)/w 2 (w - x) + h]
getdata := (ll = RandomReal[l, {100}];  
            ww = RandomReal[w, {100}];  
            hh = RandomReal[f@#] & /@ ww;
            Transpose[{ww, ll, hh}])
data = getdata; 
data1 = getdata;

Then you get this:

Mathematica graphics


Update:

If you just need to remove the unwanted points in the data you've already got, you can do the following to your data and data1:

data = RandomReal[60, {100, 3}];
data1 = RandomReal[60, {100, 3}];
f[x_] := If[x < w/2, (m - h)/w 2 x + h, (m - h)/w 2 (w - x) + h]
{data, data1} = Select[#, Last@# < f@First@# &] & /@ {data, data1}

Mathematica graphics

$\endgroup$
6
  • $\begingroup$ ,thanks for your answer,sample example purpose only.I mentioned RandomReal,but I have 10000 points.out this points,if any point is out of Building(point will checks boundaries of the width,height,length.),just remove that point from the 10000 points list. but you are changes the point value like,If any point is out of Building,you are changed that point into the inside of the building.I don't want like that. $\endgroup$
    – subbu
    Feb 28, 2013 at 14:32
  • $\begingroup$ @subbu You mean you've already got 10000 specified points and you want to test if they are inside the building and remove the ones outside? $\endgroup$
    – xzczd
    Feb 28, 2013 at 14:36
  • $\begingroup$ exactly it's right,If the point is out of building,remove that point from the 10000 points list. $\endgroup$
    – subbu
    Feb 28, 2013 at 14:57
  • $\begingroup$ @subbu See my edit for the answer. $\endgroup$
    – xzczd
    Feb 28, 2013 at 14:59
  • $\begingroup$ that one also not working.why because, {data, data1} = Select[#, Last@# < f@First@# &] & /@ {{{-50, 0, 20}}, {{100, 200, 29}}}.If you try this example,in my point of View the first point will not appear why because,my Building is in between "0-100" width,but I mentioned {-50,0,20},so I don't want that point but in your code that point also appeared. why because,you are comparing only the z-axes value only. I understood,what's the wrong in your code,I will comapare all(x,y,z) axes values. $\endgroup$
    – subbu
    Feb 28, 2013 at 15:52

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