def apeture(rays, radius = 1, center = [0,0,0]): shift2origin = rays['position'] - center.append(1); dist2 = sum(shift2origin*shift2origin, axes = 1); hit, miss = hitAndMiss(rays, dist2 <= radius*radius); return hit, miss
def refract(rays, surfMatrix, n2 = 1): #%refract(rays, surfMatrix, n2) #%this function expects unit vectors to come in. #%the equation is based on a derivation in the book Introduction to Ray Tracing by glassner r = rays['n_index']/n2; #ratio n1/n2 rays['n_index'][:] = n2; gradVec = getGrad(rays,surfMatrix); cos1 = np.sum(-rays['direction']*gradVec,axis = 1); gradVec[cos1<0,:] = -gradVec[cos1<0,:]; cos1 = np.sum(-rays['direction']*gradVec,axis = 1); cos2 = np.lib.scimath.sqrt(1-r*r*(1-cos1*cos1)); #%if imaginary, there was internal reflection; toRefl = cos2.imag != 0; #cos1 = repmat(cos1,1,4); cos2 = repmat(cos2,1,4); refl = rays['direction'] - (2*cos1*gradVec.T).T; rays['direction'] = (r * ((rays['direction']-(cos1*gradVec.T).T) - (cos2*gradVec.T).T).T).T;#refract these rays rays['direction'][:,toRefl] = refl[:,toRefl];#reflect these rays #%I believe this is an unnecessary check to ensure that the result is #% %normalized; it is guaranteed to be normalized by the equation above. #% mag = sqrt(dot(rays.direction(1:3,:),rays.direction(1:3,:),1)); #% mag(mag == 0) = 1; #% rays.direction(1:3,:) = rays.direction(1:3,:)./[mag;mag;mag]; #% rays.direction(4,:) = 0; #%the 'rule of thumb' for phase reflections caused by refraction is: #%n1 to n2: if high to low? Phase shift no! #% if low to high? Phase shift pi! if n1 < n2: #% := phase + 'pi' rays['phase'] = (rays['phase'] + rays['wavelength']/2) % rays['wavelength']; # %rays.wavephase = arrayfun(@(x,y) mod(x,y),rays.wavephase,rays.wavelength); #end reflected, refracted = hitAndMiss(rays, toRefl); return refracted;
def get2surf(rays, surfMatrix): #function [rays, missRays] = get2surf(rays, surfMatrix) #%get2surf(rays, surfMatrix) takes an array of rays, and determines if and when they will intersect the surface described by surfMatrix. #% %a lot of thanks go to #% https://www.cs.uaf.edu/2012/spring/cs481/section/0/lecture/01_26_ray_intersections.html, #% but the simple version is that a ray is defined as a vector [A + tB], #% where A and B are known vectors like [1,2,0] + t*[3,1.5,2] #% and a surface is defined as an equation in xyz, like 3x + y - z = 0. #% We combine the two equations, solve for t, and that is how far the #% vector must travel to reach its destination. # global visualize; surfD = np.zeros_like(rays['direction']); surfP = surfD.copy(); #for i in range(rays[direction].shape[1]) = 1:size(rays.direction,1) surfD = np.dot(rays['direction'] , surfMatrix) ; surfP = np.dot(rays['position' ] , surfMatrix) ; a = np.sum(surfD * rays['direction'],axis = 1); #a*t^2 b = np.sum(surfD * rays['position' ],axis = 1) + np.sum(surfP*rays['direction'],axis = 1); #b*t c = np.sum(surfP * rays['position' ],axis = 1); #c*1 t = np.zeros_like(a); #distRoot = np.array([np.zeros_like(a),np.zeros_like(b)],float ); #for indx in range(len(a)): # distRoot[indx,:] = np.roots([a[indx],b[indx],c[indx]]); # now we are going to solve for what t is for each equation. There are several cases, so we update them as we cover them. # First check if there actually is an a*t^2 component -- if not, our math is easy x = -c/b badCase = np.array([np.inf],float); #if we didn't intersect by the time we traveled to infinity up = np.abs(a) < .0001; t[up] = -c[up]/b[up]; #now for those weird cases when there wasn't an a or a b-->aka there is no intersection. Mark these cases t[up & (np.abs(b) < .001)] = badCase; #now for the regular case--we don't need to update the previous sets anymore up = ~up; #for the regular case, use the quadratic formula: x = (-b +- sqrt(b^2-4ac)) / 2a # sqrtQuad = sqrt(b^2-4ac) sqrtQuad = np.sqrt(b[up]*b[up]-4*a[up]*c[up]); temp1 = (-b[up] + sqrtQuad); temp1[[any(bad) for bad in np.array((temp1.imag !=0, temp1.real <= 0)).T]] = badCase; temp2 = (-b[up] - sqrtQuad); temp2[[any(bad) for bad in np.array((temp2.imag !=0, temp2.real <= 0)).T]] = badCase; t[up] = np.min([temp1,temp2],axis = 0); #if t.count(badCase): # isMiss = t.index(badCase); #else: # isMiss = np.array([]); isHit = (t != badCase); (hitRays, missRays) = hitAndMiss(rays,isHit); t = t[isHit]; hitRays = propigate(hitRays,t); return (hitRays,missRays);