Re: contour shading



On 07 Feb 2006 12:59:57 GMT, "jano trouba" <trouba_1@xxxxxxxxxx>
wrote:

So nobody in here to give me a hint ?

I would have thought this is a fairly common problem ....

I just implemented this idea I had regarding this. It's probably not
the best or quickest solution, but it appears to do what you want.

It operates on a pixel level, but you should be able to make it use
polygons for the contour levels.

Here are a couple of examples, showing the contour input and resulting
shading.

http://img302.imageshack.us/my.php?image=contour17al.png
http://img302.imageshack.us/my.php?image=contour23fy.png

http://img155.imageshack.us/my.php?image=contour30xj.png
http://img54.imageshack.us/my.php?image=contour49xl.png

The general algorithm is as follows:

1) Determine the level at the current pixel (c), and the level below
(c_l) and above (c_h).

2) Locate two distance measures to the level below, and the level
above. The two distance measures are the average distance (a_l & a_h
respectively) and the inverse of the average inverse distance (d_l &
d_h).

3) If both distances exist, compare d_l to d_h. If d_l is less than
d_h, compute
t = d_l / (2 * d_h)
Otherwise compute
t = d_h / (2 * d_l);

4) I wasn't sure how you wanted to handle the case where the distance
to the higher level doesn't exist (the current level is a plateau).
Currently, I compute
t = (d_l / a_l)^2;
if (t > 0.5) then t = 0.5;

5) If t < 0.5 perform the following
color = lerp(palette[c_l], palette[c], t + 0.5);
Else perform
color = lerp(palette[c], palette[c_h], t - 0.5);
where lerp() is linear interpolation.

The hard part is to compute the distances. The way I solved this was
to use a 2d pixel traversal algorithm which tested a "ray". For each
edge pixel, I ran a test for a ray starting at the current pixel,
heading towards the edge pixel.

If the ray hit a pixel with the desired level, it returned the pixels
position. If it hit a level different from the current level (c), it
would terminate, reporting no hit.

If the ray exited the image, it would report a hit only if I was
looking for the edge (which would be used for the totally white areas
in the above images).

If the test reported a hit, it would then compute the distance from
the hit point to the current pixel position. I would then do
dsum = dsum + dist;
disum = disum + 1 / dist;
n = n + 1;

When all rays has been cheked, if n is nonzero, it computes the
averages:
a = dsum / n;
d = 1 / (disum / n);

These values are then assigned to either a_l and d_l or a_h and d_h.

The images it produces is not perfect, but if you apply a gaussian
blur (radius 4-6 in the above images), it looks pretty good imho.

The traversal algorithm I used was based on "A Fast Voxel Traversal
Algorithm for Ray Tracing" by Amanatides & Woo
http://citeseer.ist.psu.edu/amanatides87fast.html

An obvious optimization is to not check against all edge pixels, but
only every k pixel, or similar.

If your contours are polygons, you should be able to simply use a
ray-polygon intersection test to determine the distance.

Hope it helps, if only by a bit :)

- Asbjørn
.



Relevant Pages

  • Dynamic Array
    ... a simple ray trace program. ... For each voxel of the object (i.e. ... that voxel for that pixel. ... with any pixels while some may interact with a few pixels. ...
    (comp.soft-sys.matlab)
  • Re: Measuring angles in an image.
    ... pixel hold discreet values that can in some way correspond to the ... distance from the camera. ... But if you have just some general photo, ... miles from me, and the sun is 93 million miles away from me. ...
    (sci.image.processing)
  • Re: color threshold
    ... I mean i arrange lind of window which take only colors which is inside in this window. ... Rest color pixel dont count in my program. ... The way I have tackled this in the past is to use the concept of colour distance. ... Use this binary mask and apply to your original image, you will find that the only pixels left are those which meet your colour range criteria. ...
    (comp.soft-sys.matlab)
  • Re: Implementing a simple raytracer (The camera)
    ... Actually its a ray caster since i really ... you'll have to specify a window in x-y plane ... will be assigned to corresponding pixel. ... If you are reading scene description, maybe corresponding file format ...
    (comp.graphics.rendering.raytracing)
  • Re: A One Pixel Long Line
    ... do a hit test on a pixel? ... The individual pixel I want to 'hit' is not part of a line, ... //namespace HitPixel ... //set EndCaps of both pens to ArrowAnchor ...
    (microsoft.public.dotnet.languages.csharp)