🤖
3次ベジェ曲線_2点特殊バージョン


黄色の点を二つ決め、
中間の二つの制御点を自動計算することで、
4つの点を指定しなければいけないところを二つに限定している。
自由度が下がる代わりに使いやすくなる。
let z0, z1, z2, z3; // 制御点
function setup() {
createCanvas(600, 400); // キャンバスを作成
background(240); // 背景色を設定
// 制御点の座標を定義
z0 = createVector(50, 200); // 始点
z3 = createVector(550, 200); // 終点
z1 = createVector((z0.x + z3.x) /2 , z0.y); // 1つ目の制御点
z2 = createVector((z0.x + z3.x) /2, z3.y); // 2つ目の制御点
}
function draw() {
z1.x = (z0.x + z3.x) /2;
z1.y = z0.y;
z2.x = (z0.x + z3.x) /2;
z2.y = z3.y;
background(240); // 毎回背景をクリアして再描画
// 制御点を描画(視覚化のため)
fill(0);
noStroke();
ellipse(z0.x, z0.y, 8, 8); // 始点
ellipse(z1.x, z1.y, 8, 8); // 制御点1
ellipse(z2.x, z2.y, 8, 8); // 制御点2
ellipse(z3.x, z3.y, 8, 8); // 終点
// 制御点間の補助線を描画(曲線の形状を理解しやすくするため)
stroke(150, 150, 150);
line(z0.x, z0.y, z1.x, z1.y);
line(z1.x, z1.y, z2.x, z2.y);
line(z2.x, z2.y, z3.x, z3.y);
// ベジェ曲線を計算し、描画
stroke(255, 0, 0); // 曲線の色を赤に
strokeWeight(2); // 曲線の太さ
noFill(); // 塗りつぶしなし
beginShape(); // 曲線を描画するための点の集合を開始
for (let t = 0; t <= 1; t += 0.005) { // tを0から1まで少しずつ増やす
// ベジェ曲線の式に基づいて点の座標を計算
let x = pow(1 - t, 3) * z0.x + 3 * pow(1 - t, 2) * t * z1.x + 3 * (1 - t) * pow(t, 2) * z2.x + pow(t, 3) * z3.x;
let y = pow(1 - t, 3) * z0.y + 3 * pow(1 - t, 2) * t * z1.y + 3 * (1 - t) * pow(t, 2) * z2.y + pow(t, 3) * z3.y;
vertex(x, y); // 計算した点を曲線のパスに追加
}
endShape(); // 曲線の描画を終了
// p5.jsのbezier()関数を使った場合(比較用、コメントアウト解除で表示)
/*
stroke(0, 0, 255); // 青色
strokeWeight(1);
noFill();
bezier(z0.x, z0.y, z1.x, z1.y, z2.x, z2.y, z3.x, z3.y);
*/
}
// マウスドラッグで制御点を移動させる機能(オプション)
// これを実装することで、インタラクティブに曲線の形状を変更できます
function mouseDragged() {
// マウスの位置に最も近い制御点を探す
let minDist = Infinity;
let closestPoint = null;
let points = [z0, z1, z2, z3];
for (let i = 0; i < points.length; i++) {
let d = dist(mouseX, mouseY, points[i].x, points[i].y);
if (d < minDist) {
minDist = d;
closestPoint = points[i];
}
}
// 検出した制御点をマウスの位置に移動
if (minDist < 50) { // 制御点の近くをクリックした場合のみ移動
closestPoint.x = mouseX;
closestPoint.y = mouseY;
}
}```
Discussion