Tôi muốn vẽ các đốm màu cong trông ngẫu nhiên trên canvas, nhưng dường như tôi không thể tìm ra thuật toán để làm điều đó. Tôi đã cố gắng tạo ra các đường cong Bezier ngẫu nhiên như thế này:canvas hình dạng cong "ngẫu nhiên"
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;
}
(Đây là một việc đơn giản hóa ... Tôi thêm bit hạn chế các dòng để trong vải, vv) Vấn đề ở đây là nhận được nó để đầu trở lại điểm khởi đầu, và cũng không chỉ tạo ra vô số góc vụng về. Có ai biết về một thuật toán tốt hơn để làm điều này, hoặc có thể nghĩ ra một trong những?
Chỉnh sửa: Tôi đã thực hiện một số tiến bộ. Tôi đã bắt đầu một lần nữa, làm việc với các đường thẳng (tôi nghĩ tôi biết phải làm gì để biến chúng thành Beziers trơn tru một khi tôi đã làm việc này một chút). Tôi đã thiết lập nó sao cho trước khi vẽ từng điểm, nó làm việc ra khoảng cách và góc để bắt đầu từ điểm trước đó. Nếu khoảng cách nhỏ hơn một số tiền nhất định, nó sẽ đóng đường cong. Nếu không, góc có thể thu hẹp dựa trên số lần lặp lại và chiều dài dòng tối đa là khoảng cách đến điểm bắt đầu. Đây là một số mã.
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();
Vấn đề tôi có bây giờ là hình dạng của phác thảo thường đi qua chính nó, trông có vẻ sai. Cách duy nhất tôi có thể nghĩ đến để giải quyết vấn đề này là theo dõi một hộp giới hạn, và mỗi điểm mới phải luôn đi ra khỏi hộp giới hạn. Đó là khó khăn bởi vì tính toán góc sẵn có thêm một mức độ phức tạp toàn bộ.
Bạn nên đăng toàn bộ trang HTML, với nội tuyến JavaScript. – Fantius
http://stackoverflow.com/questions/2956967/drawing-path-by-bezier-curves – Fantius
Đây là một jsfiddle với mã của mình: http://jsfiddle.net/EnZX4/ –