hinekure.net が http://hspdev-wiki.net/ から自動クローリングした結果を表示しています。画像やリソースなどのリンクが切れています。予めご了承ください。
物理のおおまかな話/跳ねるボールその2 - HSP開発wiki
トップ    編集凍結 差分バックアップ添付複製名前変更リロード   新規一覧単語検索最終更新   最終更新のRSS

跳ねるボールその2

斜面との衝突を計算する

斜面との衝突を計算するにはベクトル演算が便利です。 以下、速度ベクトルをv,斜面の法線ベクトルをnとします。
斜面衝突時、速度ベクトルの斜面に垂直な成分

a math image

で表されます。

BoundBall2.gif

よって跳ね返り係数をe(<0)とすると、

a math image

が衝突後の速度ベクトルとなります。

サンプルコード

Everything is expanded.Everything is shortened.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
-
|
|
|
|
-
|
|
|
|
|
|
!
-
|
|
!
-
|
|
|
|
|
|
|
|
|
|
!
 
 
 
 
 
 
 
 
-
|
-
|
!
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
//  斜面で跳ねるボール for hsp3.1b (2007/03/06)
// ベクトル演算モジュール "math3d.hsp"より抜粋(内積・ベクトル描画)
#module
#defcfunc DotPrd double vecx1, double vecy1, double vecz1, double vecx2, double vecy2, double vecz2
    return vecx1*vecx2 + vecy1*vecy2 + vecz1*vecz2
 
#deffunc DrwArrow int sx, int sy, int ex, int ey
    line sx, sy, ex, ey
 
    x = sx - ex : y = sy - ey
    ax = (x - y)/7 + ex : ay = (y + x)/7 + ey
    line ex, ey, ax, ay
 
    ax = (x + y)/7 + ex : ay = (y - x)/7 + ey
    line ex, ey, ax, ay
return
#global
 
#const BALL_SIZE 6
#define SLOPE_Y   350.0     // 斜面左端のY座標
#define G         0.1       // 重力
#define HANEKAERI -0.8      // 跳ね返り係数
 
    title "斜面での反射"
    WINX = ginfo_winx
    WINY = ginfo_winy
 
    SlopeTheta = 0.0        // 斜面の傾き
    SlopeVectX = 0.0        // 斜面の法線ベクトル
    SlopeVectY = 1.0
 
    Moving = 0              // 運動中のフラグ
    BallX = 0.0             // ボールの位置
    BallY = SLOPE_Y
 
*Main
    redraw 0
    gosub *Inkey
    gosub *Ball
    gosub *Draw
    redraw 1
    await 6
    goto *Main
 
*Inkey
    stick key
    if key & 128 : end
    if key & 256 : Moving ^= 1
    return
 
*Ball
    if Moving {
        // ボールが運動中
        vy += G
        BallX += vx : BallY += vy
 
        if BallY > (SLOPE_Y - tan(SlopeTheta)*BallX) {
            // 斜面に衝突。今回のポイント!
            BallY = SLOPE_Y - tan(SlopeTheta)*BallX         // 正確ではない
            Naiseki = DotPrd(vx, vy, 0.0, SlopeVectX, SlopeVectY, 0.0)
            tmp = vy
            vx += Naiseki * SlopeVectX * (HANEKAERI - 1)
            vy += Naiseki * SlopeVectY * (HANEKAERI - 1) + G
        }
        if (BallX < 0)|(WINX < BallX)|(BallY < 0)|(WINY < BallY) {
            // 画面外に出た時
            Moving = 0
        }
    } else {
        // ボールが停止中
        BallX = 0.0 : BallY = SLOPE_Y
 
        SlopeTheta += 0.1*(mousew/120 + (key>>1&1) - (key>>3&1))
        SlopeVectX = sin(SlopeTheta)
        SlopeVectY = cos(SlopeTheta)
 
        Theta = atan(mousey - BallY, mousex - BallX)        // 射出する角度を決定
        Speed = sqrt(mousex*mousex + (SLOPE_Y - mousey)*(SLOPE_Y - mousey))/30
        vx = cos(theta) * Speed : vy = sin(theta) * Speed
    }
    return
 
*Draw
    color 255, 255, 255 : boxf
 
    color : pos 0, 0
    mes "座標( " + BallX + ", " + BallY + " )"
    mes "速度 v = ( " + vx + ", " + vy + " )"
    if Moving {
        mes "画面クリックで中止"
    } else {
        mes "画面クリックでスタート\nホイールまたは↑・↓で斜面角度変更"
    }
 
    color 192, 192, 192     // 座標系
    DrwArrow WINX - 80, WINY - 20, WINX - 80, WINY - 80
    DrwArrow WINX - 80, WINY - 20, WINX - 20, WINY - 20
    pos WINX - 35, WINY - 40 : mes "X"
    pos WINX - 70, WINY - 80 : mes "Y"
 
    color                   // 斜面・ボール
    line WINX, SLOPE_Y - tan(SlopeTheta)*WINX, 0, SLOPE_Y
    circle BallX - BALL_SIZE, BallY - BALL_SIZE, BallX + BALL_SIZE, BallY + BALL_SIZE
 
    color 255, 0, 0         // 速度ベクトル
    DrwArrow BallX, BallY, vx * 30 + BallX, vy * 30 + BallY
 
    return
添付ファイル:
fileBoundBall2.gif
265件 [詳細]
トップ    編集凍結 差分バックアップ添付複製名前変更リロード   新規一覧単語検索最終更新   最終更新のRSS
Last-modified: 2007-04-08 (日) 02:48:27 (2436d)