1 | /*
|
---|
2 | -----------------------------------------------------------------------------
|
---|
3 | This source file is part of OGRE
|
---|
4 | (Object-oriented Graphics Rendering Engine)
|
---|
5 | For the latest info, see http://www.ogre3d.org/
|
---|
6 |
|
---|
7 | Copyright (c) 2000-2005 The OGRE Team
|
---|
8 | Also see acknowledgements in Readme.html
|
---|
9 |
|
---|
10 | You may use this sample code for anything you like, it is not covered by the
|
---|
11 | LGPL like the rest of the engine.
|
---|
12 | -----------------------------------------------------------------------------
|
---|
13 | */
|
---|
14 | /* Original author: John C. Hare
|
---|
15 | * Date: June 26, 1996 (although I've had these around for at least 6 years)
|
---|
16 | * Adapted to C++ by W.J. van der Laan 2004
|
---|
17 | */
|
---|
18 | #ifndef H_Q_Julia
|
---|
19 | #define H_Q_Julia
|
---|
20 | #include <cmath>
|
---|
21 |
|
---|
22 | /**
|
---|
23 | * Simple, fast, inline quaternion math functions
|
---|
24 | */
|
---|
25 | struct Quat {
|
---|
26 | float r,i,j,k;
|
---|
27 | };
|
---|
28 |
|
---|
29 | inline void qadd(Quat &a, const Quat &b)
|
---|
30 | {
|
---|
31 | a.r += b.r;
|
---|
32 | a.i += b.i;
|
---|
33 | a.j += b.j;
|
---|
34 | a.k += b.k;
|
---|
35 | }
|
---|
36 |
|
---|
37 | inline void qmult(Quat &c, const Quat &a, const Quat &b)
|
---|
38 | {
|
---|
39 | c.r = a.r*b.r - a.i*b.i - a.j*b.j - a.k*b.k;
|
---|
40 | c.i = a.r*b.i + a.i*b.r + a.j*b.k - a.k*b.j;
|
---|
41 | c.j = a.r*b.j + a.j*b.r + a.k*b.i - a.i*b.k;
|
---|
42 | c.k = a.r*b.k + a.k*b.r + a.i*b.j - a.j*b.i;
|
---|
43 | }
|
---|
44 |
|
---|
45 | inline void qsqr(Quat &b, const Quat &a)
|
---|
46 | {
|
---|
47 | b.r = a.r*a.r - a.i*a.i - a.j*a.j - a.k*a.k;
|
---|
48 | b.i = 2.0f*a.r*a.i;
|
---|
49 | b.j = 2.0f*a.r*a.j;
|
---|
50 | b.k = 2.0f*a.r*a.k;
|
---|
51 | }
|
---|
52 |
|
---|
53 | /**
|
---|
54 | * Implicit function that evaluates the Julia set.
|
---|
55 | */
|
---|
56 | class Julia {
|
---|
57 | private:
|
---|
58 | float global_real, global_imag, global_theta;
|
---|
59 | Quat oc,c,eio,emio;
|
---|
60 | public:
|
---|
61 | Julia(float global_real, float global_imag, float global_theta);
|
---|
62 | inline float eval(float x, float y, float z) {
|
---|
63 | Quat q, temp;
|
---|
64 | int i;
|
---|
65 |
|
---|
66 | q.r = x;
|
---|
67 | q.i = y;
|
---|
68 | q.j = z;
|
---|
69 | q.k = 0.0;
|
---|
70 |
|
---|
71 | for (i = 30; i > 0; i--) {
|
---|
72 | qsqr(temp, q);
|
---|
73 | qmult(q, emio, temp);
|
---|
74 | qadd(q, c);
|
---|
75 |
|
---|
76 | if (q.r*q.r + q.i*q.i + q.j*q.j + q.k*q.k > 8.0)
|
---|
77 | break;
|
---|
78 | }
|
---|
79 |
|
---|
80 | return((float)i);
|
---|
81 | }
|
---|
82 | };
|
---|
83 |
|
---|
84 |
|
---|
85 | Julia::Julia(float global_real, float global_imag, float global_theta):
|
---|
86 | global_real(global_real), global_imag(global_imag), global_theta(global_theta) {
|
---|
87 |
|
---|
88 | oc.r = global_real;
|
---|
89 | oc.i = global_imag;
|
---|
90 | oc.j = oc.k = 0.0;
|
---|
91 |
|
---|
92 | eio.r = cos(global_theta);
|
---|
93 | eio.i = sin(global_theta);
|
---|
94 | eio.j = 0.0;
|
---|
95 | eio.k = 0.0;
|
---|
96 |
|
---|
97 | emio.r = cos(-global_theta);
|
---|
98 | emio.i = sin(-global_theta);
|
---|
99 | emio.j = 0.0;
|
---|
100 | emio.k = 0.0;
|
---|
101 |
|
---|
102 | /***
|
---|
103 | *** multiply eio*c only once at the beginning of iteration
|
---|
104 | *** (since q |-> sqrt(eio*(q-eio*c)))
|
---|
105 | *** q -> e-io*q^2 - eio*c
|
---|
106 | ***/
|
---|
107 |
|
---|
108 | qmult(c, eio,oc);
|
---|
109 |
|
---|
110 | }
|
---|
111 |
|
---|
112 |
|
---|
113 | #endif
|
---|