POV-Ray : Newsgroups : povray.binaries.images : Problem: Finding the elevation range of an isosurface relief Server Time
2 Aug 2024 08:17:00 EDT (-0400)
  Problem: Finding the elevation range of an isosurface relief (Message 1 to 6 of 6)  
From: Jörg 'Yadgar' Bleimann
Subject: Problem: Finding the elevation range of an isosurface relief
Date: 6 Aug 2007 17:43:32
Message: <46b79604@news.povray.org>
High!

During the last months, I experimented with various isosurface (and 
pattern) functions to generate realistic-looking landscapes. To 
"navigate" around these landscapes (e. g. for placing cameras or, in the 
future, trees or buildings) I found it necessary to have an orthographic 
map view of the terrain at different scales.

But at very large scales such as 1 by 1 kilometres (whis equals to 1 
metre/pixel at my favourite rendering resolution - see last attachment) 
a problem occurs: as the human eye's ability to discern hues is limited, 
I have to adapt the color_map for the original 200 by 200 kilometres 
physical map to the height range of the respective large-scale section. 
To do this, I would have to know the highest and lowest point of the relief.

How could this be achieved? The highest point could be tested for by 
shooting a series of parallel horizontal trace() rays from one edge of 
the map section, starting at a height well above the highest mountains 
in the whole isosurface (for example 15 kilometres), going lower each 
iteration until the first mountain peak is hit. But how to this for the 
lowest point?

And, after all, I'm sure that this method would be outstandingly 
time-consuming - is there any way to do it faster?

See you in Khyberspace!


Post a reply to this message


Attachments:
Download 'ghurghusht_flat_0103b_wrinkles_oblique_view.jpg' (126 KB) Download 'ghurghusht_flat_0103c_wrinkles_physical_map.jpg' (259 KB) Download 'ghurghusht_flat_0105a_wrinkles_regional_map.jpg' (93 KB) Download 'ghurghusht_flat_0105b_wrinkles_local_map.jpg' (33 KB) Download 'ghurghusht_flat_0105c_wrinkles_microlocal_map.jpg' (12 KB)

Preview of image 'ghurghusht_flat_0103b_wrinkles_oblique_view.jpg'
ghurghusht_flat_0103b_wrinkles_oblique_view.jpg

Preview of image 'ghurghusht_flat_0103c_wrinkles_physical_map.jpg'
ghurghusht_flat_0103c_wrinkles_physical_map.jpg

Preview of image 'ghurghusht_flat_0105a_wrinkles_regional_map.jpg'
ghurghusht_flat_0105a_wrinkles_regional_map.jpg

Preview of image 'ghurghusht_flat_0105b_wrinkles_local_map.jpg'
ghurghusht_flat_0105b_wrinkles_local_map.jpg

Preview of image 'ghurghusht_flat_0105c_wrinkles_microlocal_map.jpg'
ghurghusht_flat_0105c_wrinkles_microlocal_map.jpg


 

From: Mark Birch
Subject: Re: Problem: Finding the elevation range of an isosurface relief
Date: 6 Aug 2007 20:25:00
Message: <web.46b7baac9d2cb7274daddc090@news.povray.org>
A faster(?) trace option could be to shoot vertical rays in a grid pattern
over the entire landscape, keeping track of only the current highest &
lowest points.

This wouldn't find the *exact* highest point, but unless there are some very
sharp gradient changes it would be close enough.

Alternatively you could add a second layer to your colour map, say with some
narrow black lines like isobars on a weather map.


Post a reply to this message

From: Tim Attwood
Subject: Re: Problem: Finding the elevation range of an isosurface relief
Date: 8 Aug 2007 03:11:14
Message: <46b96c92$1@news.povray.org>
You could give it a b/w gradient pigment (ambient 1)
with a scale range that is sure to fit, then render an
overhead view without lights, load the image in an
editor and check what the brightest pixel is, and
then use that and the range to figure the ballpark
height.

Or you could use this collision macro with a
box overhead and lower it until the box hits.

// check if object A collides with object B
// Example: #local isHit = collision(A, B, 1000);
#macro collision(A B rez)
   #local result = false;
   #if (((min_extent(A).x > max_extent(B).x ) |
         (min_extent(B).x > max_extent(A).x ) |
         (min_extent(A).y > max_extent(B).y ) |
         (min_extent(B).y > max_extent(A).y ) |
         (min_extent(A).z > max_extent(B).z ) |
         (min_extent(B).z > max_extent(A).z ))=false)
      #local AB = intersection{object{A} object{B}};
      #local Mn = min_extent(AB);
      #local Mx = max_extent(AB);
      #local S1 = seed(1);
      #local Pt = VRand_In_Box(Mn, Mx, S1);
      #local cnt = 0;
      #while ((result = false) & (cnt < rez))
         #local Pt = VRand_In_Box(Mn, Mx, S1);
         #if (inside(AB, Pt))
            #local result = true;
         #end
         #local cnt = cnt + 1;
      #end
   #end
   result
#end


Post a reply to this message

From: Ray Bellis
Subject: Re: Problem: Finding the elevation range of an isosurface relief
Date: 8 Aug 2007 03:52:16
Message: <46b97630$1@news.povray.org>


> How could this be achieved? The highest point could be
> tested for by shooting a series of parallel horizontal
> trace() rays from one edge of the map section, starting
> at a height well above the highest mountains in the whole
> isosurface (for example 15 kilometres), going lower each
> iteration until the first mountain peak is hit. But how
> to this for the lowest point?
>
> And, after all, I'm sure that this method would be
> outstandingly time-consuming - is there any way to do it faster?

It needn't be particular slow at all - you can use an O(LogN) binary 
sub-division algorithm:

In pseudo code:

int height = 16384;
int step = height / 2;
while (step >= 0) {
  if (hit_object_at_height(height)) {
    height += step;
  } else {
    height -= step;
  }
  step /= 2;
}

With just 15 trace calls you'd have the maximum height between 0 and 65535m 
to 1m resolution.

Ray


Post a reply to this message

From: Ray Bellis
Subject: Re: Problem: Finding the elevation range of an isosurface relief
Date: 8 Aug 2007 03:54:31
Message: <46b976b7@news.povray.org>
Ray Bellis wrote:
>
> int height = 16384;
> int step = height / 2;
> while (step >= 0) {
>  if (hit_object_at_height(height)) {
>    height += step;
>  } else {
>    height -= step;
>  }
>  step /= 2;
> }

Oops - small bug - that (step >= 0) check should be (step > 0)

Ray


Post a reply to this message

From: Mike Williams
Subject: Re: Problem: Finding the elevation range of an isosurface relief
Date: 8 Aug 2007 04:24:15
Message: <xwlvDAASwXuGFwmC@econym.demon.co.uk>
Wasn't it Tim Attwood who wrote:
>You could give it a b/w gradient pigment (ambient 1)
>with a scale range that is sure to fit, then render an
>overhead view without lights, load the image in an
>editor and check what the brightest pixel is, and
>then use that and the range to figure the ballpark
>height.

If your isosurface is independent of z (which is probably a good idea
for landscapes, since you don't want to risk disconnected fragments
floating above the main surface) then you could do the equivalent inside
POV-Ray.

Use the function that generates the isosurface as a pigment function,
apply it to a plane, then use eval_pigment on each resulting "pixel" to
obtain the brightness of the pigment. It should run a lot faster than
using trace on the isosurface. You can use eval_pigment to sample at
different separations, you're not limited by the pixel size of the
render.

Or, equivalently, use the function that generates the isosurface as a
heightfield function and use max_extents and min_extents of that
heightfield. See http://www.econym.demon.co.uk/isotut/patterns.htm#hf
You have to switch the y and -z axes and translate by <-0.5,0,-0.5> to
get the heightfield to match the isosurface. The accuracy and speed of
this method depends on the size of the heightfield grid.

In both those cases, you can gain a little bit of extra time by not
actually rendering the plane or heightfield. Just #declare them and
perform the eval_pigment or max_extents on the undisplayed object.

-- 
Mike Williams
Gentleman of Leisure


Post a reply to this message

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