POV-Ray : Newsgroups : povray.advanced-users : Height-field (dis)orientation : Re: Height-field (dis)orientation Server Time
28 Jul 2024 18:27:10 EDT (-0400)
  Re: Height-field (dis)orientation  
From: David Wallace
Date: 24 Jul 2004 23:13:16
Message: <4103254c@news.povray.org>
"Mike Williams" <nos### [at] econymdemoncouk> wrote in message
news:XKHGtAAeWt$AFwQx@econym.demon.co.uk...
> Wasn't it David Wallace who wrote:
> >I am trying to place a relatively flat object on a heightfield using the
> >following macros:
> >
> >#declare Ground = height_field {
> > png "lakeb.png"
> > smooth
> > translate <-.5,-.5,-.5>
> > texture { texGnd }
> > scale <1e4, 160, 1e4>
> >}
> >
> >#macro trnGnd( ob, ang, px, py, alt)
> > rotate y*ang
> > #local nrm = <0,0,0>;
> > #local ps = trace( ob, <px, 1e5, py>, -y, nrm);
> > #if (vlength(nrm)>.1)
> >  Reorient(y,nrm)
> > #end
> > translate ps+nrm*alt
> >#end
> >
> >// Coral is a parametric snake surface
> >object { Coral scale 1.0 trnGnd(Ground, -96, 216, -910, 0.45) }
> >
> >The snake is rather long but lies relatively flat on a plane.  When I try
to
> >orient the snake so that is is level to the local surface, it fails
> >miserably.  Some of it is above the surface and some is below.  What am I
> >doing wrong?
>
>
> There are several things that you could be doing wrong, but my guess is
> that your height_field has roughness on a scale that smooth isn't
> ironing out.
>
> If you have a small image as your height_field, then smooth will
> generally tend to iron out single-pixel bumps, but if you're using a
> large image such bumps can seriously perturb the normals.
>
> When you use trace() to get the normal, it might hit a point that's on
> the side of a tiny bump and the normal you get shows the shape of the
> bump at that exact point, rather than the overall shape of the surface.
> Another trace() performed nearby might just miss the bump and return a
> normal that points in a completely different direction.
>
> I'd suggest that you try planting cylinders to show you the normals,
> like
>
> #macro NormTest(ob,X,Z)
>  #local nrm = <0,0,0>;
>  #local ps = trace( ob, <X, 1e5, Z>, -y, nrm);
>  cylinder {ps, ps+nrm*1000, 50 pigment {rgb x}}
> #end
>
> NormTest(Ground,-96,216)
>
> And then try calculating an "average" normal by using four nearby
> points, like
>
> #macro NormTest2(ob,X,Z,delta)
>  #local A = trace( ob, <X + delta , 1e5, Z>, -y);
>  #local B = trace( ob, <X - delta , 1e5, Z>, -y);
>  #local C = trace( ob, <X , 1e5, Z + delta>, -y);
>  #local D = trace( ob, <X , 1e5, Z - delta>, -y);
>  #local nrm = vnormalize(vcross(A-B,D-C));
>  #local ps = trace( ob, <X, 1e5, Z>, -y);
>  cylinder {ps, ps+nrm*1000, 50 pigment {rgb y}}
> #end
>
> NormTest2(Ground,-96,216,100)
>
> where "delta" is chosen to be large enough to smooth out the roughness
> of the surface, but not so large that it ignores the actual features of
> the landscape that you're trying to follow. (The length of your "Coral"
> object might be a suitable value to try.)
>
>
> -- 
> Mike Williams
> Gentleman of Leisure

The trnGround macro that I use on objects has a counterpart for indivdual
points called pAlt.  Applying this macro to the points on the parametric
surface effectively pins the object to the surface.  The surface is not all
that rough (4096x4096, or 2.44 units per pixel given its size).  I am now
working on a more complicated object (a mouse) using a similar principle.


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.