Vous êtes sur la page 1sur 8

Simple Raytrace Algorithm

5th February 2007

Introduction

This document describes the mathematical formulation implemented in the raytracing program(s) that go along with the Week 5 lab. This particular algorithm is at the heart of each program, performing the mathematical operations relevant to each surface encounter. The main program does the book-keeping of initializing rays and propagating them through the system. The algorithm described here simply computes the intersection of a ray with a (generally) curved surface, computes the surface normal, and applies Snells law to arrive at the new ray position and direction.

Dening the Surfaces

Most of the time we will use spherical surfaces, but lets allow aspherical surfaces as wellin particular ellipses and hyperbolas. We will assume the optical axis of the system to be the x-axis, and only concern ourselves with rays in the x-y plane. A sphere (circle in 2-d) lying along the x-axis is described by the following equation: (x xc )2 + y 2 = R2 , (1)

where xc is the location of the center of the sphere along the x-axis, and R is the sphere radius. Similarly, an ellipse with semi-major axis, a, and semi-minor axis, b, is described by: (x xc )2 y2 + 2 = 1. 2 a b And nally, a hyperbola opening into the x-direction follows: (x xc )2 y2 2 = 1, 2 (3) (2)

where is the distance from the origin to the vertex of each hyperbolic segment, and the asymptotic slope is /. We can generalize all three of these by the relation: (x xc )2 + qy 2 = R 2 , (4)

where q is a constant describing the nature of the curve, and R is a type of radius. Inspection of Equations 14 reveal that q is positive for ellipses and spheres (q = 1.0 for a sphere), and negative for hyperbolae. Also, R = R for the sphere, R = a for the ellipse (thus the semi-major axis), and R = for the hyperbola. In all three cases, then, R describes the distance from the coordinate origin (where x = xc ) to the vertex. The parameter, q, is a2 /b2 in the case of the ellipse, and 2 / 2 in the case of the hyperbola. A large, positive value of q then represents a low, squashed ellipse, while small positive values of q represent a tall ellipse. A large negative value of q makes a sharp (acute) 1

hyperbola, while 1 < q < 0 makes a dull, obtuse hyperbola. Parabolas correspond to the limit as |q| , but numerical problems result from this choice. Since we want to describe each surface by its radius of curvature at the vertex, we must obtain the second derivative of x(y) at y = 0 and equate this with the inverse of the radius of curvature. Doing so, we get: x(y) = (R 2 qy 2 ) 2 , x (y) = qy(R 2 qy 2 ) 2 , x (y) = q(R qy )
2 2 1 2
1 1

(5) (6)
3 2

q y (R qy) |q| 1 , R R

2 2

(7) (8) (9)

|x (y = 0)| = so that

|R | = |qR| .

The last step in specifying the surface is to locate the origin appropriate to Equation 4, relative to the known vertex location. We want to specify each surface by its vertex position and radius (and q-value). Adopting the convention that R > 0 if the center of curvature is to the right of the vertex, and R < 0 if the center of curvature is to the right, we notice that the coordinate origin is at xc = xv + qR, where xc is the curves coordinate origin, and xv is the appropriate vertex location. Note that both q and R can vary in sign. For closed curves (circles and ellipses), q > 0, so that positive R puts the curve origin to the right of the vertex, and negative R puts the origin to the leftjust as it should be. For hyperbolae, q is negative, but the hyperbola with a negative R (opens to the left) is indeed to the left of the origin, so that the origin (xc ) should be to the right. If we therefore adopt R = qR, and the coordinate origin xc = xv + R , then the general formula for the curve is: (x xv R )2 + ky 2 = R 2 . (11) (10)

Ray Intersection

We will dene the ray segment, labeled by the subscript i as we must deal with multiple segments, as passing through the point (xi , yi ), and traveling at an angle i relative to the x-axis. It is assumed that the ray is traveling from left-toright, and i is positive if the rays y-value increases as it travels to the right (to larger x-values). The ray therefore has a slope: mi = tan i . (12) The ray segments position (backward or forward) therefore satises y = yi + mi (x xi ). (13)

The intersection of this ray segment with the optical curve of interest is given by the joint solution of Equation 11 and Equation 13. To this end, we substitute the y-value determined from Equation 13 into Equation 11 to get (x xv R )2 + q(yi + mi x mi xi )2 = R 2 , which can be expanded and rearranged to yield x2 + 2 qmi yi qm2 xi xv R i 1 + qm2 i x+
2 x2 + qyi + qm2 x2 + 2R xv 2qmi xi yi v i i = 0, 1 + qm2 i

(14)

(15)

which has the form: x2 + 2bx + c = 0, and this has the familiar quadratic solution: x = b with b= and c= b2 c, (16)

qmi yi qm2 xi xv R i , 1 + qm2 i

(17)

2 x2 + qyi + qm2 x2 + 2R xv 2qmi xi yi v i i . 1 + qm2 i

(18)

Now one simply inserts the solutions for b and c into Equation 16 to nd the surface intersections. But notice there are two roots. This should be the case for a line intersecting a circle, ellipse, or hyperbola: provided there is any non-tangent intersection there will be two. Which one do we want? For the circle and ellipse, we want the left-hand (negative root) solution when R (from the vertex of interest) is positive, and we want the right-hand (positive root) solution when R is negative. For the hyperbola, it is the opposite: we want the left (negative root) curve when R is negative and the right (positive root) curve when R is positive. But note that R = qR tells a consistent story, since q is negative for the hyperbolic case. So the rule becomes: if R < 0, x = b + b2 c; if R > 0, x = b b2 c. Note that the math still works for R to represent a planar interface. However, a computer will have numerical roundoff problems, so it is best to detect R > Rmax and treat such cases as planar. The intersection solution in this case is a trivial calculation of Equation 13, with x set to the x-value of the plane.

Surface Normal

Now that we have established the (x, y) value of the ray intersection, we must determine the angle of the surface normal at this location. Note that the surface normal for a circle at (x, y) has a tangent that is simply y/x, provided the center of the circle is at the coordinate origin. Note that the sign is also correct for all cases. For the general case, we can use Equation 6, noting that x = qy/x. The surface slope would be described by y dy/dx, so the slope of the normal would be the inverse of this: 1/y = dx/dy x up to a sign. A coordinate ip compensates the usual negative sign in this inverse-slope association, so that indeed the slope of the normal looks like qy/x. Now accounting for the displacement of the curves coordinate origin (as discussed in the paragraph following Equation 9), we have: tan n = qyint , xint xv R (19)

where subscripts denote the intersection coordinates and the vertex position.

Snells Law

Relating the incident ray angle, i to the outgoing ray angle, i+1 , using the surface normal angle, n , obtained from Equation 19, we rst dene in = i n . (20) Then, we apply Snells law: ni sin in = ni+1 sin out , 3 (21)

or explicitly, out = sin1 ni sin in . ni+1 (22)

And nally, we re-transform the out ray with respect to the surface normal: i+1 = out + norm . (23)

The Final Ray

The new ray segment passes through the intersection found via Equation 16. We call the x solution xi+1 , so that yi+1 = yi + mi (xi+1 xi ). Together with the angle i+1 from Equation 23, we have a full description of the new ray in space. From this point, we can either iterate for the next surface, or describe where this ray intersects the x-axis, a selected x-plane, or another ray of choice.

Notes on Subtleties

Each intersection is computed without reference to whether the designated pass-through point is to the left or right of the surface. An example of how this can be bad is if a bi-convex (positive) lens is too thin, such that the spheres occur in the wrong order far from the optical axis. The ray will blithely intersect them in this wrong order, dutifully following Snells Law, producing an unphysical ray path. A warning in the algorithm can alert you to any ray whose x-intersection jumps backward from one surface to the next. An example of where this might be good is if you want to dene your initial ray at the center of the lens rather than far out to the left, there is no penalty. For example, if I want a ray whose angle to the optical axis is 0.1 radians, and I want this ray to encounter the rst lens (at x = 0, say) at a height of 5 mm, then I can specify the initial position as (0.0,5.0) with an angle of 0.1, rather than at (100.0, -5.0) with an angle of 0.1. The math is simplied. Likewise, if I want the original ray to head for a specied point to the right of the optic (in the absence of the optic), then I simply specify the ray through that point. The calculation will backtrack to the appropriate rst-surface intersection.

Computer Code and Example

The following listing compiles and runs in C. Command line arguments are surface lename, initial x-position, initial y-position, and initial slope (tangent to the angle) relative to the optical axis. Optionally, the x-value of a nal screen may be entered to probe the y-value at which the nal ray pierces this screen (otherwise set to x = 0). #include <stdio.h> #include <stdlib.h> #include <math.h> // for printf, sscanf // for exit() // for trig, sqrt

void ray_step(double *in_ray, double *surface, double *out_ray); int main(int argc, char* argv[]) { double x[20],y[20],thet[20],n[20],x_vert[20],R[20],q[20]; double in_ray[3],out_ray[3],surf_params[5]; double slope,current_x; double screen_pos=0.0,xf,yf,thetf,mf,screen_intercept,x_intercept; int n_surf,i; 4

char filename[40]; FILE *lens_file; if (argc > 4) // must have at least these four { // command line arguments sscanf(argv[1],"%s",filename); sscanf(argv[2],"%lf",&x[0]); sscanf(argv[3],"%lf",&y[0]); sscanf(argv[4],"%lf",&slope); } else { printf("Must supply lens_file_name x0, y0, slope arguments\n"); exit(1); } if (argc > 5) { sscanf(argv[5],"%lf",&screen_pos); } thet[0] = atan(slope); // optionally, put a screen somewhere

// input slope --> angle in radians

lens_file = fopen(filename,"r"); // grab lens surface parameters fscanf(lens_file,"%d",&n_surf); // number of surfaces (first line) fscanf(lens_file,"%lf",&n[0]); // initial refr. index (2nd line) for (i = 0; i < n_surf; i++) // and n_surf additional lines... { fscanf(lens_file,"%lf %lf %lf %lf",&n[i+1],&x_vert[i+1],&R[i+1],&q[i+1]); printf("Surface %d has n = %f, x_vert = %f, radius = %g, q = %f\n", i+1,n[i+1],x_vert[i+1],R[i+1],q[i+1]); } close(lens_file); printf("Ray 1 has x = %f; y = %f; thet = %f\n",x[0],y[0],thet[0]); current_x = 0.0; for (i = 0; i < n_surf; i++) { // populate in_ray array in_ray[0] = x[i]; in_ray[1] = y[i]; in_ray[2] = thet[i]; // populate surface parameters array current_x += x_vert[i+1]; surf_params[0] = n[i]; surf_params[1] = current_x;

// now propagate surface-at-a-time // begin ray propagation for loop

surf_params[2] = R[i+1]; surf_params[3] = q[i+1]; surf_params[4] = n[i+1]; ray_step(in_ray,surf_params,out_ray); // stow out_ray into approp. arrays x[i+1] = out_ray[0]; y[i+1] = out_ray[1]; thet[i+1] = out_ray[2]; printf("Ray %d has x = %f; y = %f; thet = %f\n", i+2,x[i+1],y[i+1],thet[i+1]); } // end ray propagation for loop // final ray parameters xf = x[n_surf]; yf = y[n_surf]; thetf = thet[n_surf]; mf = tan(thetf); // compute intercepts screen_intercept = yf + mf*(screen_pos - xf); x_intercept = xf - yf/mf; printf("Final ray intercepts screen at y = %f; x-axis at x = %f\n", screen_intercept, x_intercept); } void ray_step(double *in_ray, double *surface, double *out_ray) { double x0,y0,thet0,n0,x_v,R,q,Rp,n_new,root_sign; double m,denom,b,c,thet_norm,thet_in,thet_out; double x_new,y_new,thet_new; // rename in_ray components for clarity x0 = in_ray[0]; y0 = in_ray[1]; thet0 = in_ray[2]; // rename surface params for clarity n0 = surface[0]; x_v = surface[1]; R = surface[2]; q = surface[3]; n_new = surface[4]; Rp = q*R; root_sign = -Rp/fabs(Rp); // carry out calculation

// determined from radius sign and q

// compute solution to quadratic formula m = tan(thet0); denom = 1.0 + q*m*m; b = (q*m*y0 - q*m*m*x0 - x_v - Rp)/denom; c = (x_v*x_v + q*y0*y0 + q*m*m*x0*x0 + 2.0*Rp*x_v - 2.0*q*m*x0*y0)/denom; x_new = -b + root_sign*sqrt(b*b - c); y_new = y0 + m*(x_new - x0); if (fabs(R) > 1.0e10) { x_new = x_v; y_new = y0 + m*(x_new - x0); } thet_norm = atan(q*y_new/(x_new - x_v - Rp)); thet_in = thet0 - thet_norm; thet_out = asin(n0*sin(thet_in)/n_new); thet_new = thet_out + thet_norm; if (x_new < x0) printf("WARNING: ray jumped backwards!\n"); out_ray[0] = x_new; out_ray[1] = y_new; out_ray[2] = thet_new; }

8.1

Example Input File

The input le for a beam expander looks like: 4 1.0 1.5 -1.5 -100.0 1.0 1.0 3.0 1.0e20 1.0 1.5 198.5 1.0e20 1.0 1.0 4.0 -201.55 1.0 The rst line indicates the number of surfaces. The second line indicates the initial refractive index. Each following line represents a surface. For each, the elds are as follows: the refractive index that one passes into by traversing the surface The x-displacement from the last vertex (initialized to zero) the radius of curvature: positive means center of curvature is to the right the q-constant describing the shape

In this example, the vertices lie at x-values of 1.5, 1.5, 200.0, and 204.0, respectively (the numbers in the le represent separation from the last vertex). The rst lens is a negative lens, and the second a positive lens. Surfaces are either spherical (all have q = 1.0) or planar (huge R).

8.2

Example Output

Example output of the code looks like the following: ./one_ray beam_expander -10.0 5.0 0.0 300.0 Surface 1 Surface 2 Surface 3 Surface 4 Ray 1 has Ray 2 has Ray 3 has Ray 4 has Ray 5 has Final ray has n = 1.500000, x_vert = -1.500000, radius = -100, q = 1.000000 has n = 1.000000, x_vert = 3.000000, radius = 1e+20, q = 1.000000 has n = 1.500000, x_vert = 198.500000, radius = 1e+20, q = 1.000000 has n = 1.000000, x_vert = 4.000000, radius = -201.55, q = 1.000000 x = -10.000000; y = 5.000000; thet = 0.000000 x = -1.625078; y = 5.000000; thet = 0.016681 x = 1.500000; y = 5.052135; thet = 0.025023 x = 200.000000; y = 10.020332; thet = 0.016681 x = 203.747637; y = 10.082853; thet = -0.000013 intercepts screen at y = 10.081571; x-axis at x = 756938.486328

The ray starts at (10, 5), initially horizontal. A screen has been placed at x = 300. The nal ray leaves the lens at (203.747637,10.082853) at an angle of 0.000013. This ray will cross the x-axis at x = 756938.5 (far away: nearly level).

Vous aimerez peut-être aussi