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
|