⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 el_buttonmotion.m

📁 基于matlab的反演程序,用于地球物理勘探中射线追踪及偏移成像程序.
💻 M
字号:
function el_buttonmotion(action)

	 % we are dragging a point of the current line
	 % find the clicked point
	stuff=get(gca,'userdata');
	lit=stuff(1,1);
	it=stuff(1,2:lit+1);
	hstor=stuff(1,lit+2);
	%xpt=stuff(1,lit+3);
	%ypt=stuff(1,lit+4);
	hline=stuff(1,lit+5);
	hline2=stuff(1,lit+6);
	hline3=stuff(1,lit+7);
	if( hline3 )
		line_anchors=stuff(1,lit+8:length(stuff(1,:)));
		nanchors=length(line_anchors)/2;
	else
		nanchors=0;
		line_anchors=[];
	end
	xonly=stuff(2,1);
	yonly=stuff(2,2);
	killrd=stuff(2,3);
	ispoly=stuff(2,4);
	locate=stuff(2,5);
	htext=stuff(2,6);
	dragmode=stuff(2,7);
	linkmode=stuff(2,8);
	fastopt=stuff(3,1);
	
	if(linkmode)
		set(gcf,'windowbuttonupfcn','editlines(''link'')');
	else
		set(gcf,'windowbuttonupfcn','editlines(''stopmotion'')');
	end
	
	pt=get(gca,'currentpoint');
	xpt=pt(1,1);
	ypt=pt(1,2);		

	% get the lines data	
	x=get(hline,'xdata');
	y=get(hline,'ydata');
	npts=length(x);
		

	if( strcmp(action,'button1motion') ) % drag a single point
	% see if we are trying to drag an anchor
		if( nanchors )
			ind=find( x(it(1))==line_anchors(1:2:2*nanchors) );
			if( length(ind)> 0)
				ooohh = find(y(it(1))==line_anchors(2*ind));
				if( length(ooohh) > 0)
					% simply return
					return;
				end
			end
		end
		
		%check for accidental drag of a segment separator
		if( isnan(x(it)) | isnan(y(it)) )
			return;
		end

		% correct for xonly and yonly

		xpt = xpt*(1-yonly)+x(it(1))*yonly;
		ypt = ypt*(1-xonly)+y(it(1))*xonly;
 
		if(htext)
			delete(htext);
			htext=0;
			stuff(2,6)=0;
			set(gca,'userdata',stuff);
		end
		if(locate)
			htext=text(xpt,ypt,['(' num2str(xpt) ',' num2str(ypt) ')'],'erasemode',...
			'xor','color',[.5 .5 .5]);
			stuff(2,6)=htext;
			set(gca,'userdata',stuff);
		end
		% see if its a polygon
		done=0;
		if(ispoly)
			if(it(1)==1 | it(1)==npts)
				xpt = xpt(1)*(1-yonly)+x(it(1))*yonly;
				ypt = ypt(1)*(1-xonly)+y(it(1))*xonly;
				x=[xpt x(2:npts-1) xpt];
				y=[ypt y(2:npts-1) ypt];
				done=1;
			end
		end

		if(~done)
			if(lit>1)
				if( x(it(1))==x(it(2)) & y(it(1))==y(it(2)) )
					it=it(1);
					stuff(1,3:2+lit-1)=stuff(1,2)*ones(size(stuff(1,3:2+lit-1)));
					set(gca,'userdata',stuff);
				else
					error(' you may only move nodes not segments ');
				end
			end
			xpt = xpt*(1-yonly)+x(it)*yonly;
			ypt = ypt*(1-xonly)+y(it)*xonly;
			x=[x(1:it-1) xpt x(it+1:npts)];
			y=[y(1:it-1) ypt y(it+1:npts)];
		end

		if(fastopt & ~linkmode)
			xmoved=xpt;
			ymoved=ypt;
		end
		
	elseif( strcmp(action,'button2motion') ) %kill points the pointer drags by
		% find the points in a local box
		ind=between(xpt-10*killrd,xpt+10*killrd,x,2);
		if(isempty(ind)|ind==0) return; end
		ind2=between(ypt-10*killrd,ypt+10*killrd,y(ind),2);
		if(isempty(ind2)|ind2==0) return; end
		
		% find the point closest to the current point
		d=abs(x(ind(ind2))-xpt) + abs(y(ind(ind2))-ypt);
		dkill=min(d);
		
		ik=find( d==min(d) );
		itkill=ind(ind2(ik));
		% see if we are trying to drag-kill an anchor
		if( nanchors )
			ind=find( x(itkill)==line_anchors(1:2:2*nanchors) );
			if( length(ind)> 0)
				ooohh = find(y(itkill)==line_anchors(2*ind));
				if( length(ooohh) > 0)
					% simply return
					return;
				end
			end
		end
		
		%check for accidental deletion of a segment separator
		if( isnan(x(itkill)) | isnan(y(itkill)) )
			return;
		end
		
		% see if it is a polygon endpoint
		done=0;
		if(ispoly)
			if( itkill ==1 | itkill==npts )
				x=[x(2:npts-1) x(2)];
				y=[y(2:npts-1) y(2)];
				npts=length(x);
				done=1;
			end
		end
		
		if(~done)
			x=[x(1:itkill-1) x(itkill+1:npts)];
			y=[y(1:itkill-1) y(itkill+1:npts)];
			npts=length(x);
		end

	elseif( strcmp(action,'button3motion') ) % move all points between anchors
	% see if we are trying to drag an anchor
		if( nanchors )
			ind=find( x(it(1))==line_anchors(1:2:2*nanchors) );
			if( length(ind)> 0)
				ooohh = find(y(it(1))==line_anchors(2*ind));
				if( length(ooohh) > 0)
					% simply return
					return;
				end
			end
		end
		
	%check for accidental drag of a segment separator
		if( isnan(x(it)) | isnan(y(it)) )
			return;
		end

	% display locate information if required
		if(htext)
			delete(htext);
			htext=0;
			stuff(2,6)=0;
			set(gca,'userdata',stuff);
		end
		if(locate)
			htext=text(xpt,ypt,['(' num2str(xpt) ',' num2str(ypt) ')'],'erasemode',...
			'xor','color',[.5 .5 .5]);
			stuff(2,6)=htext;
			set(gca,'userdata',stuff);
		end

		% see if its a polygon
		
		% compute the displacement
			xdisp = (xpt-x(it))*(1-yonly);
			ydisp = (ypt-y(it))*(1-xonly);
		
		if( ~nanchors ) % see if the curve is free floating
			
			x=x+xdisp(1);
			y=y+ydisp(1);

			if(fastopt)
				xmoved=x;
				ymoved=y;
			end
		
		elseif(ispoly) % treat polygons as a special case
		
			if( length(it)>1 )
				if(it(1)==1 & it(2) ==npts)|(it(1)==npts & it(2)==1 )
					it=1;
					xdisp = xdisp(1);
					ydisp = ydisp(1);
				end
			end
		
		% determine the indicies of the anchors
			ia=[];
			for k=1:nanchors
				ind=find( x == line_anchors(2*k-1) );
				ii = find( y(ind) == line_anchors(2*k) );
				ia=[ia ind(ii)];
			end
			% don't count endpoints twice
			iend=find(ia==npts);
			if( iend )
				ia=[ia(1:iend-1) ia(iend+1:length(ia))];
			end
			
		% find the anchors on either side of it
			% first go ccw
			a1=0;
			itest=it;
			wrap1=0;
			while(~a1)
				%decrement
				itest=itest-1;
				if(itest==0) %check for wrap around
					itest=npts;
					wrap1=1;
				end
				% see if itest is an anchor
				ind=find(itest==ia);
				if(ind)
					a1=itest;
				end
			end
			
			% now go clockwise
			a2=0;
			itest=it;
			wrap2=0;
			while(~a2)
				%increment
				itest=itest+1;
				if(itest==npts+1)
					itest=1;
					wrap2=1;
				end
				%see if test is an anchor
				ind=find(itest==ia);
				if(ind)
					a2=itest;
				end
			end
			
		% now the cases.
		% case1 occurs when the drag point ('it')
		% is on the opposite side of the polygon from the endpoints
		% Case 2 is when they are on the same side. Case 2 is the only possibility
		% when there is a single anchor
		%if( a1~=a2 )
			case1=0;
			if(between(a1,a2,it)) case1=1;
			%elseif( a1==1 & between(npts,a2,it) ) case1=0;
			%elseif( a2==1 & between(a1,npts,it) ) case1=0;
			end
			
			done=0;
			if( case1 ) % see if 'it' is opposite the endpoints
				if(dragmode) % constant drag
					xdvec=zeros(1,npts);
					xdvec(a1+1:a2-1)=xdisp*ones(size(a1+1:a2-1));
					ydvec=zeros(1,npts);
					ydvec(a1+1:a2-1)=ydisp*ones(size(a1+1:a2-1));
				else % elastic drag
					 % compute the x displacement
					xdvec = zeros(1,npts); % start with zero
					xinc1=xdisp/(it-a1);
					xinc2=xdisp/(a2-it);
					xdvec(a1+1:a2-1) = [(1:it-a1)*xinc1 xdisp-(1:a2-it-1)*xinc2];
				
					% compute the y displacement
					ydvec = zeros(1,npts); % start with zero
						yinc1=ydisp/(it-a1);
					yinc2=ydisp/(a2-it);
					ydvec(a1+1:a2-1) = [(1:it-a1)*yinc1 ydisp-(1:a2-it-1)*yinc2];
				end
				
				done=1;
			else % case 2
				% case two is complicated because 'it' is on the same side of
				% the polygon as the endpoints
				xdvec=zeros(1,npts); % start with zero
				ydvec=zeros(1,npts); % start with zero
					
				% determine ccw distance to a1
				if(wrap1) 
					d1=npts+it-1-a1;
				else
					d1=(it-a1);
				end
				
				%cw distance to anchor a2
				if(wrap2)
					d2=npts+a2-1-it;
				else
					d2=a2-it;
				end
				
				xinc1=xdisp/d1;
				xinc2=xdisp/d2;
				yinc1=ydisp/d1;
				yinc2=ydisp/d2;
				
				% determine ccw displacment vector
				if(wrap1)
					if(dragmode) %do constant drag
						xdvec(1:it)=xdisp*ones(size(1:it));
						xdvec(a1+1:npts)=xdisp*ones(size(a1+1:npts));
						ydvec(1:it)=ydisp*ones(size(1:it));
						ydvec(a1+1:npts)=ydisp*ones(size(a1+1:npts));
					else
						xdvec(1:it) =[xdisp+((-it+1):0)*xinc1];
						xdvec(npts-1:-1:a1)=[((npts-a1-1):-1:0)*xinc1];
						xdvec(npts)=xdvec(1);
						ydvec(1:it) =[ydisp+((-it+1):0)*yinc1];
						ydvec(npts-1:-1:a1)=[((npts-a1-1):-1:0)*yinc1];
						ydvec(npts)=ydvec(1);
					end
				else
					if(dragmode)
						xdvec(a1+1:it)=xdisp*ones(size(a1+1:it));
						ydvec(a1+1:it)=ydisp*ones(size(a1+1:it));
					else
						xdvec(a1:it) = [(0:(it-a1))*xinc1];
						ydvec(a1:it) = [(0:(it-a1))*yinc1];
					end
				end
				
				% determine cw displacement vector
				if(wrap2)
					if (dragmode)% do constant drag
						if(a2==1)
							xdvec(it:npts-1)=xdisp*...
								ones(size(it:npts-1));
							ydvec(it:npts-1)=ydisp*...
								ones(size(it:npts-1));
						else
						   xdvec(it:npts)=xdisp*ones(size(it:npts));
						   xdvec(1:a2-1)=xdisp*ones(size(1:a2-1));
						   ydvec(it:npts)=ydisp*ones(size(it:npts));
						   ydvec(1:a2-1)=ydisp*ones(size(1:a2-1));
						end
					else	
						xdvec(it:npts) = [xdisp-(0:(npts-it))*xinc2];
						xdvec(2:a2) = [((a2-2):-1:0)*xinc2];
						xdvec(1)=xdvec(npts);
						ydvec(it:npts) = [ydisp-(0:(npts-it))*yinc2];
						ydvec(2:a2) = [((a2-2):-1:0)*yinc2];
						ydvec(1)=ydvec(npts);
					end
				else
					if(dragmode)
						xdvec(it:a2-1)=xdisp*ones(size(it:a2-1));
						ydvec(it:a2-1)=ydisp*ones(size(it:a2-1));
					else
						xdvec(it:a2) = [xdisp-(0:(a2-it))*xinc2];
						ydvec(it:a2) = [ydisp-(0:(a2-it))*yinc2];
					end
				end
				done=1;
			end
		
		
		x=x+xdvec;
		y=y+ydvec;	

		if(fastopt)
			ind=find( (xdvec+ydvec)~= 0 );
			xmoved=x(ind);
			ymoved=y(ind);
		end
				
		else % group drag for non-polygons
		
			%determine the indicies of the anchors
			ia=[];
			for k=1:nanchors
				ind=find( x == line_anchors(2*k-1) );
				ii = find( y(ind) == line_anchors(2*k) );
				ia=[ia ind(ii)];
			end
			
			%determine if we are between anchors or off the end
			
			offend=0; offbeg=0;
			[iasort,ias]=sort(ia); % sort the anchors based on index
			if( it< iasort(1) ) offbeg=1; 
			elseif( it> iasort(nanchors) ) offend=1;
			end
			
			% offbeg... we are before the first anchor
			if( offbeg )
				numshifted = ia(ias(1))-1;
				
				% compute the x displacement
				xdvec = xdisp*ones(1,numshifted);% constant shift vector
				ydvec = ydisp*ones(1,numshifted);% constant shift vector
				if(~dragmode) %modify for elastic drag
					xincdisp=xdisp/(ia(ias(1))-it);
					ind=it+1:ia(ias(1))-1;% find the points to receive ramped displacement
					xdvec(ind) = xdvec(ind) - (1:length(ind))*xincdisp;
					%compute the y displacement
					yincdisp=ydisp/(ia(ias(1))-it);
					ydvec(ind) = ydvec(ind) - (1:length(ind))*yincdisp;
				end
				
				x= [x(1:numshifted)+xdvec x(ia(ias(1)):npts)];
				y= [y(1:numshifted)+ydvec y(ia(ias(1)):npts)];

				if(fastopt)
					xold=get(hline,'xdata');
					yold=get(hline,'ydata');
					xdvec=x-xold;
					ydvec=y-yold;

					ind=find( (xdvec+ydvec)~= 0 );
					xmoved=x(ind);
					ymoved=y(ind);
				end

			elseif( offend ) % we are after the last anchor
				numshifted = npts-ia(ias(nanchors));
				
				
				xdvec = zeros(1,npts); % start with zero
				ydvec = zeros(1,npts); % start with zero
				if( dragmode)
					xdvec(ia(ias(nanchors))+1:npts)=xdisp*...
						ones(size(ia(ias(nanchors))+1:npts));
					ydvec(ia(ias(nanchors))+1:npts)=ydisp*...
						ones(size(ia(ias(nanchors))+1:npts));
				else
					% compute the x displacement
					xincdisp=xdisp/(it-ia(ias(nanchors)));
					xdvec(ia(ias(nanchors))+1:it)=(1:it-ia(ias(nanchors)))*xincdisp;
					xdvec(it+1:npts)=xdisp*ones(1,length(it+1:npts));
					%compute the y displacement
					yincdisp=ydisp/(it-ia(ias(nanchors)));
					ydvec(ia(ias(nanchors))+1:it)=(1:it-ia(ias(nanchors)))*yincdisp;
					ydvec(it+1:npts)=ydisp*ones(1,length(it+1:npts));
				end
				
				x=x+xdvec;
				y=y+ydvec;

				if(fastopt)
					ind=find( (xdvec+ydvec)~= 0 );
					xmoved=x(ind);
					ymoved=y(ind);
				end
				
			else % we are between anchors
				% determine which 2 anchors
				ind=surround(iasort,it);
				ia1=iasort(ind);
				ia2=iasort(ind+1);
				
				
				xdvec = zeros(1,npts); % start with zero
				ydvec = zeros(1,npts); % start with zero
				if( dragmode )%constant displacement
					xdvec(ia1+1:ia2-1)=xdisp*ones(size(ia1+1:ia2-1));
					ydvec(ia1+1:ia2-1)=ydisp*ones(size(ia1+1:ia2-1));
				else
				% compute the x displacement
					xinc1=xdisp/(it-ia1);
					xinc2=xdisp/(ia2-it);
					xdvec(ia1+1:ia2-1) = [(1:it-ia1)*xinc1 xdisp-(1:ia2-it-1)*xinc2];
				% compute the y displacement
					yinc1=ydisp/(it-ia1);
					yinc2=ydisp/(ia2-it);
					ydvec(ia1+1:ia2-1) = [(1:it-ia1)*yinc1 ydisp-(1:ia2-it-1)*yinc2];
				end
				
				x=x+xdvec;
				y=y+ydvec;

				if(fastopt)
					ind=find( (xdvec+ydvec)~= 0 );
					xmoved=x(ind);
					ymoved=y(ind);
				end
				
			end
		end
	end
				

	% check for occurance of multiple nans in a row or at the beginning &/or end of
	% the line

	singnan=stuff(3,2);
	if(singnan)
		[x2,ikeep]=nanclear(x);
	else
		x2=x;
		ikeep=1:length(x);
	end

	if( length(x2)<npts )

		if(~strcmp(action,'button2motion'))
			xit=x(it);
			yit=y(it);
			npts=length(x2);
			x=x2;
			y=y(ikeep);

			% if we changed the number of points then change 'it' as well
			lit=stuff(1,1);
			for k=1:lit
				ind=find( x==xit(k) );
				i2=find( y(ind)==yit(k) );

				it(k)=ind(i2);
			end

			stuff(1,2:lit+1)=it;

			set(gca,'userdata',stuff);
		else
			npts=length(x2);
			x=x2;
			y=y(ikeep);
		end

	end

if( fastopt & ~linkmode & ~strcmp(action,'button2motion') )			
		set(hline2,'xdata',xmoved,'ydata',ymoved);
		set(hline2,'userdata',[x;y]);
	else
		set(hline,'xdata',x,'ydata',y);
		if( ispoly )
			set(hline2,'xdata',x(2:npts),'ydata',y(2:npts));
		else
			set(hline2,'xdata',x,'ydata',y);
		end
	end

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -