POV-Ray : Newsgroups : povray.programming : How normal vector computation works in Povray ? : Re: How normal vector computation works in Povray ? Server Time
1 Jul 2024 06:31:22 EDT (-0400)
  Re: How normal vector computation works in Povray ?  
From: Mike Williams
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

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