新しく発言する EXIT インデックスへ
点と壁の反応

  点と壁の反応 たかし 2005/10/02 16:02:58 
  rem**点と壁の初期3 たかし 2005/10/02 16:12:31 
   └「点と壁の初期3」のつづき たかし 2005/10/02 16:13:37 
    ├いろいろ思うところあるけど(なぜfor文はn-... 青木太一 2005/10/03 07:29:28 
    ├何を計算するか考えよう! 山中和義 2005/10/03 09:36:16 
    ├ローカル座標とワールド座標 山中和義 2005/10/03 10:06:59 
    └助言をいただいてここまでしました。 たかし 2005/10/04 22:22:43 
     ├偶数、奇数番号で縦、横壁を作る 山中和義 2005/10/05 07:26:10 
     └私はなぜvxやvyの0.01との大小関係でif文を... 青木太一 2005/10/05 08:53:32 
      └まずif・・・andvx(i)<0.01andvy(i)<... たかし 2005/10/07 20:13:48 
       └>まずif・・・andvx(i)<0.01andvy(i)&l... 青木太一 2005/10/09 19:01:08 
        └返事がかなり遅れてしまいました。 たかし 2005/10/20 23:25:31 

  点と壁の反応 たかし 2005/10/02 16:02:58  ツリーへ

点と壁の反応 返事を書く
たかし 2005/10/02 16:02:58
「点と壁の初期3」のプログラムの「 !点と壁の当たり判定!!!!!!!相対速度?を使う!!!!!!!」をみてもらいたい.
@壁の速度(x(i))が点の速度(0.01)より大きい時は、
LET vx(0)=x(i)-vx(0)
LET vy(0)=y(i)-vy(0) (壁1、壁2とも)
としたのだが問題はあるか
A壁の速度が点の速度より小さいときは、
let vx(0)=vx(0)-x(i)
let vy(0)=vy(0)-y(i) (壁1、壁2とも)
としたのだが問題はあるか
B壁2と点との反応が見られないのだが、どこをどうすれば「跳ね返る」ようになるのか
(なお、壁1は縦に長い壁、壁2は横に細長い壁である)

  rem**点と壁の初期3 たかし 2005/10/02 16:12:31  ツリーへ

Re: 点と壁の反応 返事を書く
たかし 2005/10/02 16:12:31
rem ** 点と壁の初期3
randomize
set window 0,1,0,1
LET n=20
dim x(0 to n),y(0 to n) !壁の位置
dim vx(0 to n),vy(0 to n)!壁(速度,velocity)と点が進む?
!初期値設定
for i=1 to n
LET x(i)=rnd
LET y(i)=rnd
LET vx(i)=(rnd-0.5)/50
LET vy(i)=(rnd-0.5)/50
next i
let x(0)=0 !点の位置
 let y(0)=0



   └「点と壁の初期3」のつづき たかし 2005/10/02 16:13:37  ツリーへ

Re: rem**点と壁の初期3 返事を書く
たかし 2005/10/02 16:13:37
「点と壁の初期3」のつづき
!!!!!!!!メインループ開始!!!!!!!
DO
 let vx(0)=0 !点の速度キーが押されてないとき
let vy(0)=0
! キー操作の設定
WAIT DELAY 0.01 ! 0.01秒待機する
IF GetKeyState(27)<0 THEN EXIT DO ! ESCを押すと終了
IF GetKeyState(37)<0 THEN LET vx(0)=-0.01
IF GetKeyState(38)<0 THEN LET vy(0)=+0.01
IF GetKeyState(39)<0 THEN LET vx(0)=+0.01
IF GetKeyState(40)<0 THEN LET vy(0)=-0.01
!点と壁の当たり判定 !!!!!!!相対速度?を使う!!!!!!!
FOR i=1 TO n-1
LET xx=ABS(x(i)-x(0))
LET yy=ABS(y(i)-y(0))
IF xx<0.025 AND yy<0.2 and x(i)>0.01 and y(i)>0.01 THEN !縦壁の幅,高さ !!!!!!壁1との判定!!!!!!
LET vx(0)=x(i)-vx(0)
LET vy(0)=y(i)-vy(0)
EXIT FOR !ひとつ見つかれば十分!
END IF
IF xx<0.025 AND yy<0.2 and x(i)<0.01 and y(i)<0.01 then
let vx(0)=vx(0)-x(i)
let vy(0)=vy(0)-y(i)
EXIT FOR !ひとつ見つかれば十分!
end if
LET xx=ABS(x(i)-x(0))
LET yy=ABS(y(i)-y(0))
IF xx<0.1 and yy<0 and x(i)>0.01 and y(i)>0.01 then
LET vx(0)=x(i)-vx(0) !!!!!!!壁2との判定!!!!!!
LET vy(0)=y(i)-vy(0)
EXIT FOR !ひとつ見つかれば十分!
end if
IF xx<0.1 and yy<0 and x(i)<0.01 and y(i)<0.01 then
let vx(0)=vx(0)-x(i)
let vy(0)=vy(0)-y(i)
EXIT FOR !ひとつ見つかれば十分!
end if
NEXT i
!点と壁が外壁にぶつかったら反射する
for i=0 to n
IF x(i)<0 THEN !外壁にぶつかったら、
LET x(i)=0 !端に位置付ける
LET vx(i)=+0.009 !反射する
END IF!反射を調節する(点が反射したときに消えることがあるが)!
IF 1<x(i) THEN
LET x(i)=0.95
let vx(i)=-0.009
END IF
IF y(i)<0 THEN
LET y(i)=0
LET vy(i)=-vy(i)
END IF
IF 1<y(i) THEN
LET y(i)=0.95
LET vy(i)=-0.009
END IF
NEXT i
!点と壁を速度によって位置を進める
for i=0 to n
LET x(i)=x(i)+vx(i)
LET y(i)=y(i)+vy(i)
next i
!壁を描く
for i=1 to n
draw kabe1 WITH SHIFT (x(i),y(i))
draw kabe2 with shift (x(i)* i/10 ,y(i)* i/10 )!!!!(kabe2のy座標のy(i)>1の反応がいまいちだが)
next i
!点を描いて動かす
DRAW tenn WITH SHIFT(x(0),y(0))
!ちらつき防止
set draw mode explicit
set draw mode hidden
clear
draw grid(0.1,0.1)
LOOP
END
external picture tenn
set area color 3
plot area : 0.01,0.05;0.04,0.05;0.04,0.02;0.01,0.02
end picture
external picture kabe1
set area color 1
plot area:0.025,0.2;-0.025,0.2;-0.025,-0.2;0.025,-0.2
END picture
external picture kabe2
set area color 1
plot area:-0.3,0;-0.3,-0.015;0.1,-0.015;0.1,0
END picture

    ├いろいろ思うところあるけど(なぜfor文はn-... 青木太一 2005/10/03 07:29:28  ツリーへ

Re: 「点と壁の初期3」のつづき 返事を書く
青木太一 2005/10/03 07:29:28
いろいろ思うところあるけど(なぜfor文はn-1までなのか、なぜ「IF y(i)<0 THEN」のときだけ「LET vy(i)=-vy(i)」なのか?(0.009でなく)時間がないので簡単なところだけ

>B壁2と点との反応が見られないのだが、どこをどうすれば「跳ね返る」ようになるのか
>(なお、壁1は縦に長い壁、壁2は横に細長い壁である)

壁2はどこに描いているかというと
>draw kabe2 with shift (x(i)* i/10 ,y(i)* i/10 )!!!!(kabe2のy座標のy(i)>1の反応がいまいちだが)
x=「x(i)* i/10」y=「y(i)* i/10」
の位置に描いていますよね。
でも衝突判定のところでは、その位置でなくx(i),y(i)で衝突判定していませんか?

衝突判定の位置と描く位置を合わせなくてはいけません。

間違ってたらごめんなさい。お役にたてたら幸いです。

    ├何を計算するか考えよう! 山中和義 2005/10/03 09:36:16  ツリーへ

Re: 「点と壁の初期3」のつづき 返事を書く
山中和義 2005/10/03 09:36:16
何を計算するか考えよう!
@、Aの式
 LET vx(0)=x(i)-vx(0)
 LET vy(0)=y(i)-vy(0) (壁1、壁2とも)
は、何を計算するものなのか?

vx()は速度、x()は位置(距離)だから、まったく別のものを組み合せている。
距離、速度、時間は、いわゆる単位が揃っていない!


●参考
元のプログラムの
 LET x(i)=x(i)+vx(i) !点、壁を速度によって位置を進める
 LET y(i)=y(i)+vy(i)
は、単位時間あたりの位置を算出している。
vx()に1(ミリ秒?)をかけて、位置(距離)にしている。

    ├ローカル座標とワールド座標 山中和義 2005/10/03 10:06:59  ツリーへ

Re: 「点と壁の初期3」のつづき 返事を書く
山中和義 2005/10/03 10:06:59
ローカル座標とワールド座標
この考え方は、「配置」するときに重要です。
「配置」は、大きさ、向き、位置の3要素あり、2D、3Dともに共通です。

描画は、
 配置するものを、ローカル座標で作成しておき、
 その原点をつまんで、ワールド座標に置きます。

【ポイント】
ものの中心がローカル座標の原点!
拡大・縮小、回転の変換は、原点が基準!


実際のプログラムで確認すると、、、

元のプログラムでは、点は
まず、ローカル座標で
 EXTERNAL PICTURE tenn
 SET AREA COLOR 3
 PLOT AREA : 0.015,0.015;-0.015,0.015;-0.015,-0.015;0.015,-0.015
 END PICTURE
と描き、
ワールド座標の点(x(0),y(0))に
 DRAW tenn WITH SHIFT(x(0),y(0)) !点を描く
と置く。 ※原点→(x(0),y(0)))の平行移動になる。


考察のプログラムでは、
 external picture tenn
 set area color 3
 plot area : 0.01,0.05;0.04,0.05;0.04,0.02;0.01,0.02
 end picture

としているため、ずれていることになる。(点の中心は(0.025,0.035))

    └助言をいただいてここまでしました。 たかし 2005/10/04 22:22:43  ツリーへ

Re: 「点と壁の初期3」のつづき 返事を書く
たかし 2005/10/04 22:22:43
助言をいただいてここまでしました。
________________________________________________________
!点と壁の当たり判定 !!!!!!!相対速度?を使う!!!!!!!
FOR i=1 TO n-1
LET xx=ABS(x(i)-x(0))
LET yy=ABS(y(i)-y(0))
IF xx<0.025 AND yy<0.2 and vx(i)>0.01 and vy(i)>0.01 THEN !縦壁の幅,高さ!!壁1との判定!!
LET vx(0)=vx(i)-vx(0)!!相対速度の概念の導入!! LET vy(0)=vy(i)-vy(0)
EXIT FOR !ひとつ見つかれば十分!
END IF
IF xx<0.025 AND yy<0.2 and vx(i)<0.01 and vy(i)<0.01 then
let vx(0)=vx(0)-vx(i)
let vy(0)=vy(0)-vy(i)
EXIT FOR !ひとつ見つかれば十分!
end if
IF xx<0.1 and yy<0 and vx(i)>0.01 and vy(i)>0.01 then
LET vx(0)=vx(i)*i/10-vx(0) !!!!!!壁2との判定!!!!!!
LET vy(0)=vy(i)*i/10-vy(0)
EXIT FOR !ひとつ見つかれば十分!
end if
IF xx<0.1 and yy<0 and vx(i)<0.01 and vy(i)<0.01 then
let vx(0)=vx(0)-vx(i)* i/10
let vy(0)=vy(0)-vy(i)* i/10
EXIT FOR !ひとつ見つかれば十分!
end if
NEXT i
--------------------------------------------------------- がしかし,まだ点と壁2が反応しません。どこがだめなのですか。

     ├偶数、奇数番号で縦、横壁を作る 山中和義 2005/10/05 07:26:10  ツリーへ

Re: 助言をいただいてここまでしました。 返事を書く
山中和義 2005/10/05 07:26:10
偶数、奇数番号で縦、横壁を作る

REM ** 点と壁

RANDOMIZE
SET WINDOW 0,1,0,1
LET n=10
DIM x(0 TO n),y(0 TO n) !点、壁の位置
DIM vx(0 TO n),vy(0 TO n) !点、壁の速度(velocity)

!初期値設定
LET x(0)=0 !点の位置
LET y(0)=0

FOR i=1 TO n !壁の位置、速度
LET x(i)=RND
LET y(i)=RND
LET vx(i)=(rnd-0.5)/50
LET vy(i)=(rnd-0.5)/50
NEXT i

LET x(n)=0.9
LET y(n)=0.9


!メインループ開始
LET t=time
DO

LET vx(0)=0 !点の速度(キーが押されてない)
LET vy(0)=0

! キー操作の設定
WAIT DELAY 0.101 ! 0.01秒待機する
IF GetKeyState(27)<0 THEN EXIT DO ! ESCを押すと終了
IF GetKeyState(37)<0 THEN LET vx(0)=-0.05
IF GetKeyState(38)<0 THEN LET vy(0)=0.05
IF GetKeyState(39)<0 THEN LET vx(0)=0.05
IF GetKeyState(40)<0 THEN LET vy(0)=-0.05

!点と壁との当り判定
FOR i=n TO 1 STEP -1
LET xx=ABS(x(i)-x(0))
LET yy=ABS(y(i)-y(0))
IF MOD(i,2)=0 THEN !偶数番号なら
LET wd=0.025 !縦壁の幅、高さ
LET ht=0.2
ELSE
LET wd=0.1
LET ht=0.025
END IF
IF xx<wd AND yy<ht THEN !衝突したら
IF i=n THEN EXIT DO !青い壁なら、終了!
LET vx(0)=0 !停止させる
LET vy(0)=0
EXIT FOR !ひとつ見つかれば十分!
END IF
NEXT i

!点、壁について
FOR i=0 TO n
LET x(i)=x(i)+vx(i) !点、壁を速度によって位置を進める
LET y(i)=y(i)+vy(i)

IF x(i)<0 THEN !外壁にぶつかったら、
LET x(i)=0 !端に位置付ける
LET vx(i)=-vx(i) !反射する
END IF
IF 1<x(i) THEN
LET x(i)=1
LET vx(i)=-vx(i)
END IF
IF y(i)<0 THEN
LET y(i)=0
LET vy(i)=-vy(i)
END IF
IF 1<y(i) THEN
LET y(i)=1
LET vy(i)=-vy(i)
END IF
NEXT i

!ちらつき防止(開始)
SET DRAW mode hidden
CLEAR

DRAW grid(0.1,0.1)

!壁を描く
SET AREA COLOR 1
FOR i=1 TO n-1
IF MOD(i,2)=0 THEN !偶数番号なら
DRAW kabe WITH SHIFT (x(i),y(i)) !縦
ELSE
DRAW kabe2 WITH SHIFT (x(i),y(i)) !横
END IF
NEXT i
SET AREA COLOR 2
IF MOD(i,2)=0 THEN
DRAW kabe WITH SHIFT (x(n),y(n))
ELSE
DRAW kabe2 WITH SHIFT (x(n),y(n))
END IF

!点を描く
DRAW tenn WITH SHIFT(x(0),y(0))

set text color 4
plot text ,at 0,0:"経過時間"&str$(time-t)&"秒"

!ちらつき防止(終了)
SET DRAW mode explicit
LOOP

END

EXTERNAL PICTURE tenn
SET AREA COLOR 3
PLOT AREA : 0.015,0.015;-0.015,0.015;-0.015,-0.015;0.015,-0.015
END PICTURE

EXTERNAL PICTURE kabe
PLOT AREA: 0.025,0.2;-0.025,0.2;-0.025,-0.2;0.025,-0.2
END PICTURE

EXTERNAL PICTURE kabe2
PLOT AREA: 0.1,0.025;0.1,-0.025;-0.1,-0.025;-0.1,0.025
END PICTURE

     └私はなぜvxやvyの0.01との大小関係でif文を... 青木太一 2005/10/05 08:53:32  ツリーへ

Re: 助言をいただいてここまでしました。 返事を書く
青木太一 2005/10/05 08:53:32
私はなぜvxやvyの0.01との大小関係でif文を使っているのかわからないので、(あと、 let vx(0)=vx(0)-vx(i)がなにをやろうとしているのかもわからない)なんともいえませんが
まず、描いている位置はx(i)* i/10 ,y(i)* i/10であって、速度vx,vyは関係ないでしょう。
i/10をかけるべきなのは衝突位置判定の
> LET xx=ABS(x(i)-x(0))
> LET yy=ABS(y(i)-y(0))
のほうです。(kabeとkabe2でxx,yyを使い分けなければいけません)

      └まずif・・・andvx(i)<0.01andvy(i)<... たかし 2005/10/07 20:13:48  ツリーへ

Re: 私はなぜvxやvyの0.01との大小関係でif文を... 返事を書く
たかし 2005/10/07 20:13:48
まず  if・・・ and vx(i)<0.01 and vy(i)<0.01 then
     let vx(0)=vx(0)-vx(i)
let vy(0)=vy(0)-vy(i)
ですが、これはvx(i)とvy(i)の値が0.01(点の速度?)よりも小さい場合vx(0)とvy(0)の値をvx(0)-vx(i)とvy(0)-vy(i)にしろ という趣旨の文。
次に  if・・・ and vx(i)>0.01 and vy(i)>0.01 then
LET vx(0)=vx(i)-vx(0)
LET vy(0)=vy(i)-vy(0)
ですが、これは vx(i)とvy(i)の値が0.01(点の速度?)よりも大きい
場合vx(0)とvy(0)の値をvx(i)-vx(0)とvy(i)-vy(0)にしろという文です。
●i/10をかけるべきなのは衝突位置判定の
> LET xx=ABS(x(i)-x(0))
> LET yy=ABS(y(i)-y(0))
のほうです。(kabeとkabe2でxx,yyを使い分けなければいけません
により !!!壁2との判定!の部分を
FOR i=1 TO n-1
LET xxx=ABS(x(i)*i/10 -x(0))
LET yyy=ABS(y(i)*i/10 -y(0))
IF xxx<0.1 and yyy<0 and vx(i)>0.01 and vy(i)>0.01 then
LET vx(0)=vx(i)-vx(0)
LET vy(0)=vy(i)-vy(0)
EXIT FOR !ひとつ見つかれば十分!
end if
IF xxx<0.1 and yyy<0 and vx(i)<0.01 and vy(i)<0.01 then
let vx(0)=vx(0)-vx(i)
let vy(0)=vy(0)-vy(i)
EXIT FOR !ひとつ見つかれば十分!
end if
NEXT i
としたのですがまだ点と壁2が反応しません。

       └>まずif・・・andvx(i)<0.01andvy(i)&l... 青木太一 2005/10/09 19:01:08  ツリーへ

Re: まずif・・・andvx(i)<0.01andvy(i)<... 返事を書く
青木太一 2005/10/09 19:01:08
>まず  if・・・ and vx(i)<0.01 and vy(i)<0.01 >then
>let vx(0)=vx(0)-vx(i)
>let vy(0)=vy(0)-vy(i)
>ですが、これはvx(i)とvy(i)の値が0.01(点の速度?)よりも小さい場合vx(0)とvy(0)の値を
>vx(0)-vx(i)とvy(0)-vy(i)にしろ という趣旨の文。
>次に  if・・・ and vx(i)>0.01 and vy(i)>0.01 >then
>LET vx(0)=vx(i)-vx(0)
>LET vy(0)=vy(i)-vy(0)
>ですが、これは vx(i)とvy(i)の値が0.01(点の速度?)よりも大きい
>場合vx(0)とvy(0)の値をvx(i)-vx(0)とvy(i)-vy(0)にしろという文です。

えー、それはまあプログラムそのままですので理解できます。
理解できないのは大きく2点。それぞれに小さい疑問がたくさんあります。
・なぜvx(i),vy(i)が「共に」0.01より大きいとか小さいかを判定しているのか? たとえばvx(i)>0.01 and vy(i)<0.01の場合処理しないのはなぜか
点の速度の絶対値は0.01でも、方向によってはそれぞれの軸で負の値をとることもあるが、なぜ正の値でのみ比較しているのか。そもそもなぜ点の速度との大小関係を比較するのか?
・vx(0),vy(0)をなぜあのように処理するのか?
 壁にあたったら、相対速度に応じて跳ね返るような挙動をさせたいのですか?
 だとしたら、GetKeyStateによって強制的にvx(0),vy(0)を設定しているところとの兼ね合いを考えないといけません。

壁2と反応しない理由は、すくなくとも見て気づいたのは
> IF xxx<0.1 and yyy<0 and vx(i)>0.01 and vy(i)>0.01 then
のyyy<0の条件です。(ABS関数でくくっているのだから)距離が0より小さくなることはないので、このIF文の条件が満たされることはありません。
なぜ壁1と同じように、壁の大きさをいれないのですか?(壁2の高さは0なのですか?)

時間がないので、きちんとプログラムを見回っていないため、適切な回答になってないかもしれません。
役に立たなかったらごめんなさい。

なにはともあれ、山中さんの書かれたプログラムでいいと思いますので、あちらも参考にしてはいかがでしょう?

        └返事がかなり遅れてしまいました。 たかし 2005/10/20 23:25:31  ツリーへ

Re: >まずif・・・andvx(i)<0.01andvy(i)&l... 返事を書く
たかし 2005/10/20 23:25:31
返事がかなり遅れてしまいました。
今何とかそれなりに作っています。
ご協力ありがとうこざいました。


インデックスへ EXIT
新規発言を反映させるにはブラウザの更新ボタンを押してください。