往復運動リストに戻る    印刷する

往復する円運動…ふたつの円列の衝突

ふたつの円の列が、円周上を往復運動しながら、衝突します。
円周上を往復する動きの計算は円列の往復する円運動と同じです。
衝突の判定は、ふたつの円の円周上の衝突と同様に行いますが、跳ね返りの時の円の間隔に注意が要ります。【リスト RCircleM2】では角度の変化量は右の列が3、左の列が-3なので、円周上を同じスピードで進み、180度のところで衝突します。そこで運動を反転させると、次に0度のところで衝突します。角度が180度と0度になったことで、衝突を判定します。
 if(angle1[i]>180){// 右の列 角度180度で衝突
     angle1[i] = 180 - (angle1[i]-180);  //衝突時180を越えた差分を折り返す
     da1[i] = -da1[i];
 }else if(angle1[i]<0){// 右の列 角度0度で衝突
     angle1[i] = - angle1[i];  //衝突時0を越えた差分を折り返す
     da1[i] = -da1[i];
 }
 if(angle2[i]<-180){// 左の列 角度180度で衝突
     angle2[i] = -180 - (angle2[i]+180);  //衝突時180を越えた差分を折り返す
     da2[i] = -da2[i];
 }else if(angle2[i]>0){// 左の列 角度0度で衝突
     angle2[i] = - angle2[i];  //衝突時0を越えた差分を折り返す
     da2[i] = -da2[i];
 }

Your browser does not support the canvas tag.

クリックで停止⇔再開
【リスト RCircleM2】
int n = 10; //円の数
float[] angle1  = new float[n]; // 位置(角度)
float[] angle2  = new float[n]; // 位置(角度)
float[] da1 =  new float[n]; //  角度の変化量
float[] da2 =  new float[n]; //  角度の変化量
float x1, y1, x2, y2;
float d = 10; // 円の直径
float len = 60; // 軌跡の円の半径
float ver=270;  //往復位置の補正 角度 3時位置は0度、右回り

void setup() {
  size(150, 150);   //描画するための画面
  noStroke();
  da1[angle1.length-1]=3;  //右列の変化量(配列末尾の値を設定)
  da2[angle2.length-1]=-3; //左列の変化量(配列末尾の値を設定)
  for(int i=angle1.length-2;i>=0;i--){  //右列の配列初期化
    angle1[i]= angle1[i+1] + 10; // 配列末尾は0で、先頭に向かって10ずつ増える
    da1[i] = da1[i+1];           //後ろの要素と同じ値(全部3)
  }
  for(int i=angle2.length-2;i>=0;i--){  //左列の配列初期化
    angle2[i]= angle2[i+1] - 10;// 配列末尾は0で、先頭に向かって10ずつ減る
    da2[i] = da2[i+1];
  }
}

void draw() { 
     background(255);   //画面の背景を白でクリア
     for(int i=0; i<n; i++){
        angle1[i] = angle1[i] + da1[i];
        angle2[i] = angle2[i] + da2[i];
        x1 = len * cos(radians(angle1[i]+ver)) + width/2.0;
        y1 = len * sin(radians(angle1[i]+ver)) +  height/2.0;
        fill(200,0,0); //右は赤
        ellipse(x1, y1, d, d);
        x2 = len * cos(radians(angle2[i]+ver)) + width/2.0;
        y2 = len * sin(radians(angle2[i]+ver)) +  height/2.0;
        fill(0);
        ellipse(x2, y2, d, d);  
        if(angle1[i]>180){// 右の列 角度180度で衝突
           angle1[i] = 180 - (angle1[i]-180);  //衝突時180を越えた差分を折り返す
           da1[i] = -da1[i];
         }else if(angle1[i]<0){// 右の列 角度0度で衝突
           angle1[i] = - angle1[i];  //衝突時0を越えた差分を折り返す
           da1[i] = -da1[i];
        }
        if(angle2[i]<-180){// 左の列 角度180度で衝突
          angle2[i] = -180 - (angle2[i]+180);  //衝突時180を越えた差分を折り返す
          da2[i] = -da2[i];
        }else if(angle2[i]>0){// 左の列 角度0度で衝突
          angle2[i] = - angle2[i];  //衝突時0を越えた差分を折り返す
          da2[i] = -da2[i];
       }
     }
}

arigat アットマーク acm.org / copyright © info