POV-Ray : Newsgroups : povray.binaries.scene-files : quaternions.inc : Re: QSample1.pov - Basic sample for using quaternions.inc for rotation Server Time
26 Apr 2024 19:05:07 EDT (-0400)
  Re: QSample1.pov - Basic sample for using quaternions.inc for rotation  
From: Tor Olav Kristensen
Date: 7 Oct 2003 16:07:46
Message: <Xns940DE0E98C34torolavkhotmailcom@204.213.191.226>
None <Non### [at] onca> wrote in news:Xns### [at] 204213191226:

> Tor Olav Kristensen <tor_olav_kCURLYAhotmail.com> wrote in
> news:Xns### [at] 204213191226: 
> 
>> Alain, your quaternions.inc file has some problems: Just look at all
>> the "Divide by zero" warnings generated when parsing your sample
>> file. 
>> 
>> I can help you with some of them if you are intereseted.
>> 
>> 
>> Tor Olav
> 
> Yes, the divide by zero messages are coming from the Qln() & QExp()
> macros where I have attempted to trap them with a conditional, but
> they still occur, it's strange.  But I think the end result is the
> same. 
> 
> If you are interested in helping it would be greatly appreciated.
> 

Note that in this expression:

(C ? A : B)

- both A and B are evaluated.

(I find this odd. IIRC this has been discussed somewhere in
these groups before. But I cannot remember if any good reasons
for this behaviour have been given.)

So your attempt to trap any division by zero errors by using
this conditional expression does not work smoothly.

It is my opinion that section '6.1.3.3 Float Operators' in the
manual should mention this behaviour.

My suggestion is to use #if #then and #else instead in such
cases.

But even if you do this in your Qln() and QExp() macros, there
is still one divide by zero warning left. It is triggered by
the QAxAn() macro. The 4th component (t) of a quaternion passed
to the macro is set to 1. - And this causes this expression to
be evaulated to zero: sqrt(1-Q.t*Q.t)

(It seems to me that it is the QBezier() macro that sets this
4th component to 1.)


Note that it is not advisable for users to use variable names
that are all lovercase letters (especially not for single
letter names).

(This is because these may be used for reserved keywords in
later versions of POV-Ray.)

See code below for my suggestions. 


P.S.: POV-Ray has an epsilon constant (= 1.0E-10) that it uses
in float comparisons. So it might not be necessary to use one
yourself, like you do when checking if the R variable is close
to zero.

Btw.: Are you sure that log() and not ln() should be used in
the QExp() macro ?


Tor Olav



#include "functions.inc" // For f_r()


#macro Qln(Q)

  #local R = f_r(Q.x, Q.y, Q.z);
  #if (R > 0)
    #local At = atan2(R, Q.t)/R;
  #else
    #local At = 0;
  #end // if

  <At*Q.x, At*Q.y, At*Q.z, 0.5*log(Qsc(Q))>

#end // macro Qln


#macro QExp(Q)

  #local R = f_r(Q.x, Q.y, Q.z);
  #local Et = exp(Q.t);
  #if (R > 0)
    #local S = sin(R)/R;
  #else
    #local S = 0;
  #end // if

  (Et*<S*Q.x, S*Q.y, S*Q.z, cos(R)>)

#end // macro QExp


#macro QAxAn(Q, An)

  #declare An = acos(Q.t)*2; 

  (<Q.x, Q.y, Q.z>/sqrt(1-Q.t*Q.t))

#end // macro QAxAn


Post a reply to this message

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