|
| 1 | +function [p,e0]=ray2surf(node,elem,p0,v0,e0) |
| 2 | +% |
| 3 | +% [p,e0]=ray2surf(node,elem,p0,v0,e0) |
| 4 | +% |
| 5 | +% Determine the entry position and element for a ray to intersect a mesh |
| 6 | +% |
| 7 | +% author: Qianqian Fang (q.fang <at> neu.edu) |
| 8 | +% |
| 9 | +% input: |
| 10 | +% node: the mesh coordinate list |
| 11 | +% elem: the tetrahedral mesh element list, 4 columns |
| 12 | +% p0: origin of the ray |
| 13 | +% v0: direction vector of the ray |
| 14 | +% e0: search direction: '>' forward search, '<' backward search, '-' bidirectional |
| 15 | +% |
| 16 | +% output: |
| 17 | +% p: the intersection position |
| 18 | +% e0: if found, the index of the intersecting element ID |
| 19 | +% |
| 20 | +% this file is part of Mesh-based Monte Carlo (MMC) |
| 21 | +% |
| 22 | +% License: GPLv3, see http://mcx.sf.net/mmc/ for details |
| 23 | +% |
| 24 | + |
| 25 | +p=p0; |
| 26 | +if(size(elem,2)==3) |
| 27 | + face=elem; |
| 28 | +else |
| 29 | + face=volface(elem); |
| 30 | +end |
| 31 | +[t,u,v,idx]=raytrace(p0,v0,node,face); |
| 32 | +if(isempty(idx)) |
| 33 | + error('ray does not intersect with the mesh'); |
| 34 | +else |
| 35 | + t=t(idx); |
| 36 | + if(e0=='>') |
| 37 | +% idx1=find(t>=0); |
| 38 | + idx1=find(t>=1e-10); |
| 39 | + elseif(e0=='<') |
| 40 | + idx1=find(t<=0); |
| 41 | + elseif(isnan(e0) || e0=='-') |
| 42 | + idx1=1:length(t); |
| 43 | + else |
| 44 | + error('ray direction specifier is not recognized'); |
| 45 | + end |
| 46 | + if(isempty(idx1)) |
| 47 | + error('no intersection is found along the ray direction'); |
| 48 | + end |
| 49 | + t0=abs(t(idx1)); |
| 50 | + [tmin,loc]=min(t0); |
| 51 | + faceidx=idx(idx1(loc)); |
| 52 | + |
| 53 | + % update source position |
| 54 | + p=p0+t(idx1(loc))*v0; |
| 55 | + |
| 56 | + if(nargout<2) |
| 57 | + return; |
| 58 | + end |
| 59 | + |
| 60 | + % find initial element id |
| 61 | + if(size(elem,2)==3) |
| 62 | + e0=faceidx; |
| 63 | + else |
| 64 | + felem=sort(face(faceidx,:)); |
| 65 | + f=elem; |
| 66 | + f=[f(:,[1,2,3]); |
| 67 | + f(:,[2,1,4]); |
| 68 | + f(:,[1,3,4]); |
| 69 | + f(:,[2,4,3])]; |
| 70 | + [tf,loc]=ismember(felem,sort(f,2),'rows'); |
| 71 | + loc=mod(loc,size(elem,1)); |
| 72 | + if(loc==0) loc=size(elem,1); end |
| 73 | + e0=loc; |
| 74 | + end |
| 75 | +end |
0 commit comments