1 /*
2 * sampling.c
3 *
4 * Copyright (C) 1989, 1991, Craig E. Kolb, Rod G. Bogart
5 * All rights reserved.
6 *
7 * This software may be freely copied, modified, and redistributed
8 * provided that this copyright notice is preserved on all copies.
9 *
10 * You may not distribute this software, in whole or in part, as part of
11 * any commercial product without the express consent of the authors.
12 *
13 * There is no warranty or other guarantee of fitness of this software
14 * for any purpose. It is provided solely "as is".
15 *
16 * $Id: sampling.c,v 4.0 91/07/17 14:31:55 kolb Exp Locker: kolb $
17 *
18 * $Log: sampling.c,v $
19 * Revision 4.0 91/07/17 14:31:55 kolb
20 * Initial version.
21 *
22 */
23 #include "common.h"
24 #include "sampling.h"
25
26 SampleInfo Sampling; /* sampling information */
27
28 /*
29 * Set sampling options.
30 */
31 void
SamplingSetOptions(n,gaussian,width)32 SamplingSetOptions(n, gaussian, width)
33 int n, gaussian;
34 Float width;
35 {
36 Float norm, u, v;
37 int x, y;
38
39 Sampling.sidesamples = n;
40 Sampling.totsamples = n*n;
41 Sampling.weight = 1. / (Float)Sampling.totsamples;
42 Sampling.spacing = 1. / (Float)Sampling.sidesamples;
43 Sampling.filterwidth = width;
44 Sampling.filterdelta = Sampling.filterwidth * Sampling.spacing;
45 Sampling.gaussian = gaussian;
46
47 Sampling.filter = (Float **)Malloc(Sampling.sidesamples
48 *sizeof(Float *));
49 for (y = 0; y < Sampling.sidesamples; y++) {
50 Sampling.filter[y] = (Float *)Malloc(Sampling.sidesamples *
51 sizeof(Float));
52 }
53 if (Sampling.gaussian) {
54 norm = 0.;
55 u = -0.5*Sampling.filterwidth +
56 0.5*Sampling.filterwidth*Sampling.spacing;
57 for (x = 0; x < Sampling.sidesamples; x++) {
58 v = -0.5*Sampling.filterwidth +
59 0.5*Sampling.filterwidth*Sampling.spacing;
60 for (y = 0; y < Sampling.sidesamples; y++) {
61 Sampling.filter[x][y] = exp(-0.5*(u*u+v*v));
62 norm += Sampling.filter[x][y];
63 v += Sampling.spacing *
64 Sampling.filterwidth;
65 }
66 u += Sampling.spacing * Sampling.filterwidth;
67 }
68
69 for (x = 0; x < Sampling.sidesamples; x++)
70 for (y = 0; y < Sampling.sidesamples; y++)
71 Sampling.filter[x][y] /= norm;
72 } else {
73 /* Box filter. Yawn. */
74 for (x = 0; x < Sampling.sidesamples; x++)
75 for (y = 0; y < Sampling.sidesamples; y++)
76 Sampling.filter[x][y] = Sampling.weight;
77 }
78 }
79
80 /*
81 * Set start time and duration of frame.
82 */
83 void
SamplingSetTime(starttime,shutter,frame)84 SamplingSetTime(starttime, shutter, frame)
85 Float starttime, shutter;
86 int frame;
87 {
88 Sampling.starttime = starttime;
89 Sampling.shutter = shutter;
90 Sampling.framenum = frame;
91 TimeSet(Sampling.starttime);
92 FrameSet((Float)frame);
93 }
94
95 /*
96 * Find a point on a unit circle that is separated from other random
97 * points by some jitter spacing.
98 *
99 * It should do the above, but the temporary hack below just finds a
100 * jittered point in a unit square.
101 */
102 void
UnitCirclePoint(pnt,sample)103 UnitCirclePoint(pnt, sample)
104 Vector *pnt;
105 {
106 /*
107 * This picks a random point on a -1 to 1 square. The jitter stuff
108 * is correct enough to avoid excessive noise. An extremely blurry
109 * bright highlight will look squarish, not roundish. Sorry.
110 */
111 Float jit;
112
113 if (sample >= 0) {
114 jit = 2. * Sampling.spacing;
115
116 pnt->x = nrand()*jit - 1.0 +
117 (sample % Sampling.sidesamples) * jit;
118 pnt->y = nrand()*jit - 1.0 +
119 (sample / Sampling.sidesamples) * jit;
120 pnt->z = 0.0;
121 } else {
122 pnt->x = nrand() * 2.0 - 1.0;
123 pnt->y = nrand() * 2.0 - 1.0;
124 pnt->z = 0.0;
125 }
126 }
127