POV-Ray : Newsgroups : povray.newusers : TRACE returns a unit-length NORMAL vector Server Time
25 Nov 2024 13:41:56 EST (-0500)
  TRACE returns a unit-length NORMAL vector (Message 1 to 9 of 9)  
From: Kenneth
Subject: TRACE returns a unit-length NORMAL vector
Date: 3 Oct 2005 18:25:01
Message: <web.4341aa9daf8295c7b55189fe0@news.povray.org>
To those of you who are new to the TRACE operation, here's a tip that I had
to find out on my own, as I could not locate this particular info anywhere
in the POV manuals, nor on any of the support websites I've been to.

TRACE, which can be a three-OR-four component operation, will, if you ask it
to, return (give back) the NORMAL vector found at an intersection point.
That's very useful for ALIGNING attached objects to a main object or
heightfield. What's missing in the TRACE tutorials I've seen is the fact
that this NORMAL vector is always 1 POV unit in length.  Meaning, the
normal's <x,y,z> vector values, no matter what they are, always produce a
vector LENGTH of 1.  This was never very clear
to me, so I constructed  a small scene file to "prove" it to myself. (If
anyone can point me to a good explanation of this
in the POV docs, I would be very appreciative.)

Here's my simple (??) scene for creating a sphere, TRACED with (imaginary)
rays that
"orbit" the sphere. This scene graphically demonstrates how the <x,y,z>
components of the NORMAL vector go about creating a unit-length. (Actually,
the demo shows only the x and y components; I left the z direction out for
clarity. In this demo, the z-axis contributes nothing anyway.) The white
lines are the unit-length vector itself, the green
lines represent the x-axis component, and the red lines represent the y-axis
component.

In the following code,  I make use of "dot operators," such as BLAH.X  If
you're not familiar with this syntax, it just means that you can extract a
SINGLE value from a 3,4, or 5 component vector.  I.e., if BLAH = <3,27,19>,
then BLAH.X = 3.  Very simple.

BTW, I left the lights out of the code, so be sure to add in a few!



global_settings {
  assumed_gamma 1.8
}

#include "math.inc"
// ----------------------------------------

camera {
  perspective
  location  <3.5, 4, -200>
  look_at   <3.5, 4,  0>
  right     x*image_width/image_height
  angle 5
}


sky_sphere {
  pigment {
    gradient y
    color_map {
      [0.0 rgb <0.6,0.7,1.0>*.5]
      [0.05 rgb 0]

    }
  }
}


#declare test_sphere =
object{
        sphere{0,8
                texture{
                        pigment {color rgb <.6,.8,1>}
                        finish{
                                ambient .1
                                diffuse .5
                              }
                       }
              }
      }

object {test_sphere}

// ---------------------------

#declare norm = <0,0,0>; // just to initialize this (any arbitrary values
// will do, as it will be changed below.)

#declare theta_angle = 0; // as rotated about the z axis, in degrees.

#while (theta_angle <= 120)

// The following use trig functions inside "MATH.INC"...
// SIND and COSD use degrees instead of radians, which is
// easier to understand.
#declare x_component = cosd (theta_angle);
#declare y_component = sind (theta_angle);

#declare shoot_from_x = 100*x_component;
#declare shoot_from_y = 100*y_component;

#declare surface_point =
        trace( // a four-component operation here...
                test_sphere, // object to trace
                <shoot_from_x, shoot_from_y, 0>, // shoot-from point
                <-x_component, -y_component, 0>, // direction of trace ray
                norm // gives back the NORMAL vector found at that point
                );


#if(norm.x = 0 & norm.y = 0 & norm.z = 0)
// A safety measure, to determine IF a trace ray actually hits the sphere.
// Uses the Boolean "AND" symbol. When a ray misses the object, TRACE
// returns <0,0,0> for the NORM value. So if this is TRUE, do
// NOTHING. I.e., make NO objects.

#else

// LINE drawn from surface intersection point, the exact length
// of the normal, aligned along the composite normal vector...
object {
        cylinder{surface_point, surface_point + norm, .035
                pigment {color rgb 1} // WHITE
                finish{
                        ambient 1
                        diffuse 0
                      }
                }
       }


// LINE drawn from surface intersection point,  the exact length of
// the x-axis part of the normal, aligned along the x-axis.
// (The .00001 addition is just to keep any "degenerate cylinders"
// from being made, which produce an error message.)
object {
        cylinder{surface_point, surface_point + <norm.x + .00001, 0, 0> .03
                pigment {color rgb <.3,1,.3>} // GREEN
                finish{
                        ambient .7
                        diffuse 0
                      }
                }
       }


// LINE drawn from surface intersection point, the exact length of
// the y-axis part of the normal, aligned along the y-axis...
object {
        cylinder{surface_point, surface_point + <0, norm.y + .00001, 0> .03
                pigment {color rgb <1,.3,.3>} // RED
                finish{
                        ambient 1
                        diffuse 0
                      }
                }
        translate norm.x*x // to make each right triangle visually clearer
       }


#end  // of #IF block

#declare theta_angle = theta_angle + 9;
#end


Post a reply to this message

From: Skip Talbot
Subject: Re: TRACE returns a unit-length NORMAL vector
Date: 5 Oct 2005 01:24:28
Message: <4343638c$1@news.povray.org>
Kenneth, doesn't it seem logical, and wouldn't you assume that the 
vectore returned by trace would indeed be a unit length vector?  What 
else would it possibly be?  Although the docs don't specifically mention 
its one unit in length, the sample code demonstrates it quite well. 
Below is the code right out of the docs with a camera and light added. 
You can see that the sphere has a radius of 1, and that just by 
eyeballing it, you can confirm that the trace result is a unit vector by 
seeing that cylinder (the trace normal) appears equal in length to the 
sphere's radius:

#declare MySphere = sphere { <0, 0, 0>, 1 }
#declare Norm = <0, 0, 0>;
#declare Start = <1, 1, 1>;
#declare Inter=
   trace ( MySphere, Start, <0, 0, 0>-Start, Norm );
   object {
     MySphere
     texture {
       pigment { rgb 1}
     }
   }
   #if (vlength(Norm)!=0)
   cylinder {
     Inter, Inter+Norm, .1
     texture {
       pigment {color red 1}
     }
   }
  #end


// create a regular point light source
light_source {
   0*x                  // light's position (translated below)
   color rgb <1,1,1>    // light's color
   translate <-20, 40, -20>
}

// perspective (default) camera
camera {
   location  <3.0, 0.0, -3.0>
   look_at   <0.0, 0.0,  0.0>
   right     x*image_width/image_height
}


Post a reply to this message

From: Kenneth
Subject: Re: TRACE returns a unit-length NORMAL vector
Date: 5 Oct 2005 04:50:00
Message: <web.43439161d049092fd47c191c0@news.povray.org>
Skip Talbot <Ski### [at] aolcom> wrote:
> Kenneth, doesn't it seem logical, and wouldn't you assume that the
> vectore returned by trace would indeed be a unit length vector?  What
> else would it possibly be?  Although the docs don't specifically mention
> its one unit in length, the sample code demonstrates it quite well.

I do agree that the sample code you've included, from the POV docs, does
visually show that the vector is indeed 1 unit in length.  However... that
doesn't seem (to me anyway) to be the best way of imparting information,
especially to the beginner. (I.e., how many different places does one need
to
look in the docs to find an answer to a question?)  As to "what else could
it possibly be," that presupposes a knowledge of vector math that I didn't
have when starting out. It did take me quite a while to really understand
the concept of vectors in general (more specifically, what values POV
itself generates, in such operations as TRACE.) Since the three values
making up a typical vector can be anywhere from 0 to 1 (and of course
beyond), my own thinking was that there was no way  to know (without a fair
amount of experimentation and screwups) if trace was creating very SMALL
<x,y,z> values, very large ones, or in fact WHAT the values could be. (If
the values are all scaled equally, the vector DIRECTION remains the same.)
When writing code (especially as a beginner), there are far too many things
that can go wrong (erroneous thinking, bad concepts, typos) to have to
"guess" at POV's workings.  I can't say I assumed (or would assume even
now) that trace would automatically return values that would "create" a
unit length.  Perhaps the more mathematically-minded POV users would... but
how do beginners know that? (I've come to understand--guess?-- that trace
must include a vnormalize function within itself to do this.)

Not to say that those starting out in POV need to be completely spoon fed!
But, let's be honest, many of the tutorials and explanations in the POV
docs seem to assume a rather deep mathematical knowledge from the get-go.
(Perhaps an indication of its lineage?) No doubt, the many tutorial
websites devoted to "explaining" things in POV reflect this. Yes, yes, I
agree that POV intrinsically works WITH math...but it need not have such a
steep learning curve, IMO.

Note that I posted my own code (and discussion) in the New Users forum, in
order to try and make life a little easier for beginners. I did assume that
more advanced users would already know about all this.


Post a reply to this message

From: Skip Talbot
Subject: Re: TRACE returns a unit-length NORMAL vector
Date: 6 Oct 2005 12:21:26
Message: <43454f06$1@news.povray.org>
You are right.  Someone with limited knowledge of vectors is really 
going to struggle at first.  If someone has the time or inspiration 
perhaps they could write up a vector tutorial and it could be included 
in the docs.

Skip


Post a reply to this message

From: Warp
Subject: Re: TRACE returns a unit-length NORMAL vector
Date: 6 Oct 2005 14:53:53
Message: <434572c1@news.povray.org>
Skip Talbot <Ski### [at] aolcom> wrote:
> Kenneth, doesn't it seem logical, and wouldn't you assume that the 
> vectore returned by trace would indeed be a unit length vector?  What 
> else would it possibly be?

  Why is it so obvious that the normal vector returned by trace() is
normalized?
  Normal vectors are usually results of some calculation which often do
not by itself return a normalized vector. For example, if you calculate
the normal vector of a triangle using cross-product, the result will not
be normalized and you have to it separately.
  POV-Ray primitives probably return their normal vectors already
normalized for convenience, but it's not something obvious. They could
perfectly well return non-normalized normal vectors.

  (For those who don't know the term, normalizing means calculating a
vector with the same direction as the given vector but with length 1.)

-- 
                                                          - Warp


Post a reply to this message

From: Kenneth
Subject: Re: TRACE returns a unit-length NORMAL vector
Date: 6 Oct 2005 17:25:01
Message: <web.43459593d049092f9e16f59b0@news.povray.org>
Skip Talbot <Ski### [at] aolcom> wrote:
 If someone has the time or inspiration
> perhaps they could write up a vector tutorial and it could be included
> in the docs.
>
> Skip

I've been thinking of doing just that, myself (probably to post on my own
tutorial webpage...whenever I get around to setting one up!  : )  )
Vectors, in all their various POV forms,  are such an important part of POV
itself...and so MUCH can be done with them, with the right knowledge.


Post a reply to this message

From: Kenneth
Subject: Re: TRACE returns a unit-length NORMAL vector
Date: 6 Oct 2005 17:40:00
Message: <web.434598d1d049092f9e16f59b0@news.povray.org>
"Kenneth" <kdw### [at] earthlinknet> wrote:

>
> Here's my simple (??) scene for creating a sphere, TRACED with (imaginary)
> rays that
> "orbit" the sphere. This scene graphically demonstrates how the <x,y,z>
> components of the NORMAL vector go about creating a unit-length.

I have an embarassing admission to make: Upon thinking about my own code
more deeply, I see that it does NOT, in fact, "prove" that TRACE returns a
unit-length vector.  All it does is show that the many returned normal
vectors are all the SAME LENGTH. (Yes, by scaling my sphere down, you would
"see" that they are all one unit in length; but, alas, that's not quite the
"proof" I was looking for.) There is, generally speaking, a fundamental
difference between a VISUAL proof and a CONCEPTUAL one. So my own code is
really no different from POV's own example code (except to show the
individual directional components  making up the vector length.)  My
apologies for misleading anyone.

Time to do some more thinking!!!!


Post a reply to this message

From: Nicholas Shea
Subject: Re: TRACE returns a unit-length NORMAL vector
Date: 7 Oct 2005 04:50:00
Message: <web.43463674d049092fa48334a50@news.povray.org>
"Kenneth" <kdw### [at] earthlinknet> wrote:

> I have an embarassing admission to make: Upon thinking about my own code
> more deeply, I see that it does NOT, in fact, "prove" that TRACE returns a
> unit-length vector.  All it does is show that the many returned normal
> vectors are all the SAME LENGTH. (Yes, by scaling my sphere down, you would
> "see" that they are all one unit in length; but, alas, that's not quite the
> "proof" I was looking for.) There is, generally speaking, a fundamental
> difference between a VISUAL proof and a CONCEPTUAL one. So my own code is
> really no different from POV's own example code (except to show the
> individual directional components  making up the vector length.)  My
> apologies for misleading anyone.
>
> Time to do some more thinking!!!!

Hello Kenneth,

Making a mistake is surely allowed. In any forum, there will always be
others who are ready to correct you :)

Your post regarding the trace macro gave me an idea: to re-write the
TS_Macros to use custom envelopes.

IE:

// ******************************************************************
// macro TS_Intersect
// ------------------------------------------------------------------
// Shoots ray from origin to vector _v and calculates intersection
// point with _ts_envelope.
#macro TS_Intersect( _v )
    trace( _usr_Envelope, <0, 0, 0>, _v, _ts_Normal );
#end
// ******************************************************************

This means geodesic grid data can now be projected onto any POV object.
So, you see, whatever you do - even in error - the butterfly effect is
always there.

Regards,

N.Shea


Post a reply to this message

From: Kenneth
Subject: Re: TRACE returns a unit-length NORMAL vector
Date: 7 Oct 2005 16:05:01
Message: <web.4346d4b1d049092fa0ad5af90@news.povray.org>
"Nicholas Shea" <nic### [at] tiscalicouk> wrote:
***************************************************************
>
> This means geodesic grid data can now be projected onto any POV object.
> So, you see, whatever you do - even in error - the butterfly effect is
> always there.
>
> Regards,
>
> N.Shea

Cool!  I'll have to try this out.

Ken


Post a reply to this message

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