真ん中の円に動く円をぶつけて反射させる動きです。
反射ベクトルの求め方について勉強したノートをこちらに作りました。
反射ベクトルの求め方の勉強
function setup() { createCanvas(400, 400); //オブジェクトリテラルで静止円の属性を定義 seishiEn = { x:width / 2, y:height / 2, r:40 }; //同じく動く円を定義 ugokuEn = { x:100, y:100, r:20, vx:5, //加速度 vy:4, //加速度 }; } function draw() { background(220); //静止円を描く fill(100, 200, 250); noStroke(); ellipse(seishiEn.x, seishiEn.y, seishiEn.r * 2); //動く円を描画 fill(250, 100, 100); ellipse(ugokuEn.x, ugokuEn.y, ugokuEn.r * 2); //位置の更新 ugokuEn.x += ugokuEn.vx; ugokuEn.y += ugokuEn.vy; //壁との反射 if (ugokuEn.x - ugokuEn.r <= 0 || ugokuEn.x + ugokuEn.r >= width) { ugokuEn.vx *= -1; } if (ugokuEn.y - ugokuEn.r <= 0 || ugokuEn.y + ugokuEn.r >= height) { ugokuEn.vy *= -1; } //衝突の検出 //現在の中心間の距離を求める let dx = ugokuEn.x - seishiEn.x; let dy = ugokuEn.y - seishiEn.y; let distance = sqrt(dx * dx + dy * dy); //中心間の距離 //衝突時の中心間の距離 let hitDist = ugokuEn.r + seishiEn.r; if (distance < hitDist) { //衝突したとき //反射ベクトルを求める //法線ベクトル //normalize()でベクトルの長さを1として方向成分のみとする let normalV = createVector(dx, dy).normalize(); //速度ベクトル sokudoV = createVector(ugokuEn.vx, ugokuEn.vy); //ベクトルの反射計算 //R = V - 2 (V・N) N //VとNの内積(スカラー値) let dotSeki = sokudoV.dot(normalV); //反射ベクトルreflecV let reflecV = p5.Vector.sub(sokudoV,p5.Vector.mult(normalV, 2 * dotSeki)); //新しい速度 ugokuEn.vx = reflecV.x; ugokuEn.vy = reflecV.y; //円がめり込まない位置に戻す //めりこんだ距離 let overlap = hitDist - distance; ugokuEn.x += normalV.x * overlap; ugokuEn.y += normalV.y * overlap; } }