|
|
This morning I woke up with a solution
to placing a random distribution of points
onto arbitrary objects. I'm not sure if any
of you have ever had one of these dreaming
moments of inspiration, but I figured it was
worth sharing it. I think someone had asked
about something like this, but I've lost the
thread.
Basically, you just check that the distance
from a random point in the bounding to
a trace hit on the object is shorter than
some threshold distance. That way the
random distribution approaches that of
the surface.
Here's a sample scene, with the macro.
#macro RandOnSurface(Obj, rsd, thresh)
#local mn = min_extent(Obj);
#local mx = max_extent(Obj);
#local dist = 1000000;
#while (dist>thresh)
#local flag = 0;
#while (flag = 0)
#local rfrom = VRand_In_Box(mn, mx, rsd);
#local rdir = vrotate(<1,0,0>,
<360*rand(rsd),360*rand(rsd),360*rand(rsd)>);
#declare Norm = <0, 0, 0>;
#local hit = trace(Obj, rfrom, rdir, Norm);
#if (vlength(Norm) != 0)
#local flag = 1;
#end
#end
#local dist = vlength( hit - rfrom);
#end
#local result = hit;
(result)
#end
#declare Bent = merge {
cylinder{<0,-1,0>,<-1,0,0>,0.2}
cylinder{<-1,0,0>,<1,0,0>,0.2}
cylinder{<1,0,0>,<0,1,0>,0.2}
sphere {<-1,0,0>,0.2}
sphere {<1,0,0>,0.2}
};
object {Bent pigment {Blue transmit 0.7} }
#declare rsd = seed(1);
#local c = 0;
#while (c<1000)
#local p = RandOnSurface(Bent, rsd, 0.05);
cone{<0,0,0>,0.025,<0,0.1,0>,0
Point_At_Trans(Norm)
translate p
pigment{Red}
}
#local c = c + 1;
#end
Post a reply to this message
|
|
|
|
> brute force but should be a reasonable approximation if you
> are willing to wait a bit for all those missing rolls.
>
> Although I think you should also pick a uniform distribution
> of trace directions, otherwise you will have some unnecessary
> systematic error. But this can be fixed by
>
> http://mathworld.wolfram.com/SpherePointPicking.html
I didn't rotate 360 y and 180 relative as in polar notation,
which is what causes that common error pointed out on wolfram,
but by 360 on 3 fixed axes. The result should be uniform already?
I guess you could use Ingo's VRand_On_Sphere() from rand.inc
#local rdir = VRand_On_Sphere(rsd);
> Also, the bounding box should be extended by "threshold",
> else areas at the border only have 50% chance of hitting.
Oops, yep.
#local mn = min_extent(Obj)-thresh;
#local mx = max_extent(Obj)+thresh;
Post a reply to this message
|
|
|
|
> I have been playing with your macro and I have the following question, as
> I am at a loss about how to solve it myself (see the image in p.b.i.).
>
> I scaled here the cones to a flat shape. What I would like is to always
> have the eliptic bases oriented horizontally, whatever their location, not
> like in the image, where part of them are oriented vertically. How could
> that be achieved with your macro? I experimented a bit and read the docs,
> but I am at a loss.
Trace and the RandOnSurface macro only return a point and a normal.
You could ignore the vertical portion of the normal and force some
object to be horizontal in respect to the horizon.
Point_At_Trans(vnormalize(<Norm.x,0,Norm.z>))
but you would need to decide what to do if the normal is vertical
or it might error out.
However, I think what you intend is to follow the shape of the object?
A normal isn't enough to generate info about how the surface
shape slopes nearby to some random point. You could trace nearby
points and rotate based on that perhaps.
Post a reply to this message
|
|