POV-Ray : Newsgroups : povray.advanced-users : One works one doesn't? Server Time
29 Jul 2024 16:22:47 EDT (-0400)
  One works one doesn't? (Message 1 to 6 of 6)  
From: Dan Johnson
Subject: One works one doesn't?
Date: 16 Jun 2001 02:09:07
Message: <3B2C49EC.D29C629E@hotmail.com>
The bottom uncommented one works given good data, but won't given bad
data.  The top one tries to correct for user error, but instead
generates errors every time.  

/*#macro Quaternion(Angle,Vector)   // creates a normalized rotation
quaternion... angle in radians
        #if (vlength(Vector)=0) 
         #warning "0 vector not allowed\nUsing identity Quaternion" 
         <1,0,0,0>
        #else
         #local A = Angle/2;
         #local V = sin(A)*vnormalize(Vector);
         <cos(A),V.x,V.y,V.z>
        #end
#end*/
#macro Quaternion(Angle,Vector)   //Old version
        #if (vlength(Vector)=0) #warning "0 vector not allowed" #end
        #local A = Angle/2;
        #local V = sin(A)*vnormalize(Vector);
        <cos(A),V.x,V.y,V.z>
#end

-- 
Dan Johnson 

http://www.geocities.com/zapob


Post a reply to this message

From: Rune
Subject: Re: One works one doesn't?
Date: 16 Jun 2001 08:53:23
Message: <3b2b56c3@news.povray.org>
Where and how is the 4D vector returned by the macro used? Can you provide
an example? That might help people helping you (though I probably won't be
able to help you myself, as 4D vectors are not my area).

Rune
--
3D images and anims, include files, tutorials and more:
Rune's World:    http://rsj.mobilixnet.dk (updated May 10)
POV-Ray Users:   http://rsj.mobilixnet.dk/povrayusers/
POV-Ray Webring: http://webring.povray.co.uk


Post a reply to this message

From: Dan Johnson
Subject: Re: One works one doesn't?
Date: 16 Jun 2001 16:28:03
Message: <3B2D133B.2BDEA666@hotmail.com>
Rune wrote:
> 
> Where and how is the 4D vector returned by the macro used? Can you provide
> an example? That might help people helping you (though I probably won't be
> able to help you myself, as 4D vectors are not my area).
> 
> Rune
> --
> 3D images and anims, include files, tutorials and more:
> Rune's World:    http://rsj.mobilixnet.dk (updated May 10)
> POV-Ray Users:   http://rsj.mobilixnet.dk/povrayusers/
> POV-Ray Webring: http://webring.povray.co.uk

OK then here is all of my 4D vector functions.  Another one is
generating a bug that is even more frustrating.  

The H2T_sr function dies most of the time it is given a 180 degree
rotation such as.

box{<0,0,0>,<1,1,1> Q_matrix(H2T_sr(x,-x)) pigment{Red}}


On with the code

// Begin Code
/*#macro Quaternion(Angle,Vector)   // creates a normalized rotation
quaternion... angle in radians
        #if (vlength(Vector)=0) 
         #warning "0 vector not allowed\nUsing identity Quaternion" 
         <1,0,0,0>
        #else
         #local A = Angle/2;
         #local V = sin(A)*vnormalize(Vector);
         <cos(A),V.x,V.y,V.z>
        #end
#end*/
#macro Quaternion(Angle,Vector)   //Old version
        #if (vlength(Vector)=0) #warning "0 vector not allowed" #end
        #local A = Angle/2;
        #local V = sin(A)*vnormalize(Vector);
        <cos(A),V.x,V.y,V.z>
#end

#macro Q_conjugate(Q)         // the conjugate of a quaternion
        <Q.x,-Q.y,-Q.z,-Q.t>  // will rotate around the same axis in the
opposite direction
#end
#macro Q_axis (Quat) // returns normalized axis of Quaternion
        #local V = vnormalize (<Quat.y,Quat.z,Quat.t>);
        #if (vlength(V) = 0)
          #warning "Degenerate Axis"
        #end
        V
#end
#macro Q_angle(Quat) // returns angle in radians of Quaternion
        acos(Quat.x)
#end
#macro Q_multiply(P,Q)  // multiplies two quaternions
        #local P0 = P.x;
        #local Pv = <P.y,P.z,P.t>;
        #local Q0 = Q.x;
        #local Qv = <Q.y,Q.z,Q.t>;
        #local PQ0 = P0*Q0 - vdot(Pv,Qv);
        #local PQv = P0*Qv + Q0*Pv + vcross(Pv,Qv);
        <PQ0,PQv.x,PQv.y,PQv.z>
#end
#macro Q_matrix_array (Q)      // converts a quaternion into a matrix
        #local Q0 = Q.x;
        #local Q1 = Q.y;
        #local Q2 = Q.z;
        #local Q3 = Q.t;
        #local QT = 2*pow(Q0,2)-1;
        array[12]
        {QT+2*pow(Q1,2),2*(Q1*Q2+Q0*Q3),2*(Q1*Q3-Q0*Q2),
         2*(Q1*Q2-Q0*Q3),QT+2*pow(Q2,2),2*(Q2*Q3+Q0*Q1),
         2*(Q1*Q3+Q0*Q2),2*(Q2*Q3-Q0*Q1),QT+2*pow(Q3,2),
         0,0,0}
#end
#macro Rotate_displace (Q,V)  // rotate using Quaternion displace using
vector, returns matrix array
        #local Mat = Q_matrix_array (Q);
        #local Mat[9] = V.x;
        #local Mat[10] = V.y;
        #local Mat[11] = V.z;
        Mat
#end
#macro Matrix_2_matrix (M)  // Creates a translation matrix from matrix
array
       
matrix<M[0],M[1],M[2],M[3],M[4],M[5],M[6],M[7],M[8],M[9],M[10],M[11]>
#end
#macro Matrix_mult (M1,M2) // multiplys two matrices
        #local R1 = <M1[0],M1[1],M1[2],0>;  // matrix 1 rows
        #local R2 = <M1[3],M1[4],M1[5],0>;
        #local R3 = <M1[6],M1[7],M1[8],0>;
        #local R4 = <M1[9],M1[10],M1[11],0>;
        
        #local C1 = <M2[0],M2[3],M2[6],M2[9]>;  // matrix 2 columns
        #local C1 = <M2[1],M2[4],M2[7],M2[10]>;
        #local C1 = <M2[2],M2[5],M2[8],M2[11]>;
        
        #local M = array[12]                  // The calculations
        {vdot(R1,C1),vdot(R1,C2),vdot(R1,C3),
         vdot(R2,C1),vdot(R2,C2),vdot(R2,C3),
         vdot(R3,C1),vdot(R3,C2),vdot(R3,C3),
         vdot(R4,C1),vdot(R4,C2),vdot(R4,C3)}
         
         M
#end
        
#macro V_matrix (V,M)// V is a vector M is a 12 element array in the
same pattern as a matrix
        #local Vx = V.x*M[0] + V.y*M[3] + V.z*M[6] + M[9];
        #local Vy = V.x*M[1] + V.y*M[4] + V.z*M[7] + M[10];
        #local Vz = V.x*M[2] + V.y*M[5] + V.z*M[8] + M[11];
        <Vx,Vy,Vz>
#end
#macro VQ(V,Q)// applies a Quaternion oporator to a vector
        /*#local Qs = Q.x;                              // Last line
replaced this code wich misteriously does not work
        #local Qv = <Q.y,Q.z,Q.t>;
        (((2*Qs*Qs)-1)*v + 2*vdot(Qv,V)*Qv + 2*Qs*vcross(Qv,V))*/
        V_matrix (V,Q_matrix_array (Q))                 // less
efficient way.
#end

#macro Q_matrix (Q)      // converts a quaternion into a matrix
        #local Q0 = Q.x;
        #local Q1 = Q.y;
        #local Q2 = Q.z;
        #local Q3 = Q.t;
        #local QT = 2*pow(Q0,2)-1;
        matrix 
        <QT+2*pow(Q1,2),2*(Q1*Q2+Q0*Q3),2*(Q1*Q3-Q0*Q2),
         2*(Q1*Q2-Q0*Q3),QT+2*pow(Q2,2),2*(Q2*Q3+Q0*Q1),
         2*(Q1*Q3+Q0*Q2),2*(Q2*Q3-Q0*Q1),QT+2*pow(Q3,2),
         0,0,0>
#end
#macro Q_half_turn(V)   //180 degree rotation about vector
        #local V = vnormalize(V);
        <0,V.x,V.y,V.z>
#end

// Here to There simple rotation version
#macro H2T_sr (V1,V2) // rotates object pointing at V1 so that it points
at V2
        #if ((vlength(V1) = 0) | (vlength (V2) = 0) |
(Same_test(vnormalize(V1),vnormalize(V2))))
          #local Qout = <1,0,0,0>;       // if either input vector is
zero, or angle between them is zero
        #else                           // no rotation needed output
identity quaternion
          #if (vlength (vcross(V1,V2)) = 0)      // see if vectors point
in opposite directions
            #if (vlength(vcross(<1,1,1>,V1))!=0) // if V1 is not
parralel to <1,1,1>
              #local Qout = Q_half_turn(<1,1,1>-Proj(<1,1,1>,V1));// 
Proj(<1,1,1>,V1) is parralel to V1 (<1,1,1>-Proj(<1,1,1>,V1))
            #else                                                 // 
should be perpendicular
              #local Qout = Q_half_turn(<1,0,-1>);
            #end 
          #else
            #local Angle = acos(vdot(V1,V2)/(vlength(V1)*vlength(V2)));
            #local Axis  = vcross (V1,V2);
            #local Qout = Quaternion(Angle,Axis);
          #end
        #end
        Qout
#end
// Here to There general rotation version
#macro H2T_r(U1,U2,V1,V2)
        #local U = U2-U1;
        #local U = U-Proj(U,U1);
        #local V = V2-V1;
        #local V = V-Proj(V,V1);
        #local Q1 = H2T_sr (U1,V1);
        #local Vr = VQ(U,Q1);
        #if (vlength(vcross(Vr,V)) = 0)
         #if (vlength(vnormalize(Vr)-vnormalize(V))=0)
          #local Q2 = <1,0,0,0>;
         #else
          #local Q2 = Q_half_turn(V1);
         #end 
        #else
        #local Q2 = H2T_sr (Vr,V);
        #end
        Q_multiply(Q2,Q1)
#end
#macro R(Axis,Angle) // rotates around axis by angle... angle in radians
        Q_matrix (Quaternion(Angle,Axis))
#end
// End Code

-- 
Dan Johnson 

http://www.geocities.com/zapob


Post a reply to this message

From: Dan Johnson
Subject: Re: One works one doesn't?
Date: 19 Jun 2001 07:12:27
Message: <3B30858D.A277D60@hotmail.com>
Dan Johnson wrote:

Fixed all the other known bugs in my code this weekend.  I still don't
know why the first one of these doesn't work, and the second one does.  

<snip>
> /*#macro Quaternion(Angle,Vector)   // creates a normalized rotation
> quaternion... angle in radians
>         #if (vlength(Vector)=0)
>          #warning "0 vector not allowed\nUsing identity Quaternion"
>          <1,0,0,0>
>         #else
>          #local A = Angle/2;
>          #local V = sin(A)*vnormalize(Vector);
>          <cos(A),V.x,V.y,V.z>
>         #end
> #end*/
> #macro Quaternion(Angle,Vector)   //Old version
>         #if (vlength(Vector)=0) #warning "0 vector not allowed" #end
>         #local A = Angle/2;
>         #local V = sin(A)*vnormalize(Vector);
>         <cos(A),V.x,V.y,V.z>
> #end
<snip>

-- 
Dan Johnson 

http://www.geocities.com/zapob


Post a reply to this message

From: Tim Attwood
Subject: Re: One works one doesn't?
Date: 22 Jun 2001 06:01:46
Message: <3B331788.742FB8BE@worldnet.att.net>
Dan Johnson wrote:

> Fixed all the other known bugs in my code this weekend.  I still don't
> know why the first one of these doesn't work, and the second one does.
>
> <snip>
> > /*#macro Quaternion(Angle,Vector)   // creates a normalized rotation
> > quaternion... angle in radians
> >         #if (vlength(Vector)=0)
> >          #warning "0 vector not allowed\nUsing identity Quaternion"
> >          <1,0,0,0>
> >         #else
> >          #local A = Angle/2;
> >          #local V = sin(A)*vnormalize(Vector);
> >          <cos(A),V.x,V.y,V.z>
> >         #end
> > #end*/
> > #macro Quaternion(Angle,Vector)   //Old version
> >         #if (vlength(Vector)=0) #warning "0 vector not allowed" #end
> >         #local A = Angle/2;
> >         #local V = sin(A)*vnormalize(Vector);
> >         <cos(A),V.x,V.y,V.z>
> > #end
> <snip>

Ok, the problem is that macros aren't full subroutines like you might
expect. For example

#macro example(a)
  #if (a=0)
   <1,0,0,0>
  #else
   <0,0,0,0>
  #end
#end

Parses into this when the macro is evaluated...

  #if (a=0)
   <1,0,0,0>
  #else
   <0,0,0,0>
  #end

And at this level everything needs to be legal, it chokes.
The solution is to dump everything into #locals..

#macro Quaternion(Angle,Vector)   // creates a normalized rotation
 quaternion... angle in radians
         #if (vlength(Vector)=0)
          #warning "0 vector not allowed\nUsing identity Quaternion"
          #local A = 1;
          #local V = <0,0,0>;
         #else
          #local A = cos(Angle/2);
          #local V = sin(Angle/2)*vnormalize(Vector);
         #end
       <A,V.x,V.y,V.z>
#end

----- Tim Attwood -----


Post a reply to this message

From: Dan Johnson
Subject: Re: One works one doesn't?
Date: 24 Jun 2001 18:44:44
Message: <3B366DD0.2ADFF5AE@hotmail.com>
Tim Attwood wrote:

<snip>
> 
> Ok, the problem is that macros aren't full subroutines like you might
> expect. For example
> 
> #macro example(a)
>   #if (a=0)
>    <1,0,0,0>
>   #else
>    <0,0,0,0>
>   #end
> #end
> 
> Parses into this when the macro is evaluated...
> 
>   #if (a=0)
>    <1,0,0,0>
>   #else
>    <0,0,0,0>
>   #end
> 
> And at this level everything needs to be legal, it chokes.
> The solution is to dump everything into #locals..
> 
> #macro Quaternion(Angle,Vector)   // creates a normalized rotation
>  quaternion... angle in radians
>          #if (vlength(Vector)=0)
>           #warning "0 vector not allowed\nUsing identity Quaternion"
>           #local A = 1;
>           #local V = <0,0,0>;
>          #else
>           #local A = cos(Angle/2);
>           #local V = sin(Angle/2)*vnormalize(Vector);
>          #end
>        <A,V.x,V.y,V.z>
> #end
> 
> ----- Tim Attwood -----

Seems to work, haven't tested what happens when I use a zero vector.  
Thanks.  

-- 
Dan Johnson 

http://www.geocities.com/zapob


Post a reply to this message

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