ページ 1 / 1
バウンドについて、
Posted: 2011年1月21日(金) 11:46
by ピー
学校の課題で斜方投射しバウンドする軌跡を描き何回バウンドしたのかを求めるというプログラムを今作っているのですがバウンドのさせ方がよくわかりません。はじめに重力加速度、反発係数、を入力しておいて時間、初速、角度を入力します。
C++です。
今のところ作り出したプログラムは以下のとうりです。
しかし、うまく動きません、何をどうやっていいかもいまいちです。
どうしたらいいですか?アドバイスお願いします、できれば解答してくれる方がいるとありがたいです。
変な文章で申し訳ありません。
#include <stdio.h>
#include <math.h>
#define g 9.8
#define π 3.1415926536
int main (void)
{
double t;
double v0;
double x, y;
double θ;
printf("初速度, 投射角度(度), 経過時間");
scanf("%lf, %lf, %lf", &v, &θ, &t);
θ *= π / 180.0;
x = v0 * cos(θ) * t;
y = v0 * sin(θ) * t - g * pow(t, 2.0) / 2.0;
printf("x = %f\ny = %f\n", x, y);
return 0;
}
double e;
x =v0*cos(θ)*e*t;
y = v0 * sin(θ) *e* t - g * pow(t, 2.0) / 2.0;
Re: バウンドについて、
Posted: 2011年1月21日(金) 12:37
by bitter_fox
ピー さんが書きました:学校の課題で斜方投射しバウンドする軌跡を描き何回バウンドしたのかを求めるというプログラムを今作っているのですがバウンドのさせ方がよくわかりません。はじめに重力加速度、反発係数、を入力しておいて時間、初速、角度を入力します。
C++です。
今のところ作り出したプログラムは以下のとうりです。
しかし、うまく動きません、何をどうやっていいかもいまいちです。
フォーラムルールに従った投稿をお願いします。
フォーラムルールにはコードを載せる際はcodeタグで囲むようにとありますので、囲んでいただきますようにお願いします。
また動かないとのことですが、プログラムを見る限りコンパイルすら通りません。
コード:
#include <stdio.h>
#include <math.h>
#define g 9.8
#define π 3.1415926536
int main (void)
{
double t;
double v0;
double x, y;
double θ;
printf("初速度, 投射角度(度), 経過時間");
scanf("%lf, %lf, %lf", &v, &θ, &t);
θ *= π / 180.0;
x = v0 * cos(θ) * t;
y = v0 * sin(θ) * t - g * pow(t, 2.0) / 2.0;
printf("x = %f\ny = %f\n", x, y);
return 0;
}
double e;
x =v0*cos(θ)*e*t;
y = v0 * sin(θ) *e* t - g * pow(t, 2.0) / 2.0;
その原因は、
プログラムに、「π」や「θ」といった記号は使えません。
次に、double e;以下がmain関数の外に出てしまっています。
グローバルな文を除くすべての文は、何らかの関数内に存在していなければなりません。
Re: バウンドについて、
Posted: 2011年1月21日(金) 13:32
by さかまき
http://f4.aaa.livedoor.jp/~pointc/log649.html
と非常によく似ています。
最後の
double e;
x =v0*cos(θ)*e*t;
y = v0 * sin(θ) *e* t - g * pow(t, 2.0) / 2.0;
が作り出したところでしょうか。
へたに書き換えなきゃよかったのに・・
勘違いだったらすみません。
Re: バウンドについて、
Posted: 2011年1月22日(土) 18:29
by ピー
回答ありがとうございます。
質問の仕方がしっかりしていなくて申し訳ありませんでした。
上の方が言っているように書き換えです。
ここからどのようにプログラムを作っていけば良いんでしょうか?
Re: バウンドについて、
Posted: 2011年1月22日(土) 18:45
by h2so5
物理にそれほど詳しいわけでは無いので、間違っていたら申し訳ありませんが、
いったいどのように、バウンドが終了したのか判断するのでしょうか?
理論上は、有限時間後にバウンドは停止しますが、その間に物体は床と無限回衝突します。
反発係数を掛ければ速度は低下しますが、0になることはありません。
Re: バウンドについて、
Posted: 2011年1月22日(土) 19:43
by ピー
それを考えていませんでした。
y軸の高さが1より小さくなった時にバウンドを終了ということになります。
Re: バウンドについて、
Posted: 2011年1月22日(土) 20:26
by a5ua
時間を入力するということは、(入力した時間をtとすると)投げてからt秒後までに
何回バウンドしたかを求めるのではないですか?
Re: バウンドについて、
Posted: 2011年1月22日(土) 20:45
by ピー
この問題なんですが、自分で問題を設定しそれをプログラミングで回答?するといった内容なのでこれは自分が作った物でなんで設定、解があいまいですいません。
とりあえず、斜方投射を行いその時に時間、角度、初速を与えその与えた時間での座標を出すといったものが作りたいのです。高さがゼロの時にバウンドを行います。
バウンド回数のカウントはなくします。
上手く説明できず、すいません。
Re: バウンドについて、
Posted: 2011年1月22日(土) 20:51
by ピー
追記です。
a5uaさん
そうです、先ほどの質問しっかり理解せず回答してしまいました。
tの時間で何回バウンドを行ったかをはかり、座標にいるのか求めようとした問題でした。
Re: バウンドについて、
Posted: 2011年1月23日(日) 16:51
by ピー
コード:
#include <stdio.h>
#include <math.h>
#define g 9.8
#define pi 3.1415926536
int main (void)
{
double t;
double v0;
double x, y;
double z;
double vx,vy;
double vx’,vy’;
printf("初速度, 投射角度(度), 経過時間");
scanf("%lf, %lf, %lf", &v0, &z, &t);
z *= pi / 180.0;
x = v0 * cos(z) * t;
y = v0* sin(z) * t - g * pow(t, 2.0) / 2.0;
vx=vo*cos(z);
vy=-g*t+vo*sin(z);
printf("x = %f\ny = %f\n", x, y);
return 0;
#define e 0.800
int n;
for(n=0;y<0;n++){
y=(e^n)*vy*t-(1/2)*g*t*t;
x=vx*t+vx’*(t-t’);
vx’=vx*(e^n);
vy’=(e^n)*vy;
}
return 0;
}
ここまで作りましたがエラーで通りません、バウンドさせた後の座標のあらわし方がわかりません
提出が明日なので急いでいます。
アドバイスお願いします。
Re: バウンドについて、
Posted: 2011年1月23日(日) 16:55
by みけCAT
変数名に'は使えない気がします。
_などを使ってみてください。
Re: バウンドについて、
Posted: 2011年1月23日(日) 16:57
by みけCAT
というか全角の’ならより一層使えません。
変数名に使用できるのは一部の半角文字だけです。
C言語で全角の文字が使えるのは""の中とコメントだけです。
http://9cguide.appspot.com/05-01.html
Re: バウンドについて、
Posted: 2011年1月23日(日) 16:58
by みけCAT
ピー さんが書きました:ここまで作りましたがエラーで通りません
エラーの際はできるだけエラーメッセージの記載をお願いします。
Re: バウンドについて、
Posted: 2011年1月23日(日) 17:00
by ピー
ありがとうございます。
_に変更しました。
Re: バウンドについて、
Posted: 2011年1月23日(日) 17:02
by ピー
エラーメッセージは以下のとうりです
>------ ビルド開始: プロジェクト: 斜方投射2, 構成: Debug Win32 ------
1>コンパイルしています...
1>斜方.cpp
1>z:\visual studio 2005\projects\斜方投射2\斜方投射2\斜方.cpp(21) : warning C4996: 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> c:\program files\microsoft visual studio 8\vc\include\stdio.h(295) : 'scanf' の宣言を確認してください。
1>z:\visual studio 2005\projects\斜方投射2\斜方投射2\斜方.cpp(26) : error C2065: 'vo' : 定義されていない識別子です。
1>z:\visual studio 2005\projects\斜方投射2\斜方投射2\斜方.cpp(36) : error C2296: '^' : 無効です。左オペランドには型 'double' が指定されています。
1>z:\visual studio 2005\projects\斜方投射2\斜方投射2\斜方.cpp(37) : error C2065: 't_' : 定義されていない識別子です。
1>z:\visual studio 2005\projects\斜方投射2\斜方投射2\斜方.cpp(38) : error C2296: '^' : 無効です。左オペランドには型 'double' が指定されています。
1>z:\visual studio 2005\projects\斜方投射2\斜方投射2\斜方.cpp(39) : error C2296: '^' : 無効です。左オペランドには型 'double' が指定されています。
1>ビルドログは "file://z:\Visual Studio 2005\Projects\斜方投射2\斜方投射2\Debug\BuildLog.htm" に保存されました。
1>斜方投射2 - エラー 5、警告 1
========== ビルド: 0 正常終了、1 失敗、0 更新、0 スキップ ==========
Re: バウンドについて、
Posted: 2011年1月23日(日) 17:10
by みけCAT
コード:
#include <stdio.h>
#include <math.h>
#define g 9.8
#define pi 3.1415926536
int main (void)
{
double t;
double v0;
double x, y;
double z;
double vx,vy;
double vx_,vy_;
printf("初速度, 投射角度(度), 経過時間");
scanf("%lf, %lf, %lf", &v0, &z, &t);
z *= pi / 180.0;
x = v0 * cos(z) * t;
y = v0* sin(z) * t - g * pow(t, 2.0) / 2.0;
vx=v0*cos(z);
vy=-g*t+vo*sin(z);
printf("x = %f\ny = %f\n", x, y);
return 0;
#define e 0.800
int n;
for(n=0;y<0;n++){
y=pow(e,n)*vy*t-(1/2)*g*t*t;
x=vx*t+vx_*(t-t_);
vx_=vx*pow(e,n);
vy_=pow(e,n)*vy;
}
return 0;
}
これで
ピー さんが書きました:1>z:\visual studio 2005\projects\斜方投射2\斜方投射2\斜方.cpp(37) : error C2065: 't_' : 定義されていない識別子です。
以外のエラーは直るはずです。
t_の使用意図が不明なのでこれは私には直せません。
Re: バウンドについて、
Posted: 2011年1月23日(日) 17:11
by みけCAT
^はC言語ではxor演算の演算子です。
よって、整数にしか使えません。
Re: バウンドについて、
Posted: 2011年1月23日(日) 17:12
by ピー
ありがとうございます。
バウンドした後のY座標の計算での求め方がわからなく、t_はバウンドする前の経過時間のつもりで書きました。
Re: バウンドについて、
Posted: 2011年1月23日(日) 17:19
by ピー
今度は
1>z:\visual studio 2005\projects\斜方投射2\斜方投射2\斜方.cpp(21) : warning C4996: 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> c:\program files\microsoft visual studio 8\vc\include\stdio.h(295) : 'scanf' の宣言を確認してください。
1>z:\visual studio 2005\projects\斜方投射2\斜方投射2\斜方.cpp(27) : error C2065: 'vo' : 定義されていない識別子です。
1>z:\visual studio 2005\projects\斜方投射2\斜方投射2\斜方.cpp(37) : error C2065: 't_' : 定義されていない識別子です。
1>ビルドログは "file://z:\Visual Studio 2005\Projects\斜方投射2\斜方投射2\Debug\BuildLog.htm" に保存されました。
1>斜方投射2 - エラー 2、警告 1
========== ビルド: 0 正常終了、1 失敗、0 更新、0 スキップ ==========
が出ました。
みけCATさんの言うとうりt_部分は仕方ないですがvoの定義されていないというのはどこか間違っているのですか?
あとt_をしっかりと定義すれば斜方投射でバウンドするプログラムは作れますか?
Re: バウンドについて、
Posted: 2011年1月23日(日) 17:20
by みけCAT
t_を宣言して、適切な値を代入してください。
vo(ブイオー)はv0(ブイゼロ)のtipoだと思います。
Re: バウンドについて、
Posted: 2011年1月23日(日) 17:30
by ピー
コード:
#include <stdio.h>
#include <math.h>
#define g 9.8
#define pi 3.1415926536
int main (void)
{
double t;
double v0;
double x, y;
double z;
double vx,vy;
double vx_,vy_;
double t_;
printf("初速度, 投射角度(度), 経過時間");
scanf("%lf, %lf, %lf", &v0, &z, &t);
z *= pi / 180.0;
x = v0* cos(z) * t;
y = v0* sin(z) * t - g * pow(t, 2.0) / 2.0;
vx=v0*cos(z);
vy=-g*t+v0*sin(z);
printf("x = %f\ny = %f\n", x, y);
return 0;
#define e 0.800
int n;
for(n=0;y<0;n++){
t_=g*pow(t, 2.0)/2.0/v0/sin(z);
y=pow(e,n)*vy*t-(1/2)*g*t*t;
x=vx*t+vx_*(t-t_);
vx_=vx*pow(e,n);
vy_=pow(e,n)*vy;
}
return 0;
}
このようにしてみました。
しかし、出力結果のyがマイナスの値になってしまいます。
Re: バウンドについて、
Posted: 2011年1月23日(日) 17:35
by みけCAT
このプログラムは、ただの斜方投射の計算なので、
パラメータによってはマイナスになってもおかしくないです。
Re: バウンドについて、
Posted: 2011年1月23日(日) 17:37
by ピー
バウンドさせるにはどのようなプログラムを組めばよいのですか?
Re: バウンドについて、
Posted: 2011年1月23日(日) 17:43
by みけCAT
1フレームずつシュミレーションしていくのがいいと思います。
地面や壁に当たったらそれなりに速度を反転させます。
座標も補正するといいでしょう。
Re: バウンドについて、
Posted: 2011年1月23日(日) 17:51
by みけCAT
たとえばこんな感じです。
簡単にするためにDXライブラリを使用しています。
コード:
#include "DxLib.h"
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
ChangeWindowMode( TRUE ) ; // ウインドウモードに変更
if( DxLib_Init() == -1 ) return -1; // DXライブラリ初期化処理 エラーが起きたら終了
SetDrawScreen( DX_SCREEN_BACK ) ; // 描画先を裏画面に設定
int White;
double x,y,vx,vy,t;
White = GetColor( 255 , 255 , 255 ) ; // 白色の値を取得
x=320;y=100;vx=0;vy=0;t=0;
while(1) {
if(ProcessMessage()!=0)break;
vy+=9.8/60.0;//計算
t+=1.0/60.0;
x+=vx;y+=vy;
if(y>=480) {//座標の補正
vy=-vy;
y=480-(y-480);
}
ClearDrawScreen(); // 裏画面のデータを全て削除
DrawCircle( x , y , 10 , White , TRUE) ; // 円を描画(塗りつぶし)
DrawFormatString( 0, 0, White , "t=%f" , t );//文字列表示
DrawFormatString( 0, 30, White , "x=%f" , x );//文字列表示
DrawFormatString( 0, 60, White , "y=%f" , y );//文字列表示
ScreenFlip() ; // 裏画面データを表画面へ反映
}
DxLib_End() ; // DXライブラリ使用の終了処理
return 0 ; // ソフトの終了
}
Re: バウンドについて、
Posted: 2011年1月23日(日) 17:54
by ピー
コード:
#include <stdio.h>
#include <math.h>
#define g 9.8
#define pi 3.1415926536
int main (void)
{
double t;
double v0;
double x, y;
double z;
double vx,vy;
double vx_,vy_;
double t_;
printf("初速度, 投射角度(度), 経過時間");
scanf("%lf, %lf, %lf", &v0, &z, &t);
z *= pi / 180.0;
x = v0* cos(z) * t;
y = v0* sin(z) * t - g * pow(t, 2.0) / 2.0;
vx=v0*cos(z);
vy=-g*t+v0*sin(z);
printf("x = %f\ny = %f\n", x, y);
return 0;
#define e 0.800
int n;
for(n=0;y<0;n++){
t_=g*pow(t, 2.0)/2.0/v0/sin(z);
y=vy_*(t-t_)-(1/2)*g*(t-t_)*(t-t_);
x=vx*t_+vx_*(t-t_);
vx_=vx*pow(e,n);
vy_=pow(e,n)*vy;
}
return 0;
}
にしてみました。やはりうまくはいきませんでした。for文をどのように変えていけばいいのでしょうかアドバイスお願いします。
Re: バウンドについて、
Posted: 2011年1月23日(日) 20:54
by パコネコ
31行目って何のために・・・
32行目以降にたどり着けてないように見えます。
それと、最後の32行目以降の確認用に、
処理の後にprintfを入れなければ、処理がうまくいってるかがわからないかと思います。
Re: バウンドについて、
Posted: 2011年1月23日(日) 21:03
by みけCAT
とりあえず適当に書いてみました。
間違っているかもしれないので自己責任でお願いします。
► スポイラーを表示
コード:
#include <stdio.h>
#include <math.h>
#define g 9.8
#define pi 3.1415926536
#define e 0.800
int main (void)
{
double t;
double v0;
double x, y;
double z;
double vx,vy;
double t_;
printf("初速度, 投射角度(度), 経過時間");
scanf("%lf, %lf, %lf", &v0, &z, &t);
z *= pi / 180.0;
vx=v0*cos(z);
vy=v0*sin(z);
x=0;
y=0;
for(t_=0;t_<t;t_+=0.1) {
vy-=g*0.1;
x+=vx;
y+=vy;
if(y<0) {
vy=-vy*e;
y=-y;
}
printf("t = %f,x = %f,y = %f\n", t_, x, y);
}
return 0;
}
Re: バウンドについて、
Posted: 2011年1月23日(日) 22:29
by h2so5
(上に同じく)とりあえず適当に書いてみました。
間違っているかもしれないので自己責任でお願いします。
初速度, 投射角度(度), 経過時間を入力するとその時点での物体の座標を返します。
► スポイラーを表示
コード:
#include <stdio.h>
#include <math.h>
#define g 9.8
#define pi 3.1415926536
#define e 0.800
#define limit 5000
int main (void)
{
int n;
double t=5,ta=0,v0,x,y,z,vx,vy,xt;
printf("初速度, 投射角度(度), 経過時間\n");
scanf("%lf, %lf, %lf", &v0, &z, &t);
x = 0;
z *= pi / 180.0;
vx = v0 * cos(z);
vy = v0 * sin(z);
xt = vy / g * (1+e) / (1-e); //バウンド終了時間
if(t >= xt){
t = xt;
vy = 0;
}
for(n=0;(t-ta>0 && vy > 0);n++){
if(n){
vy *= e;
t -= ta;
x += vx * ta;
}
ta = vy / g;
if(n > limit){ //ループ多すぎ
printf("Too Many Calculation\n");
break;
}
}
x += vx * t;
if(vy <= 0){ //初速0のとき
y = 0;n = 1;
}else{
y = vy * t - 0.5 * g * t * t;
}
printf("x:%lf y:%lf\n",x,y);
return 0;
}
http://ideone.com/z8APE
Re: バウンドについて、
Posted: 2011年1月23日(日) 22:51
by ピー
みなさん、ありがとうございます。
結果的にほとんどをみなさんにやってもらう形になりすいません。
これを参考に作ってみます。
まったく無能でご迷惑かけました。
ありがとうございました。