• 締切済み

Processing 円と線分の衝突判定について

最近プログラミングを始めました。 今、画面の中央から落ちてくる円と、マウスボタンを押したときに三角の頂点から真上に表示される線分の2つが、接触したときに円の位置を画面の最上部に移動させ、その後再び下方向に円が移動する様なプログラムを作っています。 それで、それぞれ円と線分を表示させることはができたのですが、どうやれば円と線分が衝突したことになるか分かりません。 プログラムを載せます size(400,400); } void draw(){ background(0); fill(255,0,0); noStroke(); ellipse(200,y,r,r); y = y + 1; noStroke(); fill(10,10,255); triangle(mouseX,mouseY - 20,mouseX - 14,mouseY + 20,mouseX + 14,mouseY + 20); if(mousePressed){  stroke(248,252,3);  line(mouseX,0,mouseX,mouseY-20); } } あとはif命令を書き加えれば良いと思うのですが、どうしても条件式が思いつきません。 GW中ずっと悩んでいて分からなかったので質問しました。

みんなの回答

noname#207526
noname#207526
回答No.1

円と線分の交わりは、数学で習います。基本的にアルゴリズムを考える必要がありますが、四角だと想定してもいいと思います。 面倒なら衝突判定ライブラリを利用するといいと思います。

関連するQ&A

  • processingのプログラムの書き方について。

    課題で、どこからマウスをプレスしても20個もの四角を(0,0)まで数珠つなぎみたいにするプログラムをかいているんですが全然わかりません。 そのため大きさなどは瞬時に計算をするからmouse x, mouse yをつかいます だからrect(mouseX,mouseY,mouseX,mouseY)になると思うんですが。。 とにかく全部わかりません。教えてください。 自分が書いたのはこんなのですが、全然違います。 forループ、mouseX, mouseYを使うのはわかります int s = 600; int n = 20; int i = mouseX; void setup() { size(s,s); background(255); noStroke(); rectMode(CENTER); } void draw() { if(mousePressed) { for(int i=0; i<s; i++); { fill(255,0,0); rect(mouseX,mouseY,mouseX,mouseY); } } }

  • processingのカーソルと画像の距離

    processingでクリスマスカードを作るのですが、どうしてもカーソルと雪だるまの距離があいてしまいます。この距離をあけないようにするにはどうしたらいいでしょうか?わかる方がいらっしゃいましたらどうぞよろしくお願いします。 void setup() { size(600,600); smooth(); noStroke(); } int flag = 0; void draw() { background(10,50,100); fill(0); rect(0,450,600,280); int x=50,y=30; fill(#006e54); triangle(300,50,400,200,200,200); triangle(300,50+x,420,280,180,280); triangle(300,50+2*x,420+y,280+2*x,180-y,280+2*x); fill(190,103,31); rect(275,280+2*x,50,150); textSize(45); fill(255,0,0); text("Merry X'mas!",170,580); fill(random(255),random(255),random(255)); translate(249,5); beginShape(); vertex(50 , 50 - 20); vertex(50 - 12 , 50 + 15); vertex(50 + 18 , 50 - 8); vertex(50 - 18 , 50 - 8); vertex(50 + 12 , 50 + 15); endShape(CLOSE); fill(random(255),random(255),random(255)); ellipse(20,90,30,30); fill(random(255),random(255),random(255)); ellipse(100,130,30,30); fill(random(255),random(255),random(255)); ellipse(10,170,30,30); fill(random(255),random(255),random(255)); ellipse(55,220,30,30); fill(random(255),random(255),random(255)); ellipse(130,250,30,30); fill(random(255),random(255),random(255)); ellipse(90,350,30,30); fill(random(255),random(255),random(255)); ellipse(30,300,30,30); fill(random(255),random(255),random(255)); ellipse(10,360,30,30); fill(random(255),random(255),random(255)); ellipse(160,320,30,30); fill(random(255),random(255),random(255)); ellipse(-40,330,30,30); if(mousePressed) { flag=1; } else { flag=0; } if(flag==1) { snowman(); } else { textSize(20); fill(255); text("Please press mouse to create a snowman!",-150,20); } } void snowman() { int speed=2; int x=mouseX; int y=mouseY; x+=random(-speed,speed);//let snowman move randomly // x=constrain(x,0,500); y+=random(-speed,speed); y=constrain(y,0,600); fill(255); //make a little snowman ellipse(x,y-50,50,50); ellipse(x,y,100,100); fill(0); ellipse(x-10,y-55,10,10); ellipse(x+10,y-55,10,10); fill(#ff0000); triangle(x-10,y-50,x+10,y-50,x,y-30); }

  • クリックされた地点が2点の線分上かの判定

    bool CheckOnline(int x1,int y1,int x2,int y2,int MouseX,int MouseY){ int range = 10; //許容範囲 double a; double b; if(x2 == x1){ if( abs( MouseX -x1)<range ){ if( abs(MouseY -abs(y2-y1)) <range) return true; } }else{ a=(y2-y1)/(x2-x1); b= y1 - a*x1; if( abs(MouseY - (a * MouseX +b)) <range ){ if( abs(MouseX - ((MouseY-b)/a)) <range ) return true; } } return false; } ぴったりでなく少し誤差があっても線上と判定したいです。 上記の方法ではうまく行きませんでした。 一応、y=ax+bのaとbを求めて、マウスのxとマウスのyを代入 その結果がrange以内かどうかでやってみようとした結果です。

  • processingについて

    millis 関数を用いてマウスを押している間の経過時間をマウスカーソルの位置に表示するプログラムを作成せよ。 また、その時点での経過時間の最も長い時間をウインドウに左下に表示してある。動作するように、空欄を埋めよ。 また、変数宣言がされていない変数がある。適切な変数宣言を加えよ。この変数宣言のための空欄は用意されていない。という問題の一番最初の変数宣言?でつまずいています。 プログラムはこんな感じです。 PFont font; int maxTime; (a) pressing=false; void setup(){ size(400,400); maxTime = 0; smooth(); (b) textFont(font,24); } void draw(){ background(255); fill(0); if(mousePressed){ if(pressing == (c)){ startTime = millis(); pressing = (d); } interval = (e)-startTime; text(interval,mouseX,mouseY); }else{ pressing = (f); } if((g)> maxTime){ maxTime = (h); } text(maxTime,0,height-textDescent()); } 一番最初の、(a) pressing=false;の(a)に入るものが分かりません。 他のカッコは回答しなくてもよいので、(a)に入るものを教えてください。 そこさえ分かれば自分で解けそうな気がします。

  • processingについて

    1)横480ピクセル、縦800ピクセルの実行ウィンドウ上に、その時の時:分:秒が「18:05:01」のように表示されるようにする。 2)時計の背景に、「色」、「画像」、「図形の描画による柄」のいずれかを設定する。 3)if文を使用し、   「マウスの左ボタンがクリックされている時」には、その時の年月日が表示されるように   「マウスの右ボタンがクリックされている時」には、別の何かが起きるようにしよう。   なお、「マウスのボタンが何もクリックされていない時」には、1)のようにデジタル時計が表示されていること。 また、クリックの状態から指を離したら、画面の状態は元に戻るようにすること。 上記の条件でプログラミングしないといけないのですが、何度考えても上手く実行されません。この程度のレベルが出来なくて恥ずかしい限りなのですが、誰か手助けをしていただけないでしょうか? 下記が自分の書いたプログラミングになります。(右クリックの条件を自分は”線を描く”ように設定しました。) PFont font; PImage img; void setup(){ size(480, 800); fill(0); font = loadFont("xxxxxxxxxxx.vlw"); textFont(font); img = loadImage("xxxxxxxxxxxx.jpg"); image(img, 0, 0); } void draw(){ text(nf(hour(), 2 + "/" + nf(minute(), 2) + ":" + nf(second(), 2), 150, 245); if(mousePressed == true){ if(mouseButton == LEFT){ text(month() + "/" + day() + "/" + year(), 150, 270); }else if(mouseButton == RIGHT){ stroke(23, 9, 89); strokeWeight(2); line(mouseX, mouseY, pmouseX, pmouseY); } } }

  • 内積を用いた移動する線分と円の衝突判定について

    内積を用いた移動する線分と円の衝突判定について 作成しているプログラムはピンボールのフリッパーとボールとの衝突判定です。14歳からはじめるリアルに動くゲーム物理プログラミング教室C言語編と言う本を参考にプログラミングしています。左フリッパーが315度~360度、1度~45度の範囲を1度づつ移動する度に衝突判定をする関数を作成し、衝突した場合に関数から抜け、戻り値としてボールの情報を持つ構造体の中の反射スピードと反射座標を返すものです。 ここからが質問なのですが、ボールは全くフリッパーの衝突と関係の無い所で反射してしまいます。移動しない線分の両端の座標を与えた衝突判定(壁)では正しく判定するのですが、角度を与えて移動する線分(フリッパー)では上手くいきません。お分かりになる方いらっしゃいましたら、宜しくお願い致します。 関数に渡す引数はその時のボールの座標・速度などの構造体と左フリッパーの角度です。 以下ソースコード //左フリッパーの軸と成る座標 float hx_l = (cx_l*ZOOM); //フリッパーのx座標 float hy_l = (cy_l*ZOOM+HORIZ); //フリッパーのy座標 //ベクトル a の成分を求める float ax=xy.posx-hx_l; //線分始点からボール中心へのベクトル float ay=xy.posy-hy_l; //線分始点からボール中心へのベクトル //ベクトル b の成分を求める float bx=((cx_l+cos(ToRadian(angler_l))*clubr)*ZOOM)-hx_l; //線分始点から終点へのベクトル float by=((cy_l-sin(ToRadian(angler_l))*clubr)*ZOOM+HORIZ)-hy_l;//線分始点から終点へのベクトル float inpro=ax*bx+ay*by; //ベクトル a,b の内積を求める float bl=bx*bx+by*by; //ベクトル b の長さの二乗(線分始点から終点へのベクトル if(inpro>-ZERO1 && inpro<(bl+ZERO1)){ //フリッパーとの衝突判定 //ベクトル a の線分がボールの半径より小さければ交差している if((ax*ax+ay*ay)-pow(inpro/sqrt(bl),2) < pow(xy.radius,2)){ 以下判定後の処理‥‥ ベクトルbのbx,byを求める式でangler_lが引数として渡されるフリッパーの角度に成ります。ToRadian()は関数で角度をラジアンに変更します。

  • プログラミングProcessing ピンポンゲーム

    Processingでピンポンゲームを作っています。作成したプログラムは void setup(){ size(400,300); } float x=10; float y=10; float dx=1; float dy=2; int count=0; float r_w=50.0; float a_w=15.0; float a_h=15.0; boolean checkHit(float x,float y){ if(y+a_h<250)return false; if(x+a_w>=mouseX&&x<=mouseX+r_w){ return true; }else{ return false; } } void draw(){ x=x+dx;y=y+dy; if(x+a_w>=400){ dx=-1; }else if(x<0){ dx=1; } if(y+a_w>300){ x=0; y=0; dx=1; dy=2; count=0; }else if(y<0){ dy=2; } background(0,0,128); rect(x,y,a_w,a_w); rect(mouseX,250,r_w,3); text(count,10,300); if(checkHit(x,y)){ dy=-2; count=count+1; } } このプログラムだとどうしてもラケットの下にボールが潜り込んだ時に ボールが跳ね返されてしまうバグが発生してしまいます。 問題はboolean checkHitの部分にあると思うのですが、 どのように調節すればよいか分かりません。 わかる方教えてください<(__)>

  • 線分と円が交差する条件

    線分と円(6つの値)があります 線分:(ax1,ay1)-(ax2,ay2) 円:中心(x1,y1)半径r この6つの値から 線分が円に含まれる、或いは円と交差する条件を判定したいのですが まるで検討がつきません。 円の式は (x - x1)^2 + (y - y1)^2 = r^2 でしょうか。(自信無し) リアルタイムにコンピューターで計算するため 出来れば少ない計算量で計算させたいのですが。。。 宜しくお願い致します。

  • 色つきの円を描きたいです

    色つきの円を描きたいです。 円の中心まで色を付きたいです。 出来ますか? おしえてください! お願いします。 この前教えたもらった方法でテストプログラム を作りましたが、実行不可能です。 絵を描くのが初めてですから、 サンプルを欲しいです。 お願いします。 #include <stdio.h> #include <string.h> #include <afxwin.h> void main( void ) { int X,Y,R; X=10; Y=20; R =100; Ellipse(X-R,Y-R, X+R, Y+R); }

  • Processingでのキーの同時入力

    Processingでゲームを作ろうとしているのですがキーボードの同時入力がうまくいきません。 例えば下記のようなキー入力に応じて黒い四角が動くプログラムを実行しました。方向キーを一つだけ押したときはサクサク動いてくれるのですが、→と↓を同時に押しても斜めに進んでくれません。また、→と←を押した場合もどちらか片方の方に動いてしまいます。 このような問題を解決したいので、Processingでキーボードの同時入力を判定するにはどのようにすればいいのか教えてください。 float x, y; void setup(){ size(400, 400); noStroke(); smooth(); } void draw() { background(255,255,255); fill(0,0,0); rect(x,y,20, 20); if (keyPressed && key == CODED){ if (keyCode == LEFT){ x -= 2; } if (keyCode == RIGHT){ x += 2; } if (keyCode == UP){ y -= 2; } if (keyCode == DOWN){ y += 2; } } }

専門家に質問してみよう