POV-Ray : Newsgroups : povray.general : Help creating a sgn() function : Re: Help creating a sgn() function Server Time
2 Aug 2024 00:16:11 EDT (-0400)
  Re: Help creating a sgn() function  
From: Jo Jaquinta
Date: 4 Mar 2005 10:05:33
Message: <4228793d$1@news.povray.org>
Many thanks to everyone for their answers. I didn't know about the 
select() function, that POVRay supported the ? operator, or the math.inc 
function. I've been using POVRay for 10+ years and have a bit of a blind 
spot for new features sometimes. :-)

For the curious, I needed it for a function that creates a bounding box 
for a curved room. I'm tracing the deck plan of the classic Trek 
Enterprise and the rooms are all curved rectangles. I was down to 7 pps 
for one render. I decided that a bounded_by would help. Then the head 
scratching started over the function to create the bounding box!
The function below seems to work. The renders don't seem clipped (see 
"Deck 7" in p.b.i) and the rate has gone up to 135 pps.

Critiques welcome.

Cheers,

Jo


// left & right from POV of center of circle standing on the y+ axis
// leftAngle      : left/anticockwise side
// rightAngle     : right/clockwise side
// insideRadius   : inner wall
// outsideRadius  : outer wall

#macro deck_room_bounds(leftAngle, rightAngle, insideRadius, outsideRadius)
   #local sinLeft = -sin(radians(leftAngle));
   #local cosLeft = cos(radians(leftAngle));
   #local sinRight = -sin(radians(rightAngle));
   #local cosRight = cos(radians(rightAngle));
   #local sgnSinLeft = sgn(sinLeft);
   #local sgnSinRight = sgn(sinRight);
   #local sgnCosLeft = sgn(cosLeft);
   #local sgnCosRight = sgn(cosRight);

   #local 
lowBound=<min(cosLeft*outsideRadius,cosLeft*insideRadius,cosRight*outsideRadius,cosRight*insideRadius)-DECK_WALL_THICK,-e,min(sinLeft*outsideRadius,sinLeft*insideRadius,sinRight*outsideRadius,sinRight*insideRadius)-DECK_WALL_THICK>;
   #local 
highBound=<max(cosLeft*outsideRadius,cosLeft*insideRadius,cosRight*outsideRadius,cosRight*insideRadius)+DECK_WALL_THICK,DECK_HEIGHT+e,max(sinLeft*outsideRadius,sinLeft*insideRadius,sinRight*outsideRadius,sinRight*insideRadius)+DECK_WALL_THICK>;
   #if (sgnSinLeft != sgnSinRight)
     #if (sgnCosLeft < 0) // clip left (-x)
       #local lowBound = 
<-outsideRadius-DECK_WALL_THICK,lowBound.y,lowBound.z>;
     #else // clip right (+x)
       #local highBound = 
<outsideRadius+DECK_WALL_THICK,highBound.y,highBound.z>;
     #end
   #else
     #if (sgnCosLeft != sgnCosRight)
       #if (sgnSinLeft > 0) // clip top (+z)
         #local highBound = 
<highBound.x,highBound.y,outsideRadius+DECK_WALL_THICK>;
       #else // clip bottom (-z)
         #local lowBound = 
<lowBound.x,lowBound.y,-outsideRadius-DECK_WALL_THICK>;
       #end
     #end
   #end
   box { lowBound, highBound }
#end


Post a reply to this message

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