我们热爱生命科学!-生物行

[图文] 过山车模拟器

时间:2006-01-11 16:17来源:Internet 作者:bioguider 点击: 531次

我玩了几天"RollerCoaster Tycoon"(过山车大亨),它那精美的过山车造型真是令人着迷。想不想自己动手写一个过山车模拟器?下面就是我的尝试。

程序中输入一个设计好的轨道抽象数据,产生一条细致光滑的三维视角的轨道(段与段之间是互切的)。借助这个小程序,你可以尝试逐步的完成新的轨道设计。

过山车轨道的生成程序 RollerCoaster2.m

function [d,s]=drawRollerCoaster(path,step)
%-1  /2  \3  R4  L5
%path 中的1表示直道,2表示提升,3表示降低,4表示右转,5表示左转
%step 是每一步移动的距离
%d是详细的轨迹、s是各段的端点
error=0;
way=zeros(1,length(path)+2);
way(1)=1; way(2:length(path)+1)=path; way(length(path)+2)=1;
slice=10;
turn=[0 1; -1 0];
img=[ 1 0; 0 -1];
t=flat2up(step,slice);
t2=[t(1:2,:); t(slice)-[t(3,slice-1:-1:1),0]];
v=turnright(step,slice);
v2=[(v(1:2,:)'*img)';v(3,:)];
dir=0;
h=zeros(3,1000);h(1,1)=0; h(2,1)=0; h(3,1)=0; ch=2;
j=zeros(3,100); j(:,1)=h(1); cj=2;
for i=2:length(way)-1
   switch way(i)
   case 1,
      switch way(i-1)
      case {1,4,5}
         h(1,ch)=step*cos(dir*pi/2)+h(1,ch-1);
         h(2,ch)=step*sin(dir*pi/2)+h(2,ch-1);
         h(3,ch)=h(3,ch-1);
         ch=ch+1;
         j(:,cj)=h(:,ch-1); cj=cj+1;
      case 2,
         h(:,ch:ch+slice-1)=[(t2(1:2,:)'*(turn^dir))';t2(3,:)]+h(:,ch-1)*ones(1,slice);
         ch=ch+slice;
         j(:,cj)=h(:,ch-1); cj=cj+1;
      case 3,
         h(:,ch:ch+slice-1)=[(t2(1:2,:)'*(turn^dir))';-t2(3,:)]+h(:,ch-1)*ones(1,slice);
         ch=ch+slice;
         j(:,cj)=h(:,ch-1); cj=cj+1;
		end;         
   case 2,
      switch way(i-1)
      case {1,4,5}
         h(:,ch:ch+slice-1)=[(t(1:2,:)'*(turn^dir))';t(3,:)]+h(:,ch-1)*ones(1,slice);
         ch=ch+slice;
         j(:,cj)=h(:,ch-1); cj=cj+1;
      case 2,
         h(1,ch)=step*cos(dir*pi/2)+h(1,ch-1);
         h(2,ch)=step*sin(dir*pi/2)+h(2,ch-1);
         h(3,ch)=step+h(3,ch-1);
         ch=ch+1;
         j(:,cj)=h(:,ch-1); cj=cj+1;
      otherwise,
         errin(i); error=1;
      end;
   case 3,
      switch way(i-1)
      case {1,4,5}
         h(:,ch:ch+slice-1)=[(t(1:2,:)'*(turn^dir))';-t(3,:)]+h(:,ch-1)*ones(1,slice);
         ch=ch+slice;
         j(:,cj)=h(:,ch-1); cj=cj+1;
      case 3,
         h(1,ch)=step*cos(dir*pi/2)+h(1,ch-1);
         h(2,ch)=step*sin(dir*pi/2)+h(2,ch-1);
         h(3,ch)=-step+h(3,ch-1);
         ch=ch+1;
         j(:,cj)=h(:,ch-1); cj=cj+1;
      otherwise,
         errin(i); error=1;
      end;
   case 4,
      switch way(i-1)
      case {1,4,5},
         h(:,ch:ch+slice-1)=[(v(1:2,:)'*(turn^dir))';v(3,:)]+h(:,ch-1)*ones(1,slice);
         ch=ch+slice;
         dir=dir+1;
         j(:,cj)=h(:,ch-1); cj=cj+1;
      otherwise,
         errin(i); error=1;
      end;
   case 5,
      switch way(i-1)
      case {1,4,5},
         h(:,ch:ch+slice-1)=[(v2(1:2,:)'*(turn^dir))';v2(3,:)]+h(:,ch-1)*ones(1,slice);
         ch=ch+slice;
         dir=dir-1;
         j(:,cj)=h(:,ch-1); cj=cj+1;
      otherwise,
         errin(i); error=1;
      end;
   end;
end;
d=h(:,1:ch-1);
s=j(:,1:cj-1);
function flatup=flat2up(step,slice)
Radius=step/cos(pi/8)/2/sin(pi/8);
flatup=zeros(3,slice); c=1;
for alpha=0+pi/4/slice:pi/4/slice:pi/4
   l=Radius*sin(alpha/2)*2;
   flatup(1,c)=l*cos(alpha/2);
   flatup(2,c)=0;
   flatup(3,c)=l*sin(alpha/2);
   c=c+1;
end;         
function tr=turnright(step,slice)
c=1;
for alpha=-pi/2+pi/2/slice:pi/2/slice:0
   tr(1,c)=step*cos(alpha);
   tr(2,c)=step*sin(alpha)+step;
   tr(3,c)=0;
   c=c+1;
end;
function errin(number)      
disp(['Error in sequence at ',int2str(number),'\n'])

主程序

w=[1,1,1,2,2,1,3,3,1,4,4,5,1,2,2,2,1,5,5,1,1,1,5,2,2,1,3,3,3,1,5,4,1,2,1,3,1,4,1,1,1,1,4,3,3,1,1];
[d,e]=RollerCoaster2(w,10);
hold off;
plot3(d(1,:),d(2,:),d(3,:));
hold on;
plot3([e(1,:);e(1,:)],[e(2,:);e(2,:)],[e(3,:);zeros(1,size(e,2))],'r');
axis equal
grid on
xlabel('x');
ylabel('y');
zlabel('z');
p = plot3(0,0,0,'square', ...
'EraseMode','xor','MarkerSize',5,'MarkerFaceColor',[1,0.7,0.7])
for i=2:size(e,2)
   set(p,'XData',e(1,i),'YData',e(2,i),'ZData',e(3,i))
   pause;
   drawnow
end
axis equal
grid on
xlabel('x');
ylabel('y');
zlabel('z');
hold off;

如图所示,蓝线表示轨道,红线表示支柱,一个小方块随着键盘的按键在轨道上移动。你可以任意改变视角来观察方块的运动。

很明显,这个程序还很粗糙,但很快你就可以在这里看到它的新版本了。可能增添的特性有:轨道由线升级到面,支柱变成圆柱,在线的修改轨道,自动闭合轨道。

(责任编辑:泉水)
顶一下
(19)
95%
踩一下
(1)
5%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片