ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/disk2square.c
Revision: 3.6
Committed: Wed Dec 15 01:39:52 2021 UTC (2 years, 4 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R4, HEAD
Changes since 3.5: +2 -1 lines
Log Message:
fix: added #include needed from last change

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: disk2square.c,v 3.5 2021/12/15 01:38:50 greg Exp $";
3 #endif
4 /*
5 * Disk2Square.c
6 *
7 * Code by Peter Shirley and Kenneth Chiu
8 *
9 * Associated paper in ~/Documents/Others/Shirley+Chiu_JGT-97.pdf
10 *
11 * Modified interface slightly (G. Ward)
12 */
13
14 #define _USE_MATH_DEFINES
15 #include <math.h>
16 #include "fvect.h"
17
18 /*
19 This transforms points on [0,1]^2 to points on unit disk centered at
20 origin. Each "pie-slice" quadrant of square is handled as a seperate
21 case. The bad floating point cases are all handled appropriately.
22 The regions for (a,b) are:
23
24 phi = pi/2
25 -----*-----
26 |\ /|
27 | \ 2 / |
28 | \ / |
29 phi=pi* 3 * 1 *phi = 0
30 | / \ |
31 | / 4 \ |
32 |/ \|
33 -----*-----
34 phi = 3pi/2
35
36 change log:
37 26 feb 2004. bug fix in computation of phi (now this matches the paper,
38 which is correct). thanks to Atilim Cetin for catching this.
39 */
40
41
42 /* Map a [0,1]^2 square to a unit radius disk */
43 void
44 square2disk(RREAL ds[2], double seedx, double seedy)
45 {
46
47 double phi, r;
48 double a = 2.*seedx - 1; /* (a,b) is now on [-1,1]^2 */
49 double b = 2.*seedy - 1;
50
51 if (a > -b) { /* region 1 or 2 */
52 if (a > b) { /* region 1, also |a| > |b| */
53 r = a;
54 phi = (M_PI/4.) * (b/a);
55 }
56 else { /* region 2, also |b| > |a| */
57 r = b;
58 phi = (M_PI/4.) * (2. - (a/b));
59 }
60 }
61 else { /* region 3 or 4 */
62 if (a < b) { /* region 3, also |a| >= |b|, a != 0 */
63 r = -a;
64 phi = (M_PI/4.) * (4. + (b/a));
65 }
66 else { /* region 4, |b| >= |a|, but a==0 and b==0 could occur. */
67 r = -b;
68 if (b != 0.)
69 phi = (M_PI/4.) * (6. - (a/b));
70 else
71 phi = 0.;
72 }
73 }
74 r *= 0.9999999999999; /* prophylactic against MS sin()/cos() impl. */
75 ds[0] = r * cos(phi);
76 ds[1] = r * sin(phi);
77
78 }
79
80 /* Map point on unit disk to a unit square in [0,1]^2 range */
81 void
82 disk2square(RREAL sq[2], double diskx, double disky)
83 {
84 double r = sqrt( diskx*diskx + disky*disky );
85 double phi = atan2( disky, diskx );
86 double a, b;
87
88 if (phi < -M_PI/4) phi += 2*M_PI; /* in range [-pi/4,7pi/4] */
89 if ( phi < M_PI/4) { /* region 1 */
90 a = r;
91 b = phi * a / (M_PI/4);
92 }
93 else if ( phi < 3*M_PI/4 ) { /* region 2 */
94 b = r;
95 a = -(phi - M_PI/2) * b / (M_PI/4);
96 }
97 else if ( phi < 5*M_PI/4 ) { /* region 3 */
98 a = -r;
99 b = (phi - M_PI) * a / (M_PI/4);
100 }
101 else { /* region 4 */
102 b = -r;
103 a = -(phi - 3*M_PI/2) * b / (M_PI/4);
104 }
105
106 sq[0] = a*(0.5/0.9999999999999) + 0.5;
107 sq[1] = b*(0.5/0.9999999999999) + 0.5;
108 }