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