POV-Ray : Newsgroups : povray.advanced-users : Height-field (dis)orientation Server Time
28 Jul 2024 16:32:34 EDT (-0400)
  Height-field (dis)orientation (Message 1 to 3 of 3)  
From: David Wallace
Subject: Height-field (dis)orientation
Date: 21 Jul 2004 15:28:44
Message: <40fec3ec@news.povray.org>
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?


Post a reply to this message

From: Mike Williams
Subject: Re: Height-field (dis)orientation
Date: 21 Jul 2004 16:45:26
Message: <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


Post a reply to this message

From: David Wallace
Subject: Re: Height-field (dis)orientation
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.