More ... | HSPコンテスト:ショートプログラム:数学・物理編:移動
中学校か高校か、忘れましたが、内分点の公式があります。それを利用した移動ルーチンを書いてみたいと思います。 まず、内分点の公式を思い出しましょう。 (x1,y1) (x2,y2)の二点が存在するとき、その二つの点をα:βに内分する点(x3,y3)は次のようにして求まります。
α+β=τとして、β=τ-αとすると、
となります。ここで、αを0からτまで変化させると、α=0のときx3=x2 α=τのとき,x3=x1となり、x2からx1へとx3が移動することがわかります。またτは移動にかかる時間なので、この値を調整することによって、特定の座標への移動が簡単に出来るようになります。以上のことを踏まえたスクリプトを書いてみました。(p1からp2への移動になってますがあまり気にしないでください) randomize repeat p1x=p2x p1y=p2y rnd p2x,640 rnd p2y,480 repeat 0xFF redraw 0 color 255,255,255 boxf 0,0,640,480 px=((p2x*cnt)+(p1x*(0xFF-cnt))) /0xFF py=((p2y*cnt)+(p1y*(0xFF-cnt))) /0xFF pos p2x,p2y color 255,0,0 mes "●" color 0,0,0 pos px,py mes "●" redraw 1 await 16 loop loop また以下にその技術を用いて、筆者が去年のHSPプログラミングコンテストに出したもののスクリプトを張っておきます。いまさらながら、sprocket氏( http://sprocket.babyblue.jp/ )の三角関数テーブル作成ルーチンを使わせていただいたことにお礼を申し上げます。 //---------------------------------------- dim sin,1024 ; テーブル用配列 dim cos,1024 sin.256=1024 repeat 256 r=cnt<<23/166886 ; ラジアンに変換 sin.cnt=r*r>>10*r>>13/3*r>>15*r>>17/5+r-(r*r>>10*r>>17/3)-(r*r>>10*r>>13/3*r>>15*r>>13/5*r>>13/6*r>>17/7) +4>>3 a=512-cnt sin.a=sin.cnt ; 位相をpi/4ずらしてコピー loop repeat 512 ; 位相をpi/2ずらしてコピー a=cnt+512 sin.a=-sin.cnt loop repeat 1024 //sinからCosを算出 a=cnt+768&1023 cos.a=sin.cnt loop //---------------------------------------- s=cmdline:peek c,s,1 ; コマンドラインの2文字目を取り出す if c='c' |(c=0) { //Config dialog "No Configuration.",0,"Mathline." end; } if c='p' :screen 0,,,1:else{ //プレビューかどうか bgscr 2,dispx,dispy,1 } repeat 256 palette cnt,cnt,cnt,cnt loop palfade dim PointLX,1024 dim PointLY,1024 dim PointNX,1024 dim PointNY,1024 //-------------------------初期化ルーチンここまで------------------------- //alpha 次のモデルのアルファ合成値(256単位) // // // CenterX=winx/2 CenterY=winy/2 range=winy-16 randomize repeat alpha=cnt&0xFF; if alpha=0{ memcpy PointLX,PointNX,1024*4 memcpy PointLY,PointNY,1024*4 if next>1{ repeat 60 gosub *drawline loop } last=next *@ rnd t,19; if next==t : goto *@b next=t; gosub *curbeline } gosub *drawline loop //------------------------------------------------------------------- *curbeline rnd rev1,2 rnd rev2,2 repeat 1024 dup PX,PointNX.cnt dup PY,PointNY.cnt theta1=cnt //&1023; theta2=cnt*2 &1023; theta3=cnt*3 &1023; theta4=cnt*4 &1023; theta5=cnt*5 &1023; theta6=cnt*6 &1023; theta12=cnt*12 &1023; //---------------収束系--------- if next=0{ //収束 PX=0; PY=0; } if next=1{ //ランダム発散 rnd PX,0x800 rnd PY,0x800 PX-=0x400 PY-=0x400 if PX*PX+(PY*PY)>0x100000:continue cnt } //-----------------基本三角関数------------- if next=2{ //sin wave PX=theta1-512<<1 PY=sin.theta2 } if next=3{ //CosWave PX=theta1-512<<1 PY=cos.theta2 } if next=4{ //tangent wave PX=theta1-512<<1 if sin.theta3==0 :theta3++; PY=cos.theta3<<6 / sin.theta3 } //---------------直線系------------ if next=5{ //box theta=theta1&0xff<<3-0x400 if theta1<0x100{ //0〜255 PX=theta; PY=-0x400 goto *@f; } if theta1<0x200{ //256-511 PX=0x400 PY=theta goto *@f; } if theta1<0x300{ //512-768 PX=-theta PY=0x400 } else { PX=-0x400 PY=-theta } } if next=6{ //十字 theta=cnt&0b0100000000 PX=cos.theta*cos.theta1>>10; PY=sin.theta*sin.theta1>>10; } //---------------円系--------------- if next=7{ //circle PX=cos.theta1 PY=sin.theta1 } if next=8{ //ぎざぎざ円 r=sin.theta12+1024>>2+512 PX=r*cos.theta1>>10 PY=r*sin.theta1>>10 } if next=9{ //渦巻き PX=theta1*cos.theta12>>10 PY=theta1*sin.theta12>>10 } if next=10{ //多重円 if theta1\0x100==255 : theta4=0 theta=theta1&0b1100000000+0x80 PX=theta *cos.theta4>>10 PY=theta *sin.theta4>>10 } if next=11{ //道路工事中? theta=theta1&0b11111 PX=theta *cos.theta3>>5 PY=theta *sin.theta3>>5 } //------------リサージュ------------- if next=12{ PX=sin.theta5 PY=cos.theta6 } if next=13{ //リサージュ PX=sin.theta6 PY=cos.theta5 } //--------------サイクロイド系----------- if next=14{ //ひし形 PX=cos.theta1 PX=PX*PX*PX>>20 PY=sin.theta1 PY=PY*PY*PY>>20 } if next=15{ //三角形(内サイクロイド) PY=sin.theta1*2+cos.theta2 /3+0x100 PX=cos.theta1*2+sin.theta2 /3 } if next=16{ //外サイクロイド PX=sin.theta1*6+sin.theta6 /7 PY=cos.theta1*6+cos.theta6 /7 } if next=17{ //葉っぱ PX=sin.theta4*cos.theta1>>10 PY=sin.theta4*sin.theta1>>10 } if next=18{ //万華鏡 PX=sin.theta12+sin.theta1/2 PY=cos.theta12+cos.theta1/2 } //------------------------- *@ if rev1:PX=-PX if rev2:PY=-PY loop return *drawline redraw 0 palcolor boxf ColorSride=ColorSride+10&0xFF repeat 1024 palcolor cnt-ColorSride&0xFF NPX =alpha*PointNX.cnt NPX+=256-alpha*PointLX.cnt NPY =alpha*PointNY.cnt NPY+=256-alpha*PointLY.cnt temp=NPX-LPX>>8 Distance =temp*temp temp=NPY-LPY>>8 Distance+=temp*temp DNPX=NPX*range>>19+CenterX DNPY=NPY*range>>19+CenterY DLPX=LPX*range>>19+CenterX DLPY=LPY*range>>19+CenterY if Distance > 10000 { pset DNPX,DNPY } else { line DLPX,DLPY,DNPX,DNPY } LPX=NPX LPY=NPY loop redraw await 16 return |