POV-Ray : Newsgroups : povray.programming : How normal vector computation works in Povray ? Server Time
22 Dec 2024 18:00:18 EST (-0500)
  How normal vector computation works in Povray ? (Message 1 to 6 of 6)  
From: Helix
Subject: How normal vector computation works in Povray ?
Date: 19 May 2004 12:30:01
Message: <web.40ab8a7947c00e213cca0c610@news.povray.org>
I have looked into Povray's code source, and especially torus.cpp. I have
understood the torus_inersection() function, but the torus_normal()
function is strange.

If I'm not right, in order to obtain the normal vector at a given point on a
surface, I have to get the partial derivative of the surface equation (the
gradient).

Vector N(df/dx, df/dy, df/dz)

So for the torus, I obtain:





In torus_normal() function, Povray doesn't proceed like this... I tried to
inject my normal formula, but it doesn't work.

So, why it doesn't work ? And how Povray proceed to compute normal vector ?

Thanks,


Post a reply to this message

From: ABX
Subject: Re: How normal vector computation works in Povray ?
Date: 19 May 2004 12:48:17
Message: <lm3na0d3pq9qosnnu33kkajodjr7d7eos7@4ax.com>
On Wed, 19 May 2004 12:25:44 EDT, "Helix" <nomail@nomail> wrote:
> So, why it doesn't work ? And how Povray proceed to compute normal vector ?

In short Normal in Point P on torus surface has direction of vector which ends
in point P and begins in nearest to P point on circle created by major rarius.
So all you need is to normalize this vector. HTH,

ABX


Post a reply to this message

From: Helix
Subject: Re: How normal vector computation works in Povray ?
Date: 19 May 2004 15:15:01
Message: <web.40abb16e57c01bb53cca0c610@news.povray.org>
ABX <abx### [at] abxartpl> wrote:

> In short Normal in Point P on torus surface has direction of vector which ends
> in point P and begins in nearest to P point on circle created by major rarius.
> So all you need is to normalize this vector.

Even if I normalize my N vector, it doesn't work. According to me, the
problem doesn't come from here.

Below, the source code of torus_normal():

/* SOURCE CODE BEGIN */

  /* Transform the point into the torus space. */
  MInvTransPoint(P, Inter->IPoint, Torus->Trans);

  /* Get normal from derivatives. */
  dist = sqrt(P[X] * P[X] + P[Z] * P[Z]);
  if (dist > EPSILON)
  {
    M[X] = Torus->R * P[X] / dist;
    M[Y] = 0.0;
    M[Z] = Torus->R * P[Z] / dist;
  }
  else
  {
    Make_Vector(M, 0.0, 0.0, 0.0);
  }
  VSub(N, P, M);

  /* Transform the normalt out of the torus space. */
  MTransNormal(Result, N, Torus->Trans);

  VNormalize(Result, Result);
/* SOURCE CODE END */


As you can see, the formula is totally different than mine.


Post a reply to this message

From: Mike Williams
Subject: Re: How normal vector computation works in Povray ?
Date: 19 May 2004 17:31:13
Message: <5bWy4LAOH9qAFwcL@econym.demon.co.uk>
Wasn't it Helix who wrote:
>ABX <abx### [at] abxartpl> wrote:
>
>> In short Normal in Point P on torus surface has direction of vector which ends
>> in point P and begins in nearest to P point on circle created by major rarius.
>> So all you need is to normalize this vector.
>
>Even if I normalize my N vector, it doesn't work. According to me, the
>problem doesn't come from here.
>
>Below, the source code of torus_normal():
>
>/* SOURCE CODE BEGIN */
>
>  /* Transform the point into the torus space. */
>  MInvTransPoint(P, Inter->IPoint, Torus->Trans);
>
>  /* Get normal from derivatives. */
>  dist = sqrt(P[X] * P[X] + P[Z] * P[Z]);
>  if (dist > EPSILON)
>  {
>    M[X] = Torus->R * P[X] / dist;
>    M[Y] = 0.0;
>    M[Z] = Torus->R * P[Z] / dist;
>  }
>  else
>  {
>    Make_Vector(M, 0.0, 0.0, 0.0);
>  }
>  VSub(N, P, M);
>
>  /* Transform the normalt out of the torus space. */
>  MTransNormal(Result, N, Torus->Trans);
>
>  VNormalize(Result, Result);
>/* SOURCE CODE END */
>
>
>As you can see, the formula is totally different than mine.

The method is different from yours, but there's often more than one way
of doing something. The method used here is exactly as described by ABX.
M is the nearest point on the circle, which is then vector-subtracted
from P and the result VNormalized.

Your method would work if you don't make any coding errors, but there's
more arithmetic involved so it wouldn't run as quickly. It's possible to
verify that your algorithm will give the same results by implementing it
in POV SDL, like this:


#version 3.5;
global_settings {assumed_gamma 1.0}
camera {location  <0,4,-10> look_at <0,0,0> angle 50}
background {rgb 1}
light_source {<-30, 100, -30> color rgb 1}
#include "strings.inc"

// Define the torus
#declare R=2;
#declare r=0.5;
#declare T=torus{R,r}
object {T pigment {rgb 1}}

// Find normal by asking POV to trace it
#declare N=<0,0,0>;
#declare P=trace(T,<3,0.4,-2>,-x,N);

// Draw the normal and debug it
cylinder {P,P+N,0.2 pigment {rgb x}}
#debug VStr(N)
#debug "\n"

// Find normal by the partial derivatives
#declare X=P.x;
#declare Y=P.y;
#declare Z=P.z;

#declare K = (X*X + Y*Y + Z*Z + R*R - r*r); 
#declare Nx= 4 * X * K - 8 * R*R * X;
#declare Ny= 4 * Y * K; 
#declare Nz= 4 * Z * K - 8 * R*R * Z;

#declare N = vnormalize(<Nx, Ny, Nz>);

// Draw thte normal and debug it
cylinder {P,P+N,0.2 pigment {rgb y}}
#debug VStr(N)
#debug "\n"


The N calculated by POV, using the method described by ABX is exactly
the same as that calculated by your partial derivatives.

-- 
Mike Williams
Gentleman of Leisure


Post a reply to this message

From: ABX
Subject: Re: How normal vector computation works in Povray ?
Date: 20 May 2004 05:33:53
Message: <cquoa0ljtpesg9jf75m6kokuv80t954n60@4ax.com>
On Wed, 19 May 2004 15:11:42 EDT, "Helix" <nomail@nomail> wrote:
> As you can see, the formula is totally different than mine.

Perhaps the problem is in other place ? For example are you moving
intersection point from scene space to torus space, and reverse this way
against calculated normal ?

ABX


Post a reply to this message

From: Slime
Subject: Re: How normal vector computation works in Povray ?
Date: 21 May 2004 05:50:03
Message: <40add0cb@news.povray.org>
>   dist = sqrt(P[X] * P[X] + P[Z] * P[Z]);
>   if (dist > EPSILON)
>   {
>     M[X] = Torus->R * P[X] / dist;
>     M[Y] = 0.0;
>     M[Z] = Torus->R * P[Z] / dist;
>   }
>   else
>   {
>     Make_Vector(M, 0.0, 0.0, 0.0);
>   }
>   VSub(N, P, M);

I love it when seemingly difficult things are done so simply like this.

 - Slime
 [ http://www.slimeland.com/ ]


Post a reply to this message

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