codepad
[
create a new paste
]
login
|
about
Language:
C
C++
D
Haskell
Lua
OCaml
PHP
Perl
Plain Text
Python
Ruby
Scheme
Tcl
//円(電荷)を任意で追加し、それらをクーロンの法則に基づいて動かす #include <FL/Fl.H> #include <FL/Fl_Box.H> #include <FL/Fl_Window.H> #include "../../../std_lib_facilities.h" #include "../../../Point.h" #include "../../../Graph.h" #include "../../../GUI.h" #include "../../../Simple_window.h" #include "../../../Window.h" using namespace Graph_lib; struct dx_dy { double dx; double dy; dx_dy(double xx, double yy) : dx(xx) ,dy(yy) {} dx_dy() : dx(0), dy(0) {} }; struct Coulomb_window :Window{ Coulomb_window(Point xy, int w, int h, const string& title ); int i; double k,dx,dy; //k=定数,dx=x軸方向の移動距離の合計 char c; private: Graph_lib::Rectangle rect; vector<int> vec; //正負(大きさ) Vector_ref<Circle> vcircle; //円 vector<dx_dy> vdx_dy; //移動距離x,y Button add_button; //円を追加 Button start_button; //円を動かし始める Button quit_button; //終了 Button reset_button; //ヴェクタなどのリセット In_box add_x; //追加する円の中心のx座標 In_box add_y; In_box ec; //正負(大きさ) static void cb_add(Address,Address); void add(); static void cb_start(Address,Address); void start(); static void cb_quit(Address,Address); void quit(); static void cb_reset(Address,Address); void reset(); void Calculation_of_power(); }; Coulomb_window::Coulomb_window(Point xy, int w, int h, const string& title ) :Window(xy,w,h,title), rect(Point(0,30),600,400), //背景を白く add_button(Point(x_max()-100,5),40,20,"add",cb_add), start_button(Point(x_max()-150,5),40,20,"start",cb_start), quit_button(Point(x_max()-50,5),40,20,"quit",cb_quit), reset_button(Point(x_max()-200,5),40,20,"reset",cb_reset), add_x(Point(x_max()-360,5),50,20,"add x:"), add_y(Point(x_max()-260,5),50,20,"add y:"), ec(Point(x_max()-460,5),50,20,"ec:") { k = 1; rect.set_fill_color(Color::white); rect.set_color(Color::invisible); attach(rect); attach(add_button); attach(start_button); attach(quit_button); attach(reset_button); attach(add_x); attach(add_y); attach(ec); } //dx_dyクラス同士の足し算 dx_dy operator+(const dx_dy& dd1, const dx_dy& dd2) { dx_dy dxdy = dx_dy(dd1.dx + dd2.dx, dd1.dy + dd2.dy); return dxdy; } //移動距離の計算 void Coulomb_window::Calculation_of_power() { int n,l; for(n = 0; n < vec.size(); ++n){ dx,dy = 0; for(l = 0; l < vec.size(); ++l){ double f, xx, yy, s_x, s_y = 0; // f=力, s_x=2点間のx軸方向の相対距離, xx=x軸方向の移動距離, k=定数 s_x = vcircle[n].center().x - vcircle[l].center().x; //2つの円の中心を読み取り、s_x,x_yを求める s_y = vcircle[n].center().y - vcircle[l].center().y; f = (vec[n] * vec[l] * k)/(pow(s_x,2) + pow(s_y,2)); xx = f * k * sqrt(pow(s_x,2) / (pow(s_x,2) + pow(s_y,2))); yy = sqrt(pow(f,2) - pow(xx,2)); if(vec[n] * vec[l] > 0){ //正の場合と負の場合の動きの違い if(s_x<0){ xx = (-1) * xx; }else if(s_y<0){ yy = (-1) * yy; } }else if(vec[n] * vec[l] < 0){ if(s_x>0){ xx = (-1) * xx; }else if(s_y>0){ yy = (-1) * yy; } } dx = xx + dx; dy = yy + dy; } dx_dy dxy(dx,dy); vdx_dy[n] = dxy + vdx_dy[n]; } }; //ボタンが押され、add()の呼び出し void Coulomb_window::cb_add(Address,Address pw) { reference_to<Coulomb_window>(pw).add(); }; //円を追加する void Coulomb_window::add() { int ax = add_x.get_int(); int ay = add_y.get_int(); int cec = ec.get_int(); //正負(大きさ) vec.push_back(cec); vcircle.push_back(new Circle(Point(ax,ay),10)); int m; for(m=0; m < vcircle.size(); ++m) { if(vec[m]>0){ //正であれば赤い円、負であれば青い円を描く vcircle[m].set_fill_color(Color::red); //塗りつぶす vcircle[m].set_color(Color::invisible); //輪郭線を消す attach(vcircle[m]); }else if(vec[m]<0){ vcircle[m].set_fill_color(Color::blue); vcircle[m].set_color(Color::invisible); attach(vcircle[m]); } } redraw(); }; void Coulomb_window::cb_start(Address,Address pw) { reference_to<Coulomb_window>(pw).start(); }; //円を動かす void Coulomb_window::start() { char c; while(1){ //qキーが押されるまで円を動かし続ける c = cin.peek(); if(c=='q') { c = '0'; break; //ループを抜けて再び円を追加できる状態へ戻す } Calculation_of_power(); for (int h = 0; h < vdx_dy.size(); ++h) { int a,b = 0; a = (int)(vdx_dy[h].dx + 0.5); //小数点以下は切り上げ、doubleからintへ a = (vdx_dy[h].dx - (double)a) ? a+1 : a; b = (int)(vdx_dy[h].dy + 0.5); b = (vdx_dy[h].dy - (double)b) ? b+1 : b; vcircle[h].move(a,b); } } } void Coulomb_window::cb_quit(Address,Address pw) { reference_to<Coulomb_window>(pw).quit(); }; //終了する void Coulomb_window::quit() { hide(); }; void Coulomb_window::cb_reset(Address,Address pw) { reference_to<Coulomb_window>(pw).reset(); }; //ヴェクタを消去し、初期状態にする void Coulomb_window::reset() { for(int q = 0; q < vec.size(); ++q) { detach((vcircle)[q]); } delete &vcircle; vec.clear(); vdx_dy.clear(); }; int main() try{ Coulomb_window win(Point(100,100),600,400,"Coulomb's_law"); return gui_main(); } catch(exception& e) { cerr << "exception: " << e.what() << '\n'; return 1; } catch (...) { cerr << "some exception\n"; return 2; }
Private
[
?
]
Run code
Submit