UV Mapping for Torus Object


Why it is introduced

   Reading sources of POV-Ray 3.5a I found that torus object has defined method for UV Mapping. But it was not mentioned in documentation so I checked how it worked. Wrong! I have investigated sources and found that there are two bugs. First: UV mapping is calculated for coordinates in scene space instead of object space. Second: author assumed that torus is located on x-y plane while it is located on x-z plane. Therefore I made necessary changes.

mapping comparision for torus object
No UV Mapping 3.5a Torus UV Mapping Correct Torus UV Mapping
no uv_mapping default uv_mapping patched uv_mapping
 
#version 3.5;

#declare minor=1/3;
#declare major=minor*3;

torus{
  major minor
  uv_mapping
  pigment{checker rgb 0 rgb 1 scale .1}
  rotate x*90
  rotate y*45
  translate 3*z*major
}

light_source{-9-9*z 1}
background{1}
camera{up y right x}

How it is implemented

   Implementation was pretty easy. All I need was open file torus.cpp and find definition of CalcUV and replace content of it with:

/*****************************************************************************
*
* FUNCTION
*
*   CalcUV
*
* INPUT
*   
* OUTPUT
*   
* RETURNS
*   
* AUTHOR
*
*   Alexander Enzmann
*   
* DESCRIPTION
*
*   - Calculate the u/v coordinate of a point on a torus
*
* CHANGES
*
*   - 2002.08.08 by ABX (abx@abx.art.pl)
*
*     Fix with correct placing for intersection point. It have to be
*     untransformed before further calculations.
*     Fix with correct space torus space. Change meaning of y and z.
*
******************************************************************************/
static void
CalcUV(TORUS *Torus, VECTOR IPoint, UV_VECT Result)
{
	DBL len, v, u, x, y, z;
	VECTOR P;
	
        // Transform the ray into the torus space.
        MInvTransPoint(P, IPoint, Torus->Trans);
	x = P[X];
	y = P[Y];
	z = P[Z];

	// Determine its angle from the y-axis.
	u = (1.0 - (atan2(z, x) + M_PI) / TWO_M_PI);

	len = sqrt(x * x + z * z);

	// Now rotate about the y-axis to get the point P into the x-z plane.
	x = len - Torus->R;
	v = (atan2(y, x) + M_PI) / TWO_M_PI;
        

	Result[U] = u;
	Result[V] = v;
}

Notes

   I noticed that UV coordinates are stored on intersection stack while the same method was removed from parametric object (see my notes in UV Mapping for Parametric Object). Additionally I'm not sure it is necessary to store UV coordinates anywhere. I think method CalcUV should be called directly from Torus_UVCoord method becouse it is necessary to have it there. Of course the same can be also achived with toroidal mapping for texture but I suppose method with UV coords is a little bit faster and use less memory.


Contact

This is an unofficial addition to POV-Ray. Do not ask the POV-Team for help with this. Feel free to send all opinions, suggestions, corrections and thanks :-) connected with this site to me
Copyright 2002 by Wlodzimierz ABX Skiba

Valid HTML 4.01!   Valid CSS!   Bobby WorldWide Approved AAA
If a thing is worth doing, it is worth doing well.