| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556 |
- /*****************************************************************************
- * quatern.c
- *
- * This module implements Quaternion algebra julia fractals.
- *
- * This file was written by Pascal Massimino.
- * Revised and updated for POV-Ray 3.x by Tim Wegner
- *
- * from Persistence of Vision(tm) Ray Tracer
- * Copyright 1996,1999 Persistence of Vision Team
- *---------------------------------------------------------------------------
- * NOTICE: This source code file is provided so that users may experiment
- * with enhancements to POV-Ray and to port the software to platforms other
- * than those supported by the POV-Ray Team. There are strict rules under
- * which you are permitted to use this file. The rules are in the file
- * named POVLEGAL.DOC which should be distributed with this file.
- * If POVLEGAL.DOC is not available or for more info please contact the POV-Ray
- * Team Coordinator by email to team-coord@povray.org or visit us on the web at
- * http://www.povray.org. The latest version of POV-Ray may be found at this site.
- *
- * This program is based on the popular DKB raytracer version 2.12.
- * DKBTrace was originally written by David K. Buck.
- * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
- *
- *****************************************************************************/
- #include "frame.h"
- #include "povray.h"
- #include "vector.h"
- #include "povproto.h"
- #include "fractal.h"
- #include "quatern.h"
- #include "spheres.h"
- /*****************************************************************************
- * Local preprocessor defines
- ******************************************************************************/
- #ifndef Fractal_Tolerance
- #define Fractal_Tolerance 1e-8
- #endif
- #define Deriv_z2(n1,n2,n3,n4) \
- { \
- tmp = (n1)*x - (n2)*y - (n3)*z - (n4)*w; \
- (n2) = (n1)*y + x*(n2); \
- (n3) = (n1)*z + x*(n3); \
- (n4) = (n1)*w + x*(n4); \
- (n1) = tmp; \
- }
- #define Deriv_z3(n1,n2,n3,n4) \
- { \
- dtmp = 2.0*((n2)*y + (n3)*z + (n4)*w); \
- dtmp2 = 6.0*x*(n1) - dtmp; \
- (n1) = ( (n1)*x3 - x*dtmp )*3.0; \
- (n2) = (n2)*x4 + y*dtmp2; \
- (n3) = (n3)*x4 + z*dtmp2; \
- (n4) = (n4)*x4 + w*dtmp2; \
- }
- /*****************************************************************************
- * Local typedefs
- ******************************************************************************/
- /*****************************************************************************
- * Static functions
- ******************************************************************************/
- /*****************************************************************************
- * Local variables
- ******************************************************************************/
- /*****************************************************************************
- *
- * FUNCTION
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * Pascal Massimino
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * Dec 1994 : Creation.
- *
- ******************************************************************************/
- int Iteration_z3(VECTOR point, FRACTAL *Julia)
- {
- int i;
- DBL x, y, z, w;
- DBL d, x2, tmp;
- DBL Exit_Value;
- Sx[0] = x = point[X];
- Sy[0] = y = point[Y];
- Sz[0] = z = point[Z];
- Sw[0] = w = (Julia->SliceDist
- - Julia->Slice[X]*x
- - Julia->Slice[Y]*y
- - Julia->Slice[Z]*z)/Julia->Slice[T];
-
- Exit_Value = Julia->Exit_Value;
- for (i = 1; i <= Julia->n; ++i)
- {
- d = y * y + z * z + w * w;
- x2 = x * x;
- if ((d + x2) > Exit_Value)
- {
- return (FALSE);
- }
- tmp = 3.0 * x2 - d;
- Sx[i] = x = x * (x2 - 3.0 * d) + Julia->Julia_Parm[X];
- Sy[i] = y = y * tmp + Julia->Julia_Parm[Y];
- Sz[i] = z = z * tmp + Julia->Julia_Parm[Z];
- Sw[i] = w = w * tmp + Julia->Julia_Parm[T];
- }
- return (TRUE);
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * Pascal Massimino
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * Dec 1994 : Creation.
- *
- ******************************************************************************/
- int Iteration_Julia(VECTOR point, FRACTAL *Julia)
- {
- int i;
- DBL x, y, z, w;
- DBL d, x2;
- DBL Exit_Value;
- Sx[0] = x = point[X];
- Sy[0] = y = point[Y];
- Sz[0] = z = point[Z];
- Sw[0] = w = (Julia->SliceDist
- - Julia->Slice[X]*x
- - Julia->Slice[Y]*y
- - Julia->Slice[Z]*z)/Julia->Slice[T];
- Exit_Value = Julia->Exit_Value;
- for (i = 1; i <= Julia->n; ++i)
- {
- d = y * y + z * z + w * w;
- x2 = x * x;
- if ((d + x2) > Exit_Value)
- {
- return (FALSE);
- }
- x *= 2.0;
- Sy[i] = y = x * y + Julia->Julia_Parm[Y];
- Sz[i] = z = x * z + Julia->Julia_Parm[Z];
- Sw[i] = w = x * w + Julia->Julia_Parm[T];
- Sx[i] = x = x2 - d + Julia->Julia_Parm[X];;
- }
- return (TRUE);
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * Pascal Massimino
- *
- * DESCRIPTION
- *
- * D_Iteration puts in *Dist a lower bound for the distance from *point to the
- * set
- *
- * CHANGES
- *
- * Dec 1994 : Creation.
- *
- ******************************************************************************/
- /*----------- Distance estimator + iterations ------------*/
- int D_Iteration_z3(VECTOR point, FRACTAL *Julia, DBL *Dist)
- {
- int i, j;
- DBL Norm, d;
- DBL xx, yy, zz;
- DBL x, y, z, w;
- DBL tmp, x2;
- DBL Exit_Value;
- DBL Pow;
- x = Sx[0] = point[X];
- y = Sy[0] = point[Y];
- z = Sz[0] = point[Z];
- w = Sw[0] = (Julia->SliceDist
- - Julia->Slice[X]*x
- - Julia->Slice[Y]*y
- - Julia->Slice[Z]*z)/Julia->Slice[T];
- Exit_Value = Julia->Exit_Value;
- for (i = 1; i <= Julia->n; i++)
- {
- d = y * y + z * z + w * w;
- x2 = x * x;
- if ((Norm = d + x2) > Exit_Value)
- {
- /* Distance estimator */
- x = Sx[0];
- y = Sy[0];
- z = Sz[0];
- w = Sw[0];
- Pow = 1.0 / 3.0;
- for (j = 1; j < i; ++j)
- {
- xx = x * Sx[j] - y * Sy[j] - z * Sz[j] - w * Sw[j];
- yy = x * Sy[j] + y * Sx[j] - z * Sw[j] + w * Sz[j];
- zz = x * Sz[j] + y * Sw[j] + z * Sx[j] - w * Sy[j];
- w = x * Sw[j] - y * Sz[j] + z * Sy[j] + w * Sx[j];
- x = xx;
- y = yy;
- z = zz;
- Pow /= 3.0;
- }
- *Dist = Pow * sqrt(Norm / (x * x + y * y + z * z + w * w)) * log(Norm);
- return (FALSE);
- }
- tmp = 3.0 * x2 - d;
- Sx[i] = x = x * (x2 - 3.0 * d) + Julia->Julia_Parm[X];
- Sy[i] = y = y * tmp + Julia->Julia_Parm[Y];
- Sz[i] = z = z * tmp + Julia->Julia_Parm[Z];
- Sw[i] = w = w * tmp + Julia->Julia_Parm[T];
- }
- *Dist = Precision;
- return (TRUE);
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * Pascal Massimino
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * Dec 1994 : Creation.
- *
- ******************************************************************************/
- int D_Iteration_Julia(VECTOR point, FRACTAL *Julia, DBL *Dist)
- {
- int i, j;
- DBL Norm, d;
- DBL Exit_Value;
- DBL x, y, z, w;
- DBL xx, yy, zz, x2;
- DBL Pow;
- x = Sx[0] = point[X];
- y = Sy[0] = point[Y];
- z = Sz[0] = point[Z];
- w = Sw[0] = (Julia->SliceDist
- - Julia->Slice[X]*x
- - Julia->Slice[Y]*y
- - Julia->Slice[Z]*z)/Julia->Slice[T];
- Exit_Value = Julia->Exit_Value;
- for (i = 1; i <= Julia->n; i++)
- {
- d = y * y + z * z + w * w;
- x2 = x * x;
- if ((Norm = d + x2) > Exit_Value)
- {
- /* Distance estimator */
- x = Sx[0];
- y = Sy[0];
- z = Sz[0];
- w = Sw[0];
- Pow = 1.0 / 2.0;
- for (j = 1; j < i; ++j)
- {
- xx = x * Sx[j] - y * Sy[j] - z * Sz[j] - w * Sw[j];
- yy = x * Sy[j] + y * Sx[j] + w * Sz[j] - z * Sw[j];
- zz = x * Sz[j] + z * Sx[j] + y * Sw[j] - w * Sy[j];
- w = x * Sw[j] + w * Sx[j] + z * Sy[j] - y * Sz[j];
- x = xx;
- y = yy;
- z = zz;
- Pow /= 2.0;
- }
- *Dist = Pow * sqrt(Norm / (x * x + y * y + z * z + w * w)) * log(Norm);
- return (FALSE);
- }
- x *= 2.0;
- Sy[i] = y = x * y + Julia->Julia_Parm[Y];
- Sz[i] = z = x * z + Julia->Julia_Parm[Z];
- Sw[i] = w = x * w + Julia->Julia_Parm[T];
- Sx[i] = x = x2 - d + Julia->Julia_Parm[X];
- }
- *Dist = Precision;
- return (TRUE);
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * Pascal Massimino
- *
- * DESCRIPTION
- *
- * Provided the iterations sequence has been built, perform the computation of
- * the Normal
- *
- * CHANGES
- *
- * Dec 1994 : Creation.
- *
- ******************************************************************************/
- void Normal_Calc_z3(VECTOR Result, int N_Max, FRACTAL *fractal)
- {
- DBL
- n11 = 1.0, n12 = 0.0, n13 = 0.0, n14 = 0.0,
- n21 = 0.0, n22 = 1.0, n23 = 0.0, n24 = 0.0,
- n31 = 0.0, n32 = 0.0, n33 = 1.0, n34 = 0.0;
- DBL x, y, z, w;
- int i;
- DBL tmp, dtmp, dtmp2, x2, x3, x4;
- x = Sx[0];
- y = Sy[0];
- z = Sz[0];
- w = Sw[0];
- for (i = 1; i <= N_Max; i++)
- {
- tmp = y * y + z * z + w * w;
- x2 = x * x;
- x3 = x2 - tmp;
- x4 = 3.0 * x2 - tmp;
- Deriv_z3(n11, n12, n13, n14);
- Deriv_z3(n21, n22, n23, n24);
- Deriv_z3(n31, n32, n33, n34);
- x = Sx[i];
- y = Sy[i];
- z = Sz[i];
- w = Sw[i];
- }
- Result[X] = n11 * x + n12 * y + n13 * z + n14 * w;
- Result[Y] = n21 * x + n22 * y + n23 * z + n24 * w;
- Result[Z] = n31 * x + n32 * y + n33 * z + n34 * w;
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * Pascal Massimino
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * Dec 1994 : Creation.
- *
- ******************************************************************************/
- void Normal_Calc_Julia(VECTOR Result, int N_Max, FRACTAL *fractal)
- {
- DBL
- n11 = 1.0, n12 = 0.0, n13 = 0.0, n14 = 0.0,
- n21 = 0.0, n22 = 1.0, n23 = 0.0, n24 = 0.0,
- n31 = 0.0, n32 = 0.0, n33 = 1.0, n34 = 0.0;
- DBL tmp;
- DBL x, y, z, w;
- int i;
- x = Sx[0];
- y = Sy[0];
- z = Sz[0];
- w = Sw[0];
- for (i = 1; i <= N_Max; i++)
- {
- Deriv_z2(n11, n12, n13, n14);
- Deriv_z2(n21, n22, n23, n24);
- Deriv_z2(n31, n32, n33, n34);
- x = Sx[i];
- y = Sy[i];
- z = Sz[i];
- w = Sw[i];
- }
- Result[X] = n11 * x + n12 * y + n13 * z + n14 * w;
- Result[Y] = n21 * x + n22 * y + n23 * z + n24 * w;
- Result[Z] = n31 * x + n32 * y + n33 * z + n34 * w;
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * Pascal Massimino
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * Dec 1994 : Creation.
- *
- ******************************************************************************/
- int F_Bound_Julia(RAY *Ray, FRACTAL *Fractal, DBL *Depth_Min, DBL *Depth_Max)
- {
- return (Intersect_Sphere(Ray, Fractal->Center, Fractal->Radius_Squared, Depth_Min, Depth_Max));
- }
|