キャンバスにランダムな曲線の塊を描きたいのですが、私はそれを行うためのアルゴリズムを考え出すことができません。これで問題が頭にそれを取得している (これは単純化である...私はキャンバスの中などに行を制約するビットを追加しました)キャンバスの「ランダムな」曲線の形状
context.beginPath();
// Each shape should be made up of between three and six curves
var i = random(3, 6);
var startPos = {
x : random(0, canvas.width),
y : random(0, canvas.height)
};
context.moveTo(startPos.x, startPos.y);
while (i--) {
angle = random(0, 360);
// each line shouldn't be too long
length = random(0, canvas.width/5);
endPos = getLineEndPoint(startPos, length, angle);
bezier1Angle = random(angle - 90, angle + 90) % 360;
bezier2Angle = (180 + random(angle - 90, angle + 90)) % 360;
bezier1Length = random(0, length/2);
bezier2Length = random(0, length/2);
bezier1Pos = getLineEndPoint(startPos, bezier1Length, bezier1Angle);
bezier2Pos = getLineEndPoint(endPos, bezier2Length, bezier2Angle);
context.bezierCurveTo(
bezier1Pos.x, bezier1Pos.y
bezier2Pos.x, bezier2Pos.y
endPos.x, endPos.y
);
startPos = endPos;
}
:私はこのようなランダムなベジェ曲線を作成しようとしました出発点に戻って、厄介なコーナーの負荷をかけるだけではありません。誰もがこれを行うためのより良いアルゴリズムを知っている、または1つを考えることができますか?
編集:私はいくつかの進歩を遂げました。私はもう一度やり直しました。直線で作業しています(私はこのビットを使い果たしたら、スムースベジエにするために何をすべきか知っています)。私は各点を描く前に、前の点から始点までの距離と角度を計算するように設定しました。距離が一定量未満の場合は、曲線を閉じます。そうでなければ、可能な角度は反復回数に基づいて狭くなり、最大線長さは開始までの距離になります。だからここにいくつかのコードがあります。
start = {
// start somewhere within the canvas element
x: random(canvas.width),
y: random(canvas.height)
};
context.moveTo(start.x, start.y);
prev = {};
prev.length = random(minLineLength, maxLineLength);
prev.angle = random(360);
prev.x = start.x + prev.length * Math.cos(prev.angle);
prev.y = start.y + prev.length * Math.sin(prev.angle);
j = 1;
keepGoing = true;
while (keepGoing) {
j++;
distanceBackToStart = Math.round(
Math.sqrt(Math.pow(prev.x - start.x, 2) + Math.pow(prev.y - start.y, 2)));
angleBackToStart = (Math.atan((prev.y - start.y)/(prev.x - start.x)) * 180/Math.pi) % 360;
if (isNaN(angleBackToStart)) {
angleBackToStart = random(360);
}
current = {};
if (distanceBackToStart > minLineLength) {
current.length = random(minLineLength, distanceBackToStart);
current.angle = random(angleBackToStart - 90/j, angleBackToStart + 90/j) % 360;
current.x = prev.x + current.length * Math.cos(current.angle);
current.y = prev.y + current.length * Math.sin(current.angle);
prev = current;
} else {
// if there's only a short distance back to the start, join up the curve
current.length = distanceBackToStart;
current.angle = angleBackToStart;
current.x = start.x;
current.y = start.y;
keepGoing = false;
}
context.lineTo(current.x, current.y);
}
console.log('Shape complexity: ' + j);
context.closePath();
context.fillStyle = 'black';
context.shadowColor = 'black';
context.shadowOffsetX = -xOffset;
context.shadowOffsetY = -yOffset;
context.shadowBlur = 50;
context.fill();
私が今持っている問題は、形状の輪郭がしばしば交差して見えてしまうことです。これは間違っています。私がこれを解決するために考えることができる唯一の方法は、バウンディングボックスを追跡することです。そして、それぞれの新しいポイントは、常に境界ボックスの外に出てください。利用可能な角度を計算することは、全体的な複雑さを増すので、難しいです。
JavaScriptインラインでHTMLページ全体を投稿する必要があります。 – Fantius
http://stackoverflow.com/questions/2956967/drawing-path-by-bezier-curves – Fantius
コードはjsfiddleです:http://jsfiddle.net/EnZX4/ –